为什么使用 HttpWebResponse 时会收到错误请求(代码 400)?

Why do I get a bad request (code 400) with HttpWebReponse?

我正在向 WCF 服务器应用程序发送一条简单的 json 消息。

Json 留言:

{"Name":"Julian", "Id":123}

客户端代码:

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();
         }
}

服务器端代码:

 [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
        };
    }

服务器配置文件

    <?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>

关于代码:

http://www.codeproject.com/Articles/167159/How-to-create-a-JSON-WCF-RESTful-Service-in-sec?fid=1614381&fr=1&df=90&mpp=25&prof=False&sort=Position&view=Normal&spc=Relaxed#xx0xx

我试过的:

当前输出:

我从服务器收到错误的请求响应,没有数据。

更新一:

我一定是弄错了数据转换顺序。在我之前:

MakeRequest() 方法(客户端)的第一个 if 语句已更新为使用 json 原样 发出请求的代码段.我现在在 write.Flush() 执行时收到协议违规错误:

更新客户端代码(MakeRequest 方法)

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();
        }

    }  

更新二:

streamWriter.Flush() 调用的协议违反错误是因为我没有设置 request.ContentLenth。我现在已将 Content.Length 设置为 json.Length,现在出现此错误:

图片有点小,但错误信息是:

"System.ArgumentException: Stream was not readable."

当你读到一个流的末尾时,你必须从头开始寻找它。

你可以试试这个:

StreamReader sr = new StreamReader(stream);
sr.ReadToEnd();
stream.Seek(0, SeekOrigin.Begin); 
sr.ReadToEnd(); // This should work now

我认为问题出在 try 块的第一行。我尝试读取来自 请求对象 的响应 ... 嗯 ... 尽管我确实尝试进一步读取来自 响应对象 的响应下来损坏已经完成。我在下面包含了工作代码以及导致问题的注释掉的代码。我已经用 **** 标记了有问题的 request.GetResponse() 以及您会很高兴听到的正确 response.GetResponseStream(),现在可以自由地完成它的工作了。

希望这可以节省很多人的时间!

MakeRequest方法的所有相关部分:

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;
            }
        }