Development

How to across domain post data to WCF Service by CORS

For the most application, to post data to service is very common and popular. However, it will be hard to across domain post data to a WCF service especially from SharePoint Site Collection by SSL REST request. You may have an authorization problem on this. You may also miss the data posted by web client. I have talked a way to solve the cross domain issue. The JSONP may help to get data for WCF service. However, it is not a better idea to post data by JSONP. Especially, you have a high requirement of security. In this article, we will introduce one way to cross-domain post data to WCF service in SharePoint Site Collection. I think you will benefit from this blog.

 

  1. Introduction

Imagine it that you want to submit a form data to the WCF service which is running on another domain. However, the data is sensitive to the security. So we cannot use JSONP to solve our problem. Because JSONP only supports the GET way with implicitly parameter appended in the URL. The CORS (Cross-Origin Resource Sharing) is another way to solve the cross-domain problem. The CORS builds the trust between browser and service by custom HTTP header information. The advantage of CORS is that it can support all kinds of request like POST. However, it is not supported by browsers with old version. Good news is that it have been supported in the latest version of many popular browsers. I have introduce the steps to solve the cross domain issue by JSONP in the article: How to cross-domain SSL access to WCF Service in SharePoint Site Collection by JS: JSONP call in the GET way. For CORS, Only the WCF Service API and Client-Side Ajax Code is different from the JSONP sample. Other steps should be the same. So in this paragraph, I will just focus on the WCF Service Interface and Client-Side cross-domain Ajax Call.

  1. WCF Service for POST method

In my previous article about cross domain, I listed the steps to set authentication & credential and configure cross-domain enabled and WCF REST communication. We need to do the same operations before we start this section content. Supposed it that you have finished the above steps, let’s step into the WCF Service implementation for POST method. The [AspNetCompatibilityRequirements] attribute is also necessary to be stuck to the Service implementation class as the following code shows:

[AspNetCompatibilityRequirements(

RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]

Besides, we need add [WebInvoke] attribute for each Operation Contract Method of Service to declare the HTTP request invoke method. For this paragraph, it should be ‘POST’. What’s more, we also need to define the request and response message format way. So it will looks like this:

[WebInvoke(Method = “POST”, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle=WebMessageBodyStyle.WrappedRequest, UriTemplate = “SaveData”)]

Then we need define the Operation Contract Method with non-parameter. For an example, we will have a method like ‘public void SaveData()’ instead of ‘public void SaveFormData(CustomModel param)’. Because there is a parameter parsing problem. If you give a parameter list to method, you will get a bad request error when you try to call the service. So how to get the data from HTTP request? One way is to use the ‘OperationContext.Current. RequestContext.RequestMessage’ object. Please watch out the usage of ‘System.Web.HttpContext.Current.Request’ object. If you want to read the data from the input stream of ‘System.Web.HttpContext.Current.Request’ object, you will get nothing more than an exception. It seems that the input stream have been disposed before you read data from it. The good news is that you can do it like the following:

using (var reader =

OperationContext.Current.RequestContext.RequestMessage.GetReaderAtBodyContents())

{

if (reader.Read())

{

string json = new

  string(Encoding.UTF8.GetChars(reader.ReadContentAsBase64()));

CustomModel model = JsonConvert.DeserializeObject<

CustomModel >(json);

//To do

}

}

So far, we have finished all the service code. You can start the deployment task. The detail information of deployment is referred in my previous article about cross domain.

 

  1. Cross-Domain Ajax Call

After you have deployed the service, we can start to code the client-side Ajax call. It will be very easy. There is an example:

$.ajax({

type: “POST“,

url:ns.Configuration.serviceUrl,

data: JSON.stringify(formData),

dataType: “text“,

crossDomain:true,

processData: true,

xhrFields:{

withCredentials: true,

},

success: function (data, status, jqXHR) {

},

error: function (xhr) {

}

});

 

At first, you need to set the type of Ajax call to ‘POST’. And then figure out the service URL. Pay attention to the data you want to post. It should a string with JSON format. If you pass a JSON object, you may get a string data with the format like ‘key=value’. For the ‘dataType’, you need check the returned result of service. If the service method has no result return, it is better to set its value to ‘text’. If you want to parse it to JSON object, you should return the data and set the HTTP response content type to ‘application/json; charset=utf-8’. The most important is to add ‘crossDomain’ in the options and set its value to true. Then you can add your business logic in the success callback event.

  1. IE Compatible Issue.

There is also a strange problem about CORS Post cross-domain request by IE browser. In general, the cross-domain Ajax call will trigger the window authentication. And the browser will pop up a dialog to let you to login as the diagram 4-1 shows.

1

Figure 4-1: Browser Security Dialog.

 

However, IE will miss it when you try to execute CORS Post code. The code can work correct in other browser like chrome. So far, I cannot figure out why. However, I have come up the solution to solve this problem. You can populate JSONP call before the CORS Post. The JSONP will drive the browser to pop up the Security Dialog. After you enter your secure account, the CORS Post will go well.

About the Author

More from this Author

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Subscribe to the Weekly Blog Digest:

Sign Up
Categories