Recently I was writing a custom SharePoint WCF service for using in client side JavaScript libraries (jquery, angular) and C# server side call HttpWebRequest without worrying adding references and proxy classes. Majority of the articles I referred to were only showing JSON output; I wanted this service to provide both JSON and Xml data formats. If the requirement is to output both JSON and Xml formats, I found people writing two method calls:one for each JSON and Xml. Also, I have seen articles where response was driven through method or query string parameter to get requirement format (WebMessageFormat.Xml, WebMessageFormat.Json) If I follow the former approach as shown below, the amount of code will grow twice the code that I actually need which is very inefficient and demand more maintenance.
[ServiceContract]
interface IPersonService
{
[WebGet(UriTemplate = "person/{id}", ResponseFormat = WebMessageFormat.Json)]
Person GetPersonJSON(int id); //get JSON output
[WebGet(UriTemplate = "person/{id}", ResponseFormat = WebMessageFormat.Xml)]
Person GetPersonXml(int id); //get Xml output
}
All I wanted was automatic formating based on some configuration or flag set through code. While searching for options. I found this technet article. helpful.
WCF Web HTTP Automatic and Explicit Formatting options
https://msdn.microsoft.com/en-us/library/ee476510(v=vs.110).aspx
(snippet from technet)
Automatic Formatting
The WCF Web HTTP programming model allows you to dynamically determine the best format for a service operation to return its response in. Two methods for determining an appropriate format are supported: automatic and explicit.
When enabled, automatic formatting chooses the best format in which to return the response. It determines the best format by checking the following, in order:
- The media types in the request message’s Accept header.
- The content-type of the request message.
- The default format setting in the operation.
- The default format setting in the WebHttpBehavior
(/snippet from technet)
Solution:
- Added web.config file to my custom wcf custom service. C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\isapi\<MyCustomWCFService>
- Added System.ServiceModel section as show below.
<configuration>
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior>
<webHttp automaticFormatSelectionEnabled="true" />
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
Have only service contract method.
[ServiceContract]
interface IPersonService
{
[WebGet(UriTemplate = "person/{id}")]
Person GetPerson(int id);
}
Now I can the call same method through jquery/ajax by specifying the ContentType or Accept Header and get the output format that I need.
JavaScript - JSON Output
function getPerson() {
var serviceUri = _spPageContextInfo.webAbsoluteUrl" + "/_vti_bin/<MyCustomService>/PersonService.svc/person/" + id;
$.ajax({
type: "GET",
contentType: "application/json",
url: serviceUri,
dataType: "json"
}).done(function (data) {
//do something here
}).fail(function (error) {
});
}
var serviceUri = _spPageContextInfo.webAbsoluteUrl" + "/_vti_bin/<MyCustomService>/PersonService.svc/person/" + id;
$.ajax({
type: "GET",
contentType: "application/json",
url: serviceUri,
dataType: "json"
}).done(function (data) {
//do something here
}).fail(function (error) {
});
}
JavaScript - Xml Output
function getPerson() {
var serviceUri = _spPageContextInfo.webAbsoluteUrl" + "/_vti_bin/<MyCustomService>/PersonService.svc/person/" + id;
$.ajax({
type: "GET",
contentType: "application/xml",
url: serviceUri,
dataType: "xml"
}).done(function (data) {
//do something here
}).fail(function (error) {
});
}
Server Side C# - HttpWebRequest - JSON Output
HttpWebRequest endpointRequest = (HttpWebRequest)HttpWebRequest.Create(serviceUri);
endpointRequest.Method = "GET";
endpointRequest.Accept = "application/json;odata=verbose";
Server Side C# - HttpWebRequest - Xml Output
HttpWebRequest endpointRequest = (HttpWebRequest)HttpWebRequest.Create(serviceUri);
endpointRequest.Method = "GET";
endpointRequest.Accept = "application/xml;odata=verbose";
References:
- https://social.technet.microsoft.com/wiki/contents/articles/24194.sharepoint-2013-create-a-custom-wcf-rest-service-hosted-in-sharepoint-and-deployed-in-a-wsp.aspx
- https://msdn.microsoft.com/en-us/library/ee476510(v=vs.110).aspx
- http://blog.techperspect.com/2013/06/send-large-data-with-sharepoint.html