开发者

Getting HTTP Error 400 Calling WCF service via HttpWebRequest

I have a WCF service that I'm able to call via jQuery, but I'm not able to call via HttpWebRequest. I have been able to use the exact same HttpWebRequest settings to call a ASMX service before, but this is my first attempt at calling a WCF service. I've provide the jQuery and the C# HttpWebRequest code so you can hopefully notice something I've done obviously wrong.

This is my broken C# code, the last line is throwing the error 400

string url = "http://www.site.com/Service/Webapi.svc/GetParts";
string parameters = "{part: 'ABCDE'}";
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);

req.Method = "POST";
req.ContentLength = 0;
req.ContentType = "application/json; charset=utf-8";

if (!string.IsNullOrEmpty(parameters))
{
    byte[] byteArray = Encoding.UTF8.GetBytes(parameters);
    req.ContentLength = byteArray.Length;
    Stream dataStream = req.GetRequestStream();
    dataStream.Write(byteArray, 0, byteArray.Length);
    dataStream.Close();
}

HttpWebResponse response = (HttpWebResponse)req.GetResponse();

This is my working jQuery code

 $.ajax({
    url: '/Service/Webapi.svc/GetParts',
    contentType: 'application/json; charset=utf-8',
    dataType: 'json',
    type: 'POST',
    data: JSON.stringify({ part: request.term }),
    success: function (data) {
        // Success
    }
});

Here is my relative web.config settings

  <system.serviceModel>
    <behaviors>
      <endpointBehaviors>
        <behavior name="REST">
          <enableWebScript/>
          <webHttp/>
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior name="">
          开发者_运维技巧<serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
    <services>
      <service name="Webapi">
        <endpoint address="" behaviorConfiguration="REST" binding="webHttpBinding" contract="IWebapi"/>
      </service>
    </services>
  </system.serviceModel>

Here is my service interface, I've tried changing "Method" to "POST" but this did not make a difference.

[ServiceContract]
public interface IWebapi
{
    [OperationContract]
    [WebInvoke(
        Method = "*",
        RequestFormat = WebMessageFormat.Json,
        ResponseFormat = WebMessageFormat.Json,
        BodyStyle = WebMessageBodyStyle.WrappedRequest)
    ]
    string[] GetParts(string part);
}

Here is my service implementation

public string[] GetParts(string part)
{
    return new string[] {"ABC", "BCD", "CDE"};
}


Ok, this was far from obvious earlier but I found the problem....

The root cause of the HTTP Error 400 message was an invalid formatted JSON request. I found an article online talking about receiving error 400 if the content type was wrong (which it wasn't), so I decided tor review all the elements in the HttpWebRequest again. I found that when the JSON request was being sent via jQuery it had the following format.

    // Good JSON Formatting
    {"property":"value"}

but in my code above I was using

    // Bad JSON Formatting
    {property:"value"}

After making this change, everything worked. In order to prevent this for happening again, I found an article from ScottGu about building a ToJSON() extension method using the JavaScriptSerializer. Using this extension method, I came up with the following code/fix.

  1. Created a request object (the property must match the signature of the method I'm calling)

    class Request
    {
        public string part {get; set;}
    }
    
  2. Serialized the object to get the correct JSON formatting

    Request request = new Request() { part = "ABC" };
    request.ToJSON();
    
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜