2013-03-05 101 views
1

我们遇到了一些CORS问题,我试图使用服务器代理来解决它,因为这似乎是最可靠的处理方法。但是我遇到POST请求的主要问题。使用JSON内容代理HTTP POST

代理的一般结构为: JQuery-based client -> WebServer HttpHandler Proxy -> WebAPI Service

客户端使用JSON的有效载荷,并希望他们的回报。

实例客户:

ourcompany.datasource.postData({ 
    data: ko.toJSON(requestObject), 
    success: function (response, status) { ourcompany.messenger.success('Thanks for the data!');}, 
    error: function() { ourcompany.messenger.fail('Oh no!'); } 
} 

我们使用amplify.js为好,这只是增加了围绕jQuery的底层对象的一些包装。为了完整起见,这里的请求,该jquery.ajax其余参数都在的定义:

amplify.request.define('postData', 'ajax', { 
    url: buildProxyUrl(outCompany.urls.svcData), 
    type: 'POST', 
    dataType: 'json', 
    contentType: 'application/json; charset=utf-8', 
    beforeSend: addCustomHeaders, 
    decoder: wrapperDecoder 
}); 

例的WebAPI:

[HttpPost] 
public HttpResponseMessage PostData(PostDataRequest request) 
{ 
     HttpResponseMessage response = null; 
     var response = BusinessLayer.DoSomeStuff(request); 
     return response; 
} 

这一切都在非代理情况正常工作。如您所见,我们通过反序列化WebAPI端的一些JSON来创建一个复杂的.NET对象。

代理正在搞砸这一切。从本质上讲,我无法弄清楚如何在第二个请求中发送原始请求的JSON内容,而不会被传输搞砸。当前的代码看起来是这样的:

private void MakeHttpPostRequest(HttpContext context) 
{ 
    var url = context.Request["url"]; 
    var req = WebRequest.Create(url); 
    req.Method = "POST"; 
    req.Headers["x-customheader"] = context.Request.Headers["x-customheader"]; 

    var reqStream = req.GetRequestStream(); 
    context.Request.InputStream.Position = 0; 
    context.Request.InputStream.CopyTo(reqStream); 
    reqStream.Close(); 
    context.Request.InputStream.Close(); 


    using (var stream = req.GetResponse().GetResponseStream()) 
    { 
     using (var reader = new StreamReader(stream)) 
     { 
      var content = reader.ReadToEnd(); 
      context.Response.ContentType = "application/json"; 
      context.Response.Write(content); 
     } 
    } 
} 

我试图提取内容和推到呼出的请求的其他一些手段,似乎没有任何工作。在最好的情况下,WebAPI方法被请求对象的空值调用。我不知道现在该去哪里。

回答

1

您忘记在代理中设置请求Content-Type标头。你也忘了妥善处理你所有的IDisposable资源:

private void MakeHttpPostRequest(HttpContext context) 
{ 
    var url = context.Request["url"]; 
    var req = (HttpWebRequest)WebRequest.Create(url); 
    req.Method = context.Request.HttpMethod; 
    req.ContentType = context.Request.ContentType; 
    req.Headers["x-customheader"] = context.Request.Headers["x-customheader"]; 

    using (var reqStream = req.GetRequestStream()) 
    { 
     context.Request.InputStream.Position = 0; 
     context.Request.InputStream.CopyTo(reqStream); 
    } 

    using (var response = (HttpWebResponse)req.GetResponse()) 
    using (var stream = response.GetResponseStream()) 
    { 
     context.Response.ContentType = response.ContentType; 
     stream.CopyTo(context.Response.OutputStream); 
    } 
} 
+0

哇,是的,它只是ContentType。而且,这是处理整个过程的更简洁的方式,做得非常好。我希望我能给你两个+1,但希望别人能提供这个! – CodexArcanum 2013-03-05 22:55:13