1

我们遇到了一些 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);
        }
    }
}

我尝试了其他几种提取内容并推送到传出请求的方法,但似乎没有任何效果。在最好的情况下,WebAPI 方法被调用,请求对象的值为空。我现在不知道该去哪里。

4

1 回答 1

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);
    }
}
于 2013-03-05T22:41:39.920 回答