使用JSON内容代理HTTP POST

时间:2013-03-05 22:33:20

标签: jquery asp.net-mvc json proxy cors

我们遇到了一些CORS问题,我正在尝试使用服务器代理来解决它,因为这似乎是处理它的最可靠方法。但是我遇到了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);
        }
    }
}

我已经尝试了其他几种提取内容并推送传出请求的方法,似乎没有任何工作。在最好的情况下,使用请求对象的null值调用WebAPI方法。我不知道在这一点上去哪里。

1 个答案:

答案 0 :(得分: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);
    }
}