I'm consuming a WCF service in my project for which I've added the reference using 'Add Service Reference...'. I expected it to generate a clean proxy with a ServiceClient entity and the Interface. Instead, I see that it has created a MethodNameRequest, MethodNameRequestBody, MethodNameResponse, MethodNameResponseBody entities for each OperationContract method.
So while invoking the service methods, the proxy passes to the service method an instance of MethodNameRequest with the input parameters of the method as the properties of the RequestBody. See below an example of a call to AboutInformationGet() method which doesn't accept any parameters.
public WCFDynamicInvocation.PostingService.AboutModel AboutInformationGet() {
WCFDynamicInvocation.PostingService.AboutInformationGetRequest inValue = new WCFDynamicInvocation.PostingService.AboutInformationGetRequest();
inValue.Body = new WCFDynamicInvocation.PostingService.AboutInformationGetRequestBody();
WCFDynamicInvocation.PostingService.AboutInformationGetResponse retVal = ((WCFDynamicInvocation.PostingService.IMIGQPosting)(this)).AboutInformationGet(inValue);
return retVal.Body.AboutInformationGetResult;
}
I believe this behavior is what one would expect to see in a Webservice Proxy. Hence I suspect that the WCF service is not properly configured.
Did someone here face this issue? What would be the change to be done at the service so that the proxy generated is similar to the WCF service.
Cheers.
There is a similar post here.
Right click your service reference -> Configure service reference... -> Check if "Always generate message contracts" check box is checked. Uncheck it and hit OK to regenerate the proxy to see if you get a normal proxy.
After struggling with this for some time, I've finally found that the cause for the message contracts in the proxy was the service interface had the following attribute:
[XmlSerializerFormat(Use = OperationFormatUse.Literal, Style = OperationFormatStyle.Document)]
As I understand, I could decorate the DataContracts with the following attribute to avoid wrapping
[MessageContract(IsWrapped = false)]
but the response still gets wrapped as the OperationContract hasn't been modified.
As there were no particular need to use XMLSerializer in place of WCF's default DataContractSerializer, we would remove the XmlSeralizerFormat decoration.
Related
I have gone through following references and found that a WCF service can be called dynamically. But, i have not been able to call a service (method) accepting parameters as ref and out.
Calling a WCF service from a client without having the contract interface
Dynamic Programming with WCF
Dynamically Invoking Web Services... With WCF This Time
Invoking WCF Service without adding a Service Reference.
Is there any way to make such call with ref and out parameters?
Invoking WCF Service without adding a Service Reference. works greate provided i know the Contract. So i added the web reference first, copied the generated proxy into actual project and then removed the web refernce and simply called the method as
BasicHttpBinding binding = new BasicHttpBinding();
EndpointAddress epAddr = new EndpointAddress("http://192.168.0.233/GMS/GMSService.svc");
GMSContract.IGMSService _interface = ChannelFactory<GMSContract.IGMSService>.CreateChannel(binding, epAddr);
...
bool r = _interface.MyGMSMethod(..., ref ..., out ..., out ...);
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);
I am trying to use a web service (https/ssl/basicHttpBinding). I add service reference without issues and call it asynchronously. I pass the instance of the client to the CallBack. I get this error when trying to get the result from the service at the CallBack:
Header
http://schemas.xmlsoap.org/ws/2004/08/addressing:Action
for ultimate recipient is required but
not present in the message.
var Result = client.BeginTheServiceOperation(header, CallBack, client);
private static void CallBack(IAsyncResult ar)
{
var client = ar.AsyncState as MyServiceSoapClient;
var result = client.EndTheServiceOperation(ar); // ERROR OCCURS HERE
Console.WriteLine(result);
}
What am I missing?
Thanks
It turns out that the service was expecting SOAP 1.1 and by default WCF uses SOAP 1.2. I needed to create a new custom binding, passing that configuration in and it all worked ok. This pointed me in the right direction: http://social.msdn.microsoft.com/Forums/en/wcf/thread/f3707303-4f35-4079-ac0b-eba4717cada8
This is an indication that you have not applied the the proper message configuration options to your binding. The service is expecting a SOAP message with WS-Addressing headers, but apparently your client is not passing them. Since the default binding would pass them, I have to assume you've changed your binding in some way that would prevent them from being passed.
If more assistance is required, please also add your binding configuration code/config XML to the original post.
I need to create a WCF service that will emulate some third-party service. That service has very complicated messages and wrappers for them, so I will simplify them in description.
I have WSDL of that service and created proxy class. But here the first problem occurs: all methods in proxy have
[System.ServiceModel.OperationContractAttribute(Action = "", ReplyAction = "*")]
So it is impossible to create WCF service with many methods: each for one method in proxy because every method must have unique Action. I think that third-party service has one method that handles all requests. And I created such method with needed KnownType attributes on RequestTypeBase and ResponceTypeBase. All proxy-class methods have one parameter of type, derived from RequestTypeBase.
And here is the main problem and question: when WCF service tries to deserialize message body, it throws an exception saying that expected elementName is "Process" (the name of my mega-method that processes all requests) but existing elementName is "RequestType1" (the name class with data that must be passed to "Process" method as parameter). So how can I receive such message?? Is there some attribute in WCF to not require the methodName as root of Message body? And I even not understand for what does WCF need that MethodName there if he already knows what method is called? Looks like redundancy with action specification.
Maybe simple MessabeBody example that is successfully processing by WCF, will help to understand what I mean:
<s:Body>
<TestMethod xmlns="someNamespace">
<x>1</x>
<str>param2</str>
</TestMethod>
</s:Body>
You could skip WCF deserialization completely on the service side by using the "universal service contract":
[ServiceContract]
public interface IUniversalRequestResponseContract
{
[OperationContract(Action="*", ReplyAction="*")]
Message ProcessMessage(Message msg);
}
and then handle deserialization yourself working with the Message instance received.
If you are writing a stub emulation of some external service for testing purposes (I'm guessing), that is a good approach anyway because you can control exactly what is sent in the response.
I have a class, in which I have a service reference (WCF) to an ASMX web service.
This obviously generates local proxy methods such as
string DoSomething(string someParameter, string someOtherParameter)
I have a method that receives a WCF message class already representing a call to this service, which I simply need to forward
I could of course use XmlDictionaryReader to extract the information from the WCF message, deserialise into the proxy classes and pass those into the proxy method, but as these will simply get serialised back it seems very wasteful
How can I call the service using the already serialised message? (I assume I will need to modify the soap action on the incoming message)
There's a two-part series on how to build a WCF router on MSDN - maybe that helps? Seems like that's more or less what you're trying to do - use a WCF service to basically route a message on to a second service (ASMX in your case).
Marc