Calling WCF service from dynamics crm 2011 plugin - wcf

I have written a plugin for Dynamics CRM 2011 that calls a WCF service hosted on a different server. Below is the code in my plugin. In the class library for the plugin I have not used a service reference but used svcutil.exe to generate a WCF client.
var binding = new BasicHttpBinding();
binding.Name = "BasicHttpBinding_IMyService";
binding.Security.Mode = BasicHttpSecurityMode.None;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
binding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;
binding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName;
var endpoint = new EndpointAddress("http://test/MyService.svc");
ChannelFactory<IMyService> factory = new ChannelFactory<IMyService>(binding, endpoint);
IMyService channel = factory.CreateChannel();
channel.InsertTest(testobject);
I am getting the following error:
'System.Threading.Tasks.Task`1[System.Int32]' cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute. If the type is a collection, consider marking it with the CollectionDataContractAttribute. See the Microsoft .NET Framework documentation for other supported types.
Anyone had experience trying to do this? Or any ideas on what I am doing wrong?

The error your getting is with the serialization of the object you're sending. Check to see if your testobject has a Task property. If it does, consider ignoring it during serialization. See this SO post.

Make sure the service is set up correctly. I cried blood a few months ago doing that. Google for "Setting up a basic WCF web service for REST in VS 2010" and you'll probably get a hit on WordPress blog where I explain the approach. (Not trying to self-promote here. I wish someone else had that blog before I resolved the issue myself. Really.)
Show the code that you're using to connect to the service. When I get to work tomorrow, I can compare with mine and find any difference. I remember that I had this serialization issue but I'm not sure how we killed it. But we did, somehow. (And check if Daryl's hint works. It could.)

Related

Facing an issue while using existing Web service as wcf into VS 2012

I have one of webservice which as below method
c.Accountdata ad = new Accountdata();
c.response res = ad.PostData(RequestData);
NOw, i have used above webservice into vs 2012 as add service reference so, it is added as a WCF SERVICE.
Now, i get below code.
c.AccountdataSoapClient ad =new AccountdataSoapClient();
c.response res = new c.response();
ad.PostData(REQUESTHEADER,RequestData,out res).
//in above method, two argumnets are increased (HEADER AND OUT PARAMETER).
I have passed request header instance as it is not actually existed in web service.
NOW, PROBLEM: it throws CLIENT FAULT EXCEPTION.
please suggst me how i could use same web service into this VS 2012 and correct such issue.
not sure, how old webservice schema map into WCF.
Thanks
If your web service is an old-style web-service (not WCF) then you should add a reference to it by this old-services compatibility menu, and use it as you are used it before:

Proxy generated for WCF creating Message Contracts

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.

Config Framework and WIF Federation+Delegation: Need factory.CreateChannelActingAs(token)

My current task is to secure a WCF service. The service is hosted using the configuration framework (5.5, released with the StockTraider sample) and the caller uses the configuration framework as well.
I managed to secure the connection using ws2007FederationHttpBinding.
For the "IsOnline()"-Check my STS issues a service token and this works already but for the actual service calls, I want to have ActAs-Tokens to still know the real user inside the called service.
My STS is capable of issuing the correct ActAs-Tokens.
The problem is the loadbalancing client, which always opens the factory and I cannot call the WIF-methods (ConfigureChannelFactory() and CreateChannelActingAs()) anymore, because they require the factory to be in the created state.
My best try is this, but it looses the ActAs-Subject somewhere and feels like a hack:
IPSServiceClient = new Client(serviceName, settingsInstance, createNewChannelInstance: true);
var token = ((IClaimsIdentity)Thread.CurrentPrincipal.Identity).BootstrapToken;
var factoryObject = IPSServiceClient.createANewChannelFactoryByAddress(IPSServiceClient.getANodeAddress());
var factory = factoryObject as ChannelFactory<IIWBPortalServiceV1>;
factory.ConfigureChannelFactory(); //factory must not be state=open here
factory.Credentials.SupportInteractive = false; //no cardspace
_channel = factory.CreateChannelActingAs(token);
Do I miss an extensibility point in the config framework? What is the best way I should go?
If I make a new console app, add service reference and add the two calls (ConfigureChannelFactory() and CreateChannelActingAs()) it just works!
The posted code inside my questions works. The problem was the web.config of the STS which was missing AudienceUris inside the ActAs-securityTokenHandlers section.
Still: The posted code feels like a hack to me.

Capture global WCF ServiceHost request events

I'm using a really simple WCF project which is being hosted by a WPF application. It basically operates as a REST server for dishing up data on my PC. No IIS, and it runs as SingleInstance. I want to see what IP's are accessing MyService, and what WebMethod they're attempting to invoke.
Ok so I can have an event as part of my Service, declared in the service class itself. Here's some code that gets it going, it all works exactly as expected (no flames about m_ please ;)):
MyService ds = new MyService(); // It's not really called this :)
ds.Request += new EventHandler(ds_Request); // I want to avoid this
ds.SomePropertySetFromMyRehostingClient = "something"; // SingleInstance now required
m_Service = new ServiceHost(ds, new Uri(GetServerHostUri()));
m_Service.Description.Behaviors.Find<ServiceBehaviorAttribute>().InstanceContextMode = InstanceContextMode.Single;
m_Service.BeginOpen(new TimeSpan(0, 0, 5), new AsyncCallback(EndStartService), null);
Then in each service method, I can raise this event so my app knows that someone has tried to use it. Brilliant, but let's face it, this is awful.
I have to write something along the lines of:
var who = OperationContext.Current.IncomingMessageProperties.Via;
var what = OperationContext.Current.IncomingMessageProperties["UriTemplateMatchResults"];
for each service call.
Is there a more generic catch-all-event that can detect a call to my service? There's probably one fired by one of the many Behaviour/ChannelDispatcher types which I admittedly don't fully understand.
Thanks for your help, Tom
Using IParameterInspector you can hook to any method calls and inspect the method and/or parameters.
There is no other way to get the extra information (IP address, etc) of the incoming message other than the one you have used. This is just a bad design by Microsoft IMHO (see my rant here).
You can find an example here.

WCF 4 REST service can't return a StatusDescription, only StatusCode

I'm currently migrating my WCF RESTful service from .NET 3.5 (Starter Kit) to .NET 4. I started my project using a WCF Rest service template from Visual Studio 2010.
I had to figure out how to keep my authorization scheme (formely done with RequestInterceptor) using ServiceAuthorizationManager. After some work and researching I got it done.
But now I have a collateral problem. My service used to feedback my client of any processing errors using HTTP status code and a brief description. I was using WebOperationContext at many points of my service method to describe to clients what went wrong, like this:
protected void returnCode(HttpStatusCode code, string description)
{
WebOperationContext ctx = WebOperationContext.Current;
ctx.OutgoingResponse.StatusDescription = description;
ctx.OutgoingResponse.StatusCode = code;
}
But in WCF 4, only StatusCode works - StatusDescription silently fails. I can't figure out why.
My only guess is that WebOperationContext doesn't work in this new WCF 4 scenario, and I should be using OperationContext instead, but that also doesn't work. The following method is used in my custom class extending ServiceAuthorizationManager, informing clients a request couldn't be access because auth digest was malformed:
private void GenerateBadDigestMessage(ref OperationContext operationContext)
{
Message reply = Message.CreateMessage(MessageVersion.None, null, null, new DataContractJsonSerializer(typeof(object)));
HttpResponseMessageProperty hrp = new HttpResponseMessageProperty();
hrp.StatusCode = HttpStatusCode.Forbidden;
hrp.StatusDescription = "bad digest";
reply.Properties[HttpResponseMessageProperty.Name] = hrp;
operationContext.RequestContext.Reply(reply);
operationContext.RequestContext = null;
}
Even by using OperationContext direclty here (insted of WebOperationContext), StatusDescription doesn't work.
What I'm missing here? Why such a small thing can break from .NET 3.5 to 4?
I recommend you to use WebFaultException in .NET 4.0. Read for example "Introducing WCF WebHttp Services in .NET 4". Try
throw new WebFaultException<string> ("bad digest", HttpStatusCode.Forbidden);
OK! Here is what I found out. There is nothing wrong with my code. There is nothing wrong with .NET framework 3.5 or 4.0.
The problem is asp.net development server. When you are debugging your service application, it is likely to be hosted on asp.net development server and it completely ignores the status description given by application. Refer this question.
Awarding the bounty to #Oleg who at least tried to help me.
One potential problem is that you are setting the RequestContext to null:
operationContext.RequestContext.Reply(reply);
operationContext.RequestContext = null;
Another possibility is that the parameter "description" is not set.
Also on the client side are you checking:
WebOperationContext.Current.IncomingResponse.StatusDescription
One more possibility, could the values have been overwritten after returnCode was called?
Make sure you return from the Service Method NULL object...so that Status code description is visible in Response Headers, it worked for me.