WCF service reference does not include commens from original service methods - wcf

I have created a simple WCF web service with a method. This method has comments on it.
Why does the comment not appear in the service reference for a consuming app?
Is there some other way to propagate to method comments to the proxy?
/// <summary>
/// Do some work
/// </summary>
public void DoWork()
{
}

It doesn't appear on the service reference because the comments aren't part of the service metadata. There are two options you can use to have the comments appear on the proxy:
Share the contract interface between the server and the client (i.e., not generate the proxy, but simply reuse your interface on the client side).
Use some custom WSDL export extension which is aware of the comments (or other attributes), and a custom WSDL import extension which can understand those when generating the client. The sample at http://msdn.microsoft.com/en-us/library/aa717040.aspx is one possible implementation.

Perhaps WCF Extras would work for you. It sounds like what you want.
"Adding WSDL Documentation from Source Code XML Comments"

Make sure your service reference is marked as internal instead of public and the warning will go away.

Related

WCF RIA services and WSDL generation

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 "."

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);

How to create a WCF web service within an ASP.NET application that can return instances of an interface as a transparent proxy

My use-case:
I already have a working ASP.NET application
I would like to implement a new Web Service as part of that application
I am supposed to use a WCF service (*.svc), not an ASP.NET web service (*.asmx)
The service needs to have one operation, let’s call it GetInterface(), which returns instance of an interface. This instance must reside on the server, not be serialized to the client; methods called on that interface must execute on the server.
Here’s what I tried (please tell me where I went wrong):
For the purpose of testing this, I created a new ASP.NET Web Application project called ServiceSide.
Within that project, I added a WCF Service using “Add → New Item”. I called it MainService. This created both a MainService class as well as an IMainService interface.
Now I created a new Class library project called ServiceWorkLibrary to contain only the interface declaration that is to be shared between the client and server, nothing else:
[ServiceContract]
public interface IWorkInterface
{
[OperationContract]
int GetInt();
}
Back in ServiceSide, I replaced the default DoWork() method in the IMainService interface as well as its implementation in the MainService class, and I also added a simple implementation for the shared IWorkInterface. They now look like this:
[ServiceContract]
public interface IMainService
{
[OperationContract]
IWorkInterface GetInterface();
}
public class MainService : IMainService
{
public IWorkInterface GetInterface()
{
return new WorkInterfaceImpl();
}
}
public class WorkInterfaceImpl : MarshalByRefObject, IWorkInterface
{
public int GetInt() { return 47; }
}
Now running this application “works” in the sense that it gives me the default web-service page in the browser which says:
You have created a service.
To test this service, you will need to create a client and use it to
call the service. You can do this using the svcutil.exe tool from the
command line with the following syntax:
svcutil.exe http://localhost:59958/MainService.svc?wsdl
This will generate a configuration file and a code file that contains
the client class. Add the two files to your client application and use
the generated client class to call the Service. For example:
So on to the client then. In a separate Visual Studio, I created a new Console Application project called ClientSide with a new solution. I added the ServiceWorkLibrary project and added the reference to it from ClientSide.
Then I ran the above svcutil.exe call. This generated a MainService.cs and an output.config, which I added to the ClientSide project.
Finally, I added the following code to the Main method:
using (var client = new MainServiceClient())
{
var workInterface = client.GetInterface();
Console.WriteLine(workInterface.GetType().FullName);
}
This already fails with a cryptic exception in the constructor call. I managed to fix this by renaming output.config to App.config.
I notice that the return type of GetInterface() is object instead of IWorkInterface. Anyone know why? But let’s move on...
Now when I run this, I get a CommunicationException when calling GetInterface():
The underlying connection was closed: The connection was closed unexpectedly.
How do I fix this so that I get the IWorkInterface transparent proxy that I expect?
Things I’ve tried
I tried adding [KnownType(typeof(WorkInterfaceImpl))] to the declaration of WorkInterfaceImpl. If I do this, I get a different exception in the same place. It is now a NetDispatcherFaultException with the message:
The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter http://tempuri.org/:GetInterfaceResult. The InnerException message was 'Error in line 1 position 491. Element 'http://tempuri.org/:GetInterfaceResult' contains data from a type that maps to the name 'http://schemas.datacontract.org/2004/07/ServiceSide:WorkInterfaceImpl'. The deserializer has no knowledge of any type that maps to this name. Consider using a DataContractResolver or add the type corresponding to 'WorkInterfaceImpl' to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding it to the list of known types passed to DataContractSerializer.'. Please see InnerException for more details.
The InnerException mentioned is a SerializationException with the message:
Error in line 1 position 491. Element 'http://tempuri.org/:GetInterfaceResult' contains data from a type that maps to the name 'http://schemas.datacontract.org/2004/07/ServiceSide:WorkInterfaceImpl'. The deserializer has no knowledge of any type that maps to this name. Consider using a DataContractResolver or add the type corresponding to 'WorkInterfaceImpl' to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding it to the list of known types passed to DataContractSerializer.
Notice how this seems to indicate that the system is trying to serialize the type. It is not supposed to do that. It is supposed to generate a transparent proxy instead. How do I tell it to stop trying to serialize it?
I tried adding an attribute, [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)], to the WorkInterfaceImpl class. No effect.
I tried changing the attribute [ServiceContract] on the IWorkInterface interface (declared in the shared library ServiceWorkLibrary) to [ServiceContract(SessionMode = SessionMode.Required)]. Also no effect.
I also tried adding the following magic system.diagnostics element to the Web.config in ServerSide:
<system.diagnostics>
<!-- This logging is great when WCF does not work. -->
<sources>
<source name="System.ServiceModel" switchValue="Information, ActivityTracing" propagateActivity="true">
<listeners>
<add name="traceListener" type="System.Diagnostics.XmlWriterTraceListener" initializeData="c:\traces.svclog" />
</listeners>
</source>
</sources>
</system.diagnostics>
This does generate the c:\traces.svclog file as promised, but I’m not sure I can make any sense of its contents. I’ve posted the generated file to pastebin here. You can view this information in a more friendly UI by using svctraceviewer.exe. I did that, but frankly, all that stuff doesn’t tell me anything...
What am I doing wrong?
The use-case I am describing is not directly supported by WCF.
The accepted work-around is to return an instance of EndpointAddress10 which points to the service for the “other” interface. The client must then manually create a Channel to access the remote object. WCF doesn’t properly encapsulate this process.
An example that demonstrates this is linked to from the MSDN article “From .NET Remoting to the Windows Communication Foundation (WCF)” (find the text that says “Click here to download the code sample for this article”). This example code demonstrates both .NET Remoting as well as WCF. It defines an interface that looks like this:
[ServiceContract]
public interface IRemoteFactory
{
IMySessionBoundObject GetInstance();
[OperationContract]
EndpointAddress10 GetInstanceAddress();
}
Notice that the interface-returning method is not part of the contract, only the one that returns an EndpointAddress10 is marked with [OperationContract]. The example calls the first method via Remoting, where it correctly creates a remote proxy as one would expect — but when using WCF it resorts to the second method and then instantiates a separate ChannelFactory with the new endpoint address to access the new object.
What is MainServiceClient()? It is the class marshaling the client messages to the server.
You should take a look at a related SO post on returning interfaces as parameters in WCF. ServiceKnownTypeAttribute may be helpful.
Sessions may also be what you're looking for MarshalByRef as it relates to .NET Remoting behaviors.
Another approach (as mentioned on MSDN Forums) is to return the EndpointAddress of the service interface instead of the interface itself.
WCF does serialize everything - regardless of the binding. The best approach you should take if you need to communicate with the service on the same system is to use IPC transport binding (net.pipe).
What you are trying to do is a direct violation of the SOA Tenet: "Services share schema and contract, not class". What this means it that you don't actually pass implementation code from the service to its consumers, just the return values that are specified in the contract itself.
The main focus of WCF and SOA in general is interoperability, meaning services should be accessible to clients of any platform. How would a Java or C++ consumer be able to use this service you are designing? Short answer is that it couldn't, which is why you will find it difficult if not impossible to serialize this code over messaging standards like SOAP.
A more appropriate way to structure this code would be to host each implementation of IWorkerInterface as its own service (it has been defined as a service contract, after all), and expose each service on a different endpoint. Instead of MainService behaving as remote factory for proxies to an IWorkerInterface, it could act a as an endpoint factory to the different services you have set up. Endpoint metadata could easily be serialized and provided to the client by IMainService. The client could then take that metadata and construct a proxy to the remote implementation, either through some custom IServiceProxy implementation, or even through the objects already provided to you by WCF (such as the ChannelFactory).

What is client base class , how to use it?

I am just curious to know that what is ClientBase class in WCF, and how can i use it.
I surfed the internet and i found that this class is used to create proxies to call service methods , but no example.
Please anyone explain it with example , it will help me undestand this class...
It's the base class for your client proxies being generated by either "Add Service Reference", the svcutil.exe command line utility, or by your custom code if you don't want to use any of those methods.
It's a generic type that takes the generated client-copy of the service contract as its type parameter.
It can be extended, if you wish to do so - e.g. see IDesign's download page for a few samples of what can be done, things like:
AsyncClientBase for safe asynchronous calls
HeaderClientBase for simplified support of custom headers in your messages
Marc
It's there for autogenerated proxies which are created when service references are added to your project, not really for your own use.

Force WCF to call a method on every request before entering actual function

I have a RESTful WCF service with many different functions. For each function I need to call an authentication method that I have written. I can manually call this method on every request but I was looking for a way to force the WCF engine to call this method before these functions are entered. Does anyone know if this is possible?
Cheers
You could use the "Custom Behavior" approach.
You would need to write a Class that implements IDispatchMessageInspector. The following MSDN magazine article gives a nice explanation of this: Extending WCF with Custom Behaviors (link points to Wayback Machine cached copy; downloads likely don't work).
To force WCF REST Service to first call a method especially if it's for authorization
customize/override CheckAccessCore method of System.ServiceModel.ServiceAuthorizationManager
refer: http://msdn.microsoft.com/en-us/library/ms731774(v=vs.110).aspx
If it's for authorization, can't you use the built in services?
For instance, there is the PrincipalPermission attribute. Does that help in your case?
You could think about creating a WCF routing service. You would call a fixed endpoint - your authentication method - and then from there on, route your calls to the actual methods, based on some indication in the request.
For .NET 4, the Routing Service functionality will be included into WCF out of the box.
What I don't know is how that all matches REST, though.
I came across this post, while searching for the same thing.None of the answer's were simple/quick solution so if you just want a function to be called before every method then you can do what i just did:
I created a zero argument constructor:
public class myService : ImyService
{
myService ()
{
ConnectToDatabAse();
FunctionYouWantToCallBeforeEveryMethodCall();
//Add here more
}
}