WebAPI在PUT / DELETE操作上返回404

时间:2018-09-24 01:43:01

标签: asp.net-web-api

这似乎是一个相当普遍的问题,但是我看过的SO文章都没有为我解决这个问题。

我正在Windows 10(而不是IIS Express)的IIS上运行的ASP.NET WebForms / MVC应用程序上工作,该应用程序使用jQuery AJAX在单独的服务器上调用WebAPI应用程序。为了解决CORS问题,并向所有API调用添加其他处理,我们使用MVC控制器实现了服务器端代理,因此每个调用最终都将如下所示:

strip()

这一切都非常成功。

但是,每次添加新的API端点时,我们都不得不实施新的服务器端代理方法,这让我们非常烦恼,因此我们决定使用WebAPI创建透明的服务器端代理,并真正做到了工作。

透明的服务器端代理是这样实现的:

[HttpPost]
public ActionResult Timesheets_Submit(Timesheet data)
{
    var processedData = ProcessTheRequestInSomeWay(data);
    var client = new SdkClient();
    var results = client.Timesheets.Post(processedData);
    return Json(results);
}

因此,对public class TransparentProxyDelegatingHandler : DelegatingHandler { private static readonly Uri BaseUri = new Uri("https://my.apiserver.com"); protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { request.Headers.Add("X-Forwarded-For", request.GetClientIpAddress()); request.RequestUri = new Uri(BaseUri, request.RequestUri.PathAndQuery.Replace("/Proxy", string.Empty)); ProcessRequestInSomeWay(request); var response = await Client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken); return response; } } 的请求将转换为对POST /Proxy/Timesheets的调用,并且响应几乎按原样返回。

我遇到的问题是,使用PUT和DELETE动词的调用被我的UI拒绝为POST https://my.apiserver.com/Timesheets(不是API,我仍然可以使用Fiddler / Postman直接调用它);原始代理使用了这些动词,所以这与尚未配置它们不一样,只是在我调用委派处理程序时。该处理程序永远不会被调用,因此路由引擎中发生了一些事情,导致MVC PUT / DELETE请求正常工作,但是WebAPI PUT / DELETE请求失败。

1 个答案:

答案 0 :(得分:1)

事实证明我没有正确注册TransparentProxyDelegatingHandler;我正在WebApiConfig中这样注册它:

configuration.MessageHandlers.Add(new TransparentProxyDelegatingHandler());

但是事实证明(由于https://blog.kloud.com.au/2013/11/24/do-it-yourself-web-api-proxy/),我真正想要的是:

configuration.Routes.MapHttpRoute(name: "proxy", routeTemplate: "proxy/{*path}",
                handler: HttpClientFactory.CreatePipeline(
                    innerHandler: new HttpClientHandler(),
                    handlers: new DelegatingHandler[]
                    {
                        new TransparentProxyDelegatingHandler(), 
                    }),
                defaults: new { path = RouteParameter.Optional }, 
                constraints: null);

我猜想这是因为我没有将任何实际的ApiController实现连接到WebApi,所以在管道的早期阶段并没有以某种方式正确解决。

>