I am sending a simple json message to a WCF server application.
Json message:
{"Name":"Julian", "Id":123}
Client side code:
public string MakeRequest(string parameters)
{
Console.WriteLine("parameters:" + parameters);
var request = (HttpWebRequest)WebRequest.Create(EndPoint);
request.Method = Method.ToString();
request.ContentLength = 0;
request.ContentType = ContentType;
Console.WriteLine("request: " + request.Headers.ToString());
if (PostData != null && Method == HttpVerb.POST)
{
var encoding = new UTF8Encoding();
var bytes = ObjectToByteArray(PostData);
request.ContentLength = bytes.Length;
Console.WriteLine("Content length: " + request.ContentLength);
using (var writeStream = request.GetRequestStream())
{
writeStream.Write(bytes, 0, bytes.Length);
}
}
try
{
using (var response = (HttpWebResponse)request.GetResponse())
{
var responseValue = string.Empty;
if (response.StatusCode != HttpStatusCode.OK)
{
var message = String.Format("Request failed. Received HTTP {0}", response.StatusCode);
throw new ApplicationException(message);
}
// grab the response
using (var responseStream = response.GetResponseStream())
{
if (responseStream != null)
using (var reader = new StreamReader(responseStream))
{
responseValue = reader.ReadToEnd();
}
}
return responseValue;
}
}
catch (WebException exception)
{
string responseText;
using (var reader = new StreamReader(exception.Response.GetResponseStream()))
{
responseText = reader.ReadToEnd();
return responseText;
}
}
private byte[] ObjectToByteArray(object obj)
{
if (obj == null)
return null;
BinaryFormatter bf = new BinaryFormatter();
using (MemoryStream ms = new MemoryStream())
{
bf.Serialize(ms, obj);
return ms.ToArray();
}
}
Server side code:
[WebInvoke(Method = "POST",
ResponseFormat = WebMessageFormat.Json,
RequestFormat =WebMessageFormat.Json,
UriTemplate = "/postdata")]
public Person PostData(Person data)
{
//Return new person with data inputted from json message
return new Person()
{
Id = data.Id,
Name = data.Name
};
}
Server's Config file
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<services>
<service name="WcfJsonRestService.Service1" behaviorConfiguration="Metadata">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8732/service1"/>
</baseAddresses>
</host>
<endpoint address="http://localhost:8732/service1"
binding="webHttpBinding"
contract="WcfJsonRestService.IService1"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="Metadata">
<serviceMetadata httpGetEnabled="true" policyVersion="Policy15"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior>
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
</configuration>
About the code:
What I've tried:
Current Output:
I get a bad request response from the server with no data.
Update 1:
I must have been getting the data conversion order wrong. Before I:
The first if-statement of the MakeRequest() method (Client side) has been updated with a code segment that makes the request with the json as is. I now get a protocol violation error when write.Flush() executes:
Updated client side code (MakeRequest method)
if (PostData != null && Method == HttpVerb.POST)
{
//var encoding = new UTF8Encoding();
//var bytes = ObjectToByteArray(PostData);
//request.ContentLength = bytes.Length;
//Console.WriteLine("Content length: " + request.ContentLength);
//using (var writeStream = request.GetRequestStream())
//{
// writeStream.Write(bytes, 0, bytes.Length);
//}
using (var streamWriter = new StreamWriter(request.GetRequestStream()))
{
streamWriter.Write(json);
streamWriter.Flush();
streamWriter.Close();
}
var httpResponse = (HttpWebResponse)request.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
}
}
Update 2:
The protocol violation error from the streamWriter.Flush() call was because I hadn't set the request.ContentLenth. I have now set the Content.Length to json.Length and I now get this error:
The image is a bit small but the error message reads:
"System.ArgumentException: Stream was not readable."
I think the problem was in the first lines of the try block. I attempt to read the response from the request object ... ehem ... Although I did try to read the response from the response object further down the damage was already done. I've included the working code below together with the commented out code that was causing the issue. I have marked the offending request.GetResponse() with **** as well as the correct response.GetResponseStream() which you'll be happy to hear, is now free to do its job.
Hope this saves someone a lot of time!
All the relevant parts of the MakeRequest method:
var request = (HttpWebRequest)WebRequest.Create(EndPoint);
request.Method = Method.ToString();
request.ContentLength = 0;
request.ContentType = ContentType;
Console.WriteLine("request: " + request.Headers.ToString());
if (PostData != null && Method == HttpVerb.POST)
{
Console.WriteLine("json length: " + json.Length);
Console.WriteLine(json);
request.ContentLength = json.Length;
var encoding = new UTF8Encoding();
using (var streamWriter = new StreamWriter(request.GetRequestStream()))
{
streamWriter.Write(json);
streamWriter.Flush();
streamWriter.Close();
}
}
try
{
// **** FIRST READ USING request.GetResponse() ****
//var httpResponse = (HttpWebResponse)request.GetResponse();
//using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
//{
// streamReader.ReadToEnd();
//}
using (var response = (HttpWebResponse)request.GetResponse())
{
var responseValue = string.Empty;
if (response.StatusCode != HttpStatusCode.OK)
{
var message = String.Format("Request failed. Received HTTP {0}", response.StatusCode);
throw new ApplicationException(message);
}
// grabs the response
using (var responseStream = response.GetResponseStream())
{
if (responseStream != null)
using (var reader = new StreamReader(responseStream))
{
// **** SECOND READ USING response.GetResponseStream() ****
responseValue = reader.ReadToEnd();
}
}
return responseValue;
}
}