WCF RIA services and WSDL generation - wcf

Need help on an issue I am having. I inherited this WCF RIA project and am trying to understand a couple of things.
When I publish the project, how does the WSDL get generated and put on the URL that I published to?
And I want to incorporate FaultException handling so as to transmit the exceptions to the client side. I read some stuff regarding the FaultException on the web and was able to get a small sample working with the regular WCF service.
I thought it would be similar within my actual project. But unfortunately I am running into some issues(probably due to my lack of WCF + RIA services knowledge).
So in my actual project my Context class derives off of LinqToEntitiesDomainService.
I created a new ContextFaultException class which had some methods to capture some custom error messaging.
Then I applied the [FaultContract(typeof(ContextFaultException))] to some of the methods in my Context class. Everything compiles and all is fine. But when I published to a website and then when I added this service reference to the client, I don't see my new ContextFaultException in the Reference.cs file that's generated.
I thought may be moving it within the Context class will solve the issue. So I made my ContextFaultException class as an inner class of this Context class but I am running into some other issues. Before I try to figure out these issues, I just want to know if this the right approach?
Any suggestions/pointers??
TIA

The URL must be formatted to get to the namespace wdsl
for example:
namespace My.Namespace.Services
{
[EnableClientAccess()]
public partial class MyClassName : LinqToEntitiesDomainService<XXX>
{
....
}
}
Then use the following pattern for the url
http://YOURHOST/APP/Services/My-Namespace-Services-MyClassName.svc?wsdl
Use "-" for the "."

Related

Access Business Classes in WCF methods

I have an asmx web service I am converting to WCF. In the old structure I had a number of web service methods that accessed business classes to do the work. For example:
public DataSet GetAppointmentDataToConvert(string aAccessToken, string aStartingId)
{
//verify that the user is allowed to use this web service
if (!isAuthorized(aAccessToken))
{
throw new Exception("Not authorized");
}
cls256_BitEncryptionConversion cls256 = new cls256_BitEncryptionConversion();
return cls256.GetAppointmentDataToConvert(aStartingId);
}
This method initialized the cls256_BitEncryptionConversion class and called a method inside it to do the work, then returned the result.
I am trying to set up a WCF Service that will use the cls256_BitEncryptionConversion class, but despite both the class and the service being in the same namespace, my service method is unable to "see" the class. What am I doing wrong?
These are few tips for you to resolve it your self:
Make it sure that even they have the same namespace are they in the same project?
If they are in different project add it as you reference where you want to use it. And probably add a using directive if necessary.
I was able to resolve the issue by restructuring the project. I moved all the classes from the app_code folder into the root of the project.

WCF Callback implementation function never gets called

I am designing a WCF service with callback, but my implementation of the callback function never gets called. And I am confused about the generated service proxy, so please help.
Here is the scenario: in the server side, I defined the service interface IMyService and callback interface IMyServiceCallback, I also implemented the IMyService in the server project. Besides the server project, I surely have another client project, to which I added the service reference in VS. And I implemented the IMyServiceCallback interface on the client side. So here comes the problem: when I am debugging it, the function never goes into my implementation of IMyServiceCallback and of course the desired result never comes out.
And this is I where I got confused: when I added the service reference in the client side, it actually generated three interfaces on the local: IMyService, IMyServiceCallback, and IMyServiceChannel plus the client proxy class. And in my local implementation of IMyServiceCallback, I declared the class to implement the local IMyServiceCallback interface, not the one from service side. Could this be the problem? Why is there two declarations of the interface under different projects(and hence different namespaces)? The reason I implement the client side interface is, if I implemented from the server side interface, it would give the error: "InstanceContext provided to the ChannelFactory contains a UserObject that does not implement the CallbackContractType error" when I tried to call the service. And another confusing part is, on the server side if I declare the callback interface name as IMyCallback, or anything else, instead of IMyServiceCallback, the generated interface on the client side would still be IMyServiceCallback, which is the name of the service interface plus the suffix "Callback". And in this situation I also got the "InstanceContext provided to the ChannelFactory contains a UserObject that does not implement the CallbackContractType error".
I guess there is something that I misunderstood about the "add service reference" and how I should implement the interface(which one to implement). Could anyone help me? Thanks!
Updated:
I somehow fixed the problem. Firstly, the two declarations is fine is desired. The local client will need to implement the local interface, which is generated when adding the service reference. And my problem was that I also defined a DataContract but the generated reference file didn't have it. It could either because I had added the assembly of the service project as reference(somebody said in this case add service reference will not generate the Datacontract) or because I was missing DataMember attribute. But anyway, after I fixed both parts, the function is working now.
When you "Add Service Reference" and generate a proxy, it is totally separate from your service implementation. Remember, you may be consuming a service that you have not written and do not have access to the service source code.
The client code should use the client generated interfaces. If you change your service, you need to regenerate the proxy.
If you find this too messy, and you know you will always control both ends, you can share the service interfaces in a common assembly and generate a proxy class at runtime using DuplexChannelFactory.CreateChannel().
As for your problem, I can only assume you are not registering your callback properly. This is covered here.
if you want publish , you must implement IMyServiceCallback and IMyService together in same project.
if only subscribe , you must implement IMyServiceCallback interface
I fixed the issue when my callback instruction was embedded in a function call.
I learned that placing the callback in just a method that does not return a result works fine.
However, when the callback instruction is placed within a function I ran into timeout issue.
I resolved it by using a backgroundworker thread within the function being invoked:
public static IMyServiceCallback Callback;
.
.
.
TaskStateData taskStateData = GetSomeData();
BackgroundWorker backgroundWorker = new BackgroundWorker();
backgroundWorker.DoWork += (se, ev) =>
{
Tuple<OperationContext, TaskStateData> data = ev.Argument as Tuple<OperationContext, TaskStateData>;
var operationContext = data.Item1;
if (operationContext != null)
{
Callback = operationContext.GetCallbackChannel<IMyServiceCallback>();
Callback.OnCallBack();
}
};
Tuple<OperationContext, TaskStateData> payload = new Tuple<OperationContext, TaskStateData>(OperationContext.Current, taskStateData);
backgroundWorker.RunWorkerAsync(payload);

Creating a log for WCF operations / getting app directory

I want my WCF service to log errors / operations, etc.
I have a very simple logging class but finding the directory to create / write to is returning a null reference exception:
public static string Path()
{
return Path.GetDirectoryName
(Assembly.GetEntryAssembly().Location);
}
This works in say a console app but not WCF, perhaps there is a different convention?
Or alternatively are there any simple libraries for logging in WCF?
WCF has built-in message logging, following links should help you.
http://msdn.microsoft.com/en-us/library/ms730064.aspx
http://geekswithblogs.net/mnf/archive/2008/10/03/use-wcf-message-logging.aspx
http://mkdot.net/blogs/dejan/archive/2008/10/23/wcf-tracing-and-message-logging.aspx

Unable to get WCF Test client to test WCF Service Library

I am attempting to replace a WSE service with the WCF equivalent where the WSDL is provided externally.
First, I used svcutil and wsdl to generate all the service and client classes (ATP, I'm only concerned with the service implementation.) I generated an empty WCF Service Library project and replaced/renamed the IService1.cs with a class named for the interface ServiceContractAttribute generated. I then renamed the implementation class Service1.cs with the name of the implementation-class JINDEXWcfListener.cs. I removed the generated code from this class and created class definition JINDEXWcfListener:[interface name].
The tool auto-generated the implementation of the interface. I used the single method adorned with [OperationContractAttribute] to put my local implementation code. I modified the default app.config generated to adjust the contract and service names as required.
When I start debug, I can see that the service is starting in the WTC. However, when the single operation is exposed, the is a red dot with a yellow question mark in front of the operation name. When I RC on the op name, I get "This operation is not supported in WCF Test client" with no additional information. What is wrong?
WCFTestClient has quite a few limitations. I have fought "problems" for several hours that later turned out to be just WCFTestClient problems. Complex objects can give you a lot of grief, also any custom lists, etc such as a custom implementation of the IList interface. Try out WcfStorm. I think they have a free version and a trial version.

Change Casing in WCF Service Reference

I'm creating a service reference to a web service written in Java. The generated classes now follow the Java casing convention used in the web service, for example class names are camelCase rather than PascalCase.
Is there a way to get the desired casing from the service reference?
CLARIFICATION:
With WSE based services, one could modify the generated Reference.cs to provide .NET standard casing and use XmlElementAttribute to map to the Java naming presented by the external web service, like this:
[System.Xml.Serialization.XmlElementAttribute("resultType", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
[System.Runtime.Serialization.DataMember]
public virtual MyResultType ResultType
{ ... }
Not terribly maintenance-friendly without writing custom code to either generate the proxy code or modify it after it's been generated.
What I'm after is one or more options to present a WCF generated client proxy to calling applications using the .NET casing conventions, achieving the same as I did previously with WSE. Hopefully with less manual effort.
Well, since your WCF client proxies are partial classes, you could always add a second file for the same class, which implements the PascalCasedMethodName for each javaCasedMethodName and then just call the Java method from your new method.
public partial class MyClientProxy
{
......
public MyResultType GetResultType(string inputParam)
{
return this.getResultType(inputParam);
}
......
}
Seems a bit redundant - but that should really work, I think. Since your code is stored in a separate file, it won't be overwritten if you re-create the client proxy - and since it's the second part of a partial class, it will be "merged into" the class definition for your client code to call.