My original Service Contract:
[ServiceContract(
Namespace = "http://my.framework/superservices/myservice",
Name = "IMyServiceContract")]
public interface IMyServiceContract
{
[OperationContract]
[FaultContract(typeof(MyFaultContract))]
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped,
RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json,
UriTemplate = "GetMyItemListJSONMC")]
GetListResponse GetMyItemListJSONMC(GetListRequest request);
// Other methods like this.
}
The request I want to send with POST to my service:
[MessageContract]
public class GetListRequest
{
[MessageBodyMember]
public int NbItems {get;set;}
[MessageBodyMember]
public DateTime? InputDate { get; set; }
[MessageBodyMember]
public string AnotherParameter { get; set; }
[MessageBodyMember]
public MyItem ACoolItem { get; set; }
}
[DataContract(
Namespace="http://my.framework/superservices/myservice/types",
Name="MyItem")]
public class MyItem
{
[DataMember]
public int BirthYear { get; set; }
[DataMember]
public string FirstName { get; set; }
[DataMember]
public string LastName { get; set; }
[DataMember]
public DateTime? BirthFullDate { get; set; }
}
The response I want to get from my service:
[MessageContract]
public class GetListResponse
{
[MessageBodyMember]
public List<MyItem> Result { get; set; }
[MessageBodyMember]
public string ReceivedUsername { get; set; }
[MessageBodyMember]
public string ReceivedPassword { get; set; }
}
Client Code:
private void CallService<TRequest, TResponse>()
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestedUri);
request.Method = "POST";
request.ContentType = "application/json; charset=utf-8";
DataContractJsonSerializer serRequest = new DataContractJsonSerializer(typeof(TRequest));
using (MemoryStream ms = new MemoryStream())
{
serRequest.WriteObject(ms, requestObject);
String json = Encoding.UTF8.GetString(ms.ToArray());
using (StreamWriter writer = new StreamWriter(request.GetRequestStream()))
{
writer.Write(json);
}
}
// Read Response
WebResponse response = request.GetResponse();
using (Stream stream = response.GetResponseStream())
{
if (stream != null)
{
string temp = new StreamReader(stream).ReadToEnd();
return Deserialize<TResponse>(temp);
}
return default(TResponse);
}
}
The original Service Config:
<endpoint address="" binding="webHttpBinding" bindingConfiguration="security"
name="HttpGetUseEndpoint" behaviorConfiguration="JSONBehavior"
contract="ServiceContracts.IMyServiceContract"/>
<endpointBehaviors>
<behavior name="JSONBehavior">
<webHttp faultExceptionEnabled="True"/>
<dataContractSerializer maxItemsInObjectGraph="20000000"/>
</behavior>
</endpointBehaviors>
<behavior name="InternalServiceBehavior">
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceMetadata httpGetEnabled="false"/>
<serviceThrottling maxConcurrentCalls="1500" maxConcurrentSessions="1500" maxConcurrentInstances="1500"/>
<dataContractSerializer maxItemsInObjectGraph="20000000"/>
</behavior>
With this service, I can send JSON Request using POST and handle them in my service implementation like this:
[ServiceBehavior(Name = "MyService",
Namespace = "http://my.framework/advertiserservices/myservice")]
public class MyService : IMyServiceContract
{
public GetListResponse GetMyItemListJSONMC(GetListRequest request)
{
// Do the Job and return the response.
}
}
Now, I want to replace this service implementation by a kind of routing implementation where I could catch all the requests to any service method of my contract. To do this, I adapt the configuration:
<service name="ServiceImplementation.RoutingService"
behaviorConfiguration="InternalServiceBehavior">
<endpoint address="" binding="webHttpBinding" bindingConfiguration="security" name="HttpGetUseEndpoint" behaviorConfiguration="JSONBehavior" contract="ServiceContracts.IRouterService"/>
</service>
I implement my router interface:
[ServiceContract]
public interface IRouterService
{
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped,
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json, UriTemplate = "*")]
Message ProcessMessage(Message message);
}
and the service implementation itself:
public Message ProcessMessage(Message message)
{
UriTemplateMatch uriTemplate = WebOperationContext.Current.IncomingRequest.UriTemplateMatch;
string methodName = uriTemplate.RelativePathSegments.First();
// Routing)
switch (methodName.ToUpper())
{
case "GETMYITEMLISTJSONMC":
// 1st try to retrieve the JSON from Message:
TypedMessageConverter converter = TypedMessageConverter.Create(typeof(GetListRequest), string.Empty, string.Empty);
GetListRequest typedMessage = (GetListRequest)converter.FromMessage(message);
// 2nd Try to retreive JSON from Message
GetListRequest request = message.GetBody<GetListRequest>();
return WebOperationContext.Current.CreateJsonResponse(new GetListResponse());
break;
}
}
Now finally comes my problem and my question:
Running this code and debugging, I am expecting the incoming System.ServiceModel.Channels.Message in input to contain a pure JSON structure but looking with QuickWatch, I see some kind of plain-XML mixed with JSON brackets:
{<root type="object">
<ACoolItem type="object">
<BirthFullDate type="null">
</BirthFullDate>
<BirthYear type="number">1981</BirthYear>
<FirstName type="string">Cool First Name</FirstName>
<LastName type="null">
</LastName>
</ACoolItem>
<AnotherParameter type="string">jsonPost</AnotherParameter>
<InputDate type="string">/Date(1395414903106+0100)/</InputDate>
<NbItems type="number">5</NbItems>
</root>}
This makes that I cannot deserialize the request on service side, because both techniques exposed in the code abover expects JSON.
How can I get the input Message to contain pure JSON instead of this curious mix of JSON and XML?
Thanks for your help.