Search

Jun 24, 2010

OperationFormatter could not serialize error with WCF

I was working with calling WCF from iPhone, I have posted one post on “how can you call WCF from iPhone” you can find here. While I was working with this, I faced this issue and after doing some research I found solution! Here is what I did.

Following operation contract works fine.

[OperationContract]
public Dictionary<string, string> GetDictionary()

Note that I have only put operation contract not decoration which needed to work WCF with iPhone and Json.
But if we change this that operation contract to following...

[OperationContract]
public string GetDictionary()

After doing this I started getting follwoing error.

The OperationFormatter could not serialize any information from the Message because the Message is empty

I was wondering as it was issue with primitive type string! where it was working find with complex type. I searched a lot but did not get any solution for this. The service was retuning Serialized Json data; but not sure what was wrong there. I was searching for workaround to this but didn’t find any then I wrap that string into concert class and and return that class object, and you don’t believe it works fine! Error is gone I fixed The OperationFormatter could not serialize any information from the Message because the Message is empty error, wow!!!!!

I have modified operation and now it looks like following.

[DataContract]
public class Response
{
[DataMember]
public string Data { get; set; }
}

[OperationContract]
public Response GetDictionary()
{
return new Response() { Data = "success" };
}

It still open question why it was not working in only string, however it was working with Dictionary object and then with Abstract type! I assume that at the time of serializing request its not able to create object of string as its primitive type! Not sure its true but it works fine with wrapper.

Jun 22, 2010

wsdl-service-soap-address location having machine name not domain name

After fixing “Domain name replaced with machine name in WCF Service”, you can find solution in my previous post.

I found same issue but somewhere else, when you look into wsdl at the end where all services are listed there still machine name exists.

image

And hence any of the client will have following error.

There was no endpoint listening at http://domainname/ServiceName.svc that could accept the message. This is often caused by an incorrect address or SOAP action.

That is because it still uses computer name in soap address not domain name. Lets fix this issue too. We have to simply change endpoint address nothing more.

<services>
<service behaviorConfiguration="serviceBehaviour" name="Demo.Service.MultiEndPointsService">
<endpoint address="http://192.168.1.2/Demo.Service/MultiEndPointsService.svc/basic" binding="basicHttpBinding" bindingConfiguration="basicBinding"
contract="Demo.Service.MultiEndPointsService" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="serviceBehaviour">
<serviceMetadata httpGetEnabled="true" httpGetUrl="http://192.168.1.2/Demo.Service/MultiEndPointsService.svc/basic"/>
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>

Now let’s how wsdl looks like.

image

We are good to go!

Domain name replaced with Machine Name in WCF Service

I personally came across this issue WCF was taking machine name not IP address or domain name and also I got questions from forums about “how to replaced Machine Name with Domain name in WCF Service wsdl link?”. This occurs when we host WCF service on IIS then the links to wsdl is uses local machine name not the domain name or IP address.

image

You can see in browser [here I used IP address of my machine] in wsdl link its adding my computer name, this is same issue when I publish this service on production; the wsdl link is taking name of production machine not domain.

I found some solutions which changes the bindings on server but again that is not helpful for me on production server however it works well on local machine.

Then I was checking the configurations and found solution for how Domain name replaced with Machine Name in WCF Service without playing with IIS bindings. In service behavior we can change the behavior of serviceMetadata which will FIX our problem. We need to specify on what location metadata will resides httpGetUrl or httpsGetUrl. We can add url having domain rather machine name. So final configuration should look like following which is our solution.

<system.serviceModel>
<services>
<service name="Demo.Service.MultiEndPointsService" behaviorConfiguration="serviceBehaviour">
<endpoint address="basic" binding="basicHttpBinding" bindingConfiguration="basicBinding" contract="Demo.Service.MultiEndPointsService" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="serviceBehaviour">
<serviceMetadata httpGetEnabled="true" httpGetUrl="http://192.168.3.61/Demo.Service/MultiEndPointsService.svc/basic" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding name="basicBinding" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647">
<security mode="None"></security>
<readerQuotas maxStringContentLength="2147483647" />
</binding>
</basicHttpBinding>
</bindings>
</system.serviceModel>

You can see value of httpGetUrl; I have specified IP address

image

Now let’s see again in browser.

image

There you goo!!!

Jun 21, 2010

Calling WCF service from iPhone

WCF changes way of communication between application-to-application and intra-application. This post will help you to call WCF from iPhone application. First we will see what we have to do on WCF to let iPhone application call service. And the sample code which call WCF from iPhone.

First let’s create simple WCF service.

[ServiceContract(Namespace = "")]
[DataContractFormat]
public class MultiEndPointsService
{
[OperationContract]
public string GetDictionary()
{
Dictionary<string, string> dict = new Dictionary<string, string>();
dict.Add("IB", "Imran Bhadelia");
dict.Add("DO", "David Oliver");
dict.Add("NA", "Nick Althoff");
dict.Add("JJ", "Jay Joshi");
dict.Add("DL", "Dave Larson");
dict.Add("BA", "Brenda Ayong-Chee");
dict.Add("JP", "Jay Parikh");

StringBuilder sbJson = new StringBuilder();
new JavaScriptSerializer().Serialize(dict, sbJson);
return sbJson.ToString();

}
}

This is simple WCF Service. We need to add some decoration for enabling web script and handle POST method. We are going to send http post form iPhone application and send Json string as response. Doing so we also need to decorate our operation contract to set request and response format.

[ServiceContract(Namespace = "")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehaviorAttribute(IncludeExceptionDetailInFaults = true)]
[DataContractFormat(Style = OperationFormatStyle.Document)]
public class MultiEndPointsService
{
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.WrappedRequest,
RequestFormat = WebMessageFormat.Xml, ResponseFormat = WebMessageFormat.Json)]
[OperationContract]
public string GetDictionary()
{
Dictionary<string, string> dict = new Dictionary<string, string>();
dict.Add("IB", "Imran Bhadelia");
dict.Add("DO", "David Oliver");
dict.Add("NA", "Nick Althoff");
dict.Add("JJ", "Jay Joshi");
dict.Add("DL", "Dave Larson");
dict.Add("BA", "Brenda Ayong-Chee");
dict.Add("JP", "Jay Parikh");

StringBuilder sbJson = new StringBuilder();
new JavaScriptSerializer().Serialize(dict, sbJson);
return sbJson.ToString();
}
}

And following are the configuration settings

<system.serviceModel>
<services>
<service name="Demo.Service.MultiEndPointsService" behaviorConfiguration="serviceBehaviour">
<endpoint address="basic" binding="basicHttpBinding" bindingConfiguration="basicBinding" contract="Demo.Service.MultiEndPointsService" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="serviceBehaviour">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding name="basicBinding" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647">
<security mode="None"></security>
<readerQuotas maxStringContentLength="2147483647" />
</binding>
</basicHttpBinding>
</bindings>
</system.serviceModel>

We need to create basicHttpBinding so it get called form iPhone application, we haven’t sent security to call this method; and following is the Objective-C code which call WCF from iPhone.

NSString *soapMessage = [NSString stringWithFormat:@"<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"><SOAP-ENV:Body><GetDictionary></GetDictionary></SOAP-ENV:Body></SOAP-ENV:Envelope>"];

NSURL *url = [NSURL URLWithString:@http://localhost/Demo.Service/MultiEndPointsService.svc/basic];
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url];
NSString *msgLength = [NSString stringWithFormat:@"%d", [soapMessage length]];

[theRequest addValue: @"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
[theRequest addValue: @"urn:MultiEndPointsService/GetDictionary" forHTTPHeaderField:@"SOAPAction"];
[theRequest addValue: msgLength forHTTPHeaderField:@"Content-Length"];
[theRequest setHTTPMethod:@"POST"];
[theRequest setHTTPBody: [soapMessage dataUsingEncoding:NSUTF8StringEncoding]];

NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];

Once you parse the response it will look like following.

wsdl

You can also call operation contract having parameters, for that need to create proper message and then add it in SOAP-BODY that will work.

Jun 20, 2010

WCF Service with webHttpBinding-basicHttpBinding-wsHttpBinding

WCF Services are designed to support distributed services where consumed client. Services are typically have WSDL interface which any of client can consumed regardless of platform on which WCF is hosted on.

WCF Services having three portions, Class having methods, host environment to host service, and one or more endpoints. Endpoints is place where WCF Client connects to WCF Service. In order to accommodate different communication scenario you just need to create more then one endpoints, for each endpoint you specify the address, a binding and a contract. Address is simple listener; contract specify the format of message which will arrive on specified address and binding is let you configure transport protocol, encoding and security. There are few built-in bindings represented by System.ServiceModel.Channels.Binding class to support HTTP, TCP and MSMQ protocols.

That was brief about WCF, now lets come to our business. We need to use wsHttpBinding + basicHttpBinding + webHttpBinding all together. That means we need to have multiple ends points to our service for different-different scenario. Here are the Service contract and operation contracts which we are going to use.

image

We will add one by one binding and check into WCF Test Client. First we will add basicHttpBinding which is designed for interoperability utmost important, its using SOAP 1.1.

image

You can see single endpoints having address and bindings, we have added binding configuration name basicBinding, which have property like security mode to None, readerQuotas having setting for client who is reading data from channel, also maxBufferSize which is parameter defined size which can be passed thru channel. We can see bindings in WCF Test Client it will show basic http bindings having one method. The value of maxBufferSize and maxReceivedMessgaeSize should be same for transfer mode is buffered. We have added behavior configuration for our service; serviceMetadata httpGetEnabled="true" allows simple HTTP Get request to succeed for metadata retrieval, by default WCF does not exposed metadata.

We can use WCF Test Client to check whether our setting are correct or not. So open WCF Test Client and add service url into service project.

image

It shows that we have exposed our service using basicHttpBinding. Now lets add wsHttpBinding binding, which is design for security, reliable messaging and transactions and its using SOAP 1.2 along with WS-Addressing 1.0 for message version which will carry additional protocol headers.

image

We have added binding configuration to set security and session reliability. The reliable session WCF provides ensures that messages sent between endpoints are transferred across SOAP or transport intermediaries and are delivered only once and, optionally, in the same order in which they were sent

Now let’s check on our WCF Test Client.

image

So, we can see two endpoints has been exposed, one is for basic binding and other is web script bindings. We already add basic and ws bindings lets add now web bindings.

image

One more endpoint, it’s now easy to expose more then one endpoint for single operation contract. If you need any security or additional settings then you can add binding configuration for this endpoint, but for now we don’t need any configurations. Let’s check our WCF Test Client.

image

We can see all these three binding for single operation contract! You can see wsdl file which will expose all these three bindings.

image

So we have exposed webHttpBinding + basicHttpBinding + wsHttpBinding endpoints in WCF service using same operation contract. We can use webHttpBinding for Silverlight application and also Json call.

Jun 14, 2010

RadComboBox dropdown issue in IE

Hello All, I was facing issue with RadComboBox dropdown, its adding scrollbar in IE if an item is longer then default size.

image

This is normal behavior, as we have item which get fits into dropdown, now consider following case where we items which are little longer then before.

image

Here you can see horizontal scrollbar is appear as our text is little bit longer then min-width property. Min-width property allow you to set minimum width of dropdown. But this looks weird.

Solution: You need to override following default style of RadComboBox.

<style>
.rcbSlide div
{
width: auto !important;
min-width: 150px !important;
max-width: 400px !important;
}
.rcbList
{
position: relative !important;
}
</style>

We can see after applying this style into page, RadComboBox will look like following.

image