【问题标题】:Restful WCF with PUT operation when using JSON (server error 400)使用 JSON 时带有 PUT 操作的 Restful WCF(服务器错误 400)
【发布时间】:2013-11-18 17:13:01
【问题描述】:

已经使用 webHTTPBinding 创建了一个 Restful WCF 服务

在我的客户端应用程序中使用服务时,遇到此错误

远程服务器返回错误:(400) Bad Request。(已经尝试过设置maxReceivedMessageSize等在线解决方案)

场景:

客户端的2个方法

1) 工作正常** GET 请求**

private static void GenerateGETRequest()
{
            HttpWebRequest GETRequest = (HttpWebRequest)WebRequest.Create(url);
            GETRequest.Method = "GET";
            GETRequest.ContentType = "application/json"; 

            Console.WriteLine("Sending GET Request");

            HttpWebResponse GETResponse = (HttpWebResponse)GETRequest.GetResponse();
            Stream GETResponseStream = GETResponse.GetResponseStream();
            StreamReader sr = new StreamReader(GETResponseStream);

            Console.WriteLine("Response from Restful Service");
            Console.WriteLine(sr.ReadToEnd());
}

2) 异常******(PUT 请求和响应)**

private static void GeneratePUTRequest()
{

            byte[] dataByte = CreateJSONObject(Object); //this custom method converts object that I pass to JSON serialized object

            HttpWebRequest PUTRequest = (HttpWebRequest)HttpWebRequest.Create(Url);
            PUTRequest.Method = "PUT";
            **//PUTRequest.ContentType = "application/json"; //error 400 when un-commenting this**
            PUTRequest.ContentLength = dataByte.Length;

            Stream PUTRequestStream = PUTRequest.GetRequestStream();
            PUTRequestStream.Write(dataByte, 0, dataByte.Length);

            **HttpWebResponse PUTResponse = (HttpWebResponse)PUTRequest.GetResponse(); // this is where i get the exception when un-commenting above line**

            Stream PUTResponseStream = PUTResponse.GetResponseStream();
            StreamReader sr = new StreamReader(PUTResponseStream);

            Console.WriteLine("Response from Restful Service");
            Console.WriteLine(sr.ReadToEnd());
}

当我取消注释注释中提到的行(在代码中)时,2 方法会引发异常。注释中也提到了抛出异常的地方(在上面的代码中)。

第二种方法适用于所需的输出(如果我评论提到的行)。

其他资源

[OperationContract]
[WebInvoke(Method = "PUT",
    RequestFormat = WebMessageFormat.Json,
    ResponseFormat = WebMessageFormat.Json,
    BodyStyle = WebMessageBodyStyle.Wrapped,
    UriTemplate = "Controller")]

【问题讨论】:

    标签: wcf put wcf-rest internal-server-error


    【解决方案1】:

    为了通过 POST 或 PUT 发送数据,您需要根据 WCF 服务正确构造数据。这基本上就是您所需要的(只需将您的应用程序的 POST 更改为 PUT)

    1) WCF 服务接口

    [OperationContract]
    [WebInvoke(Method = "POST",
        UriTemplate = "GetData",
        RequestFormat = WebMessageFormat.Xml,
        BodyStyle = WebMessageBodyStyle.Bare)]
    string GetData(DataRequest parameter);
    

    2) WCF 服务实现

    public string GetData(DataRequest parameter)
    {
        //Do stuff
        return "your data here";
    }
    

    3) WCF 服务中的数据协定(在本例中为 DataRequest)

    [DataContract(Namespace = "YourNamespaceHere")]
    public class DataRequest
    {
        [DataMember]
        public string ID{ get; set; }
        [DataMember]
        public string Data{ get; set; }
    }
    

    4) 发送数据的客户端必须正确构造数据! (本例中为 C# 控制台应用程序)

    static void Main(string[] args)
    {
        ASCIIEncoding encoding = new ASCIIEncoding();
        string SampleXml = "<DataRequest xmlns=\"YourNamespaceHere\">" +
                                        "<ID>" +
                                        yourIDVariable +
                                        "</ID>" +
                                        "<Data>" +
                                        yourDataVariable +
                                        "</Data>" +
                                    "</DataRequest>";
    
        string postData = SampleXml.ToString();
        byte[] data = encoding.GetBytes(postData);
    
        string url = "http://localhost:62810/MyService.svc/GetData";
    
        string strResult = string.Empty;
    
        // declare httpwebrequet wrt url defined above
        HttpWebRequest webrequest = (HttpWebRequest)WebRequest.Create(url);
        // set method as post
        webrequest.Method = "POST";
        // set content type
        webrequest.ContentType = "application/xml";
        // set content length
        webrequest.ContentLength = data.Length;
        // get stream data out of webrequest object
        Stream newStream = webrequest.GetRequestStream();
        newStream.Write(data, 0, data.Length);
        newStream.Close();
    
        //Gets the response
        WebResponse response = webrequest.GetResponse();
        //Writes the Response
        Stream responseStream = response.GetResponseStream();
    
        StreamReader sr = new StreamReader(responseStream);
        string s = sr.ReadToEnd();
    
        return s;
    }
    

    【讨论】:

    • 2) 另外,请帮助我理解这一点:(我的请求和响应格式是 JSON)无法找到明确的答案。如果我给出:a) WrappedResponse - 响应将被转换为 JSON 格式并发送 b) Bare (Request) - 请求将从 JSON 反序列化并转换为 DataRequest 对象(如上)(响应) - 响应不会转换为 JSON格式 c)WrappedRequest - ?????请阐明差异,如果我的理解有任何不正确之处。
    • 当我提到数据合约并在 post 方法语法中使用它时,它确实有效。 1) 是否可以在服务中以 Stream 的形式接收数据(而不是提及 DataRequest 对象)?
    • blog.clicdata.com/2012/01/12/understand-webmessagebodystyle 关于 WrappedResponse 的第一个问题
    • codeproject.com/Articles/35982/… 关于作为流发送/接收数据的第二个问题
    • 如果您对这个问题有所了解,请回答stackoverflow.com/questions/20092931/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-23
    • 2013-10-29
    • 2011-03-04
    相关资源
    最近更新 更多