【问题标题】:WebAPI return 404 on PUT/DELETE operationsWebAPI 在 PUT/DELETE 操作上返回 404
【发布时间】:2018-09-25 13:19:15
【问题描述】:

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

我正在开发一个在 Windows 10 上的 IIS 上运行的 ASP.NET WebForms/MVC 应用程序(所以不是 IIS Express),它使用 jQuery AJAX 在单独的服务器上调用 WebAPI 应用程序。为了解决 CORS 问题,并为所有 API 调用添加额外的处理,我们使用 MVC 控制器实现了一个服务器端代理,因此每个调用最终都会像这样结束:

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

这一切都非常成功。

但是,我们已经厌倦了每次添加新的 API 端点时都必须实现新的服务器端代理方法,因此我们决定使用 WebAPI 创建一个透明的服务器端代理,并让它真正发挥作用工作。

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

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 的请求将被转换为对POST https://my.apiserver.com/Timesheets 的调用,并且返回的响应几乎是原样。

我遇到的问题是使用 PUT 和 DELETE 动词的调用被我的 UI 拒绝为 404 Not Found(不是 API,我仍然可以使用例如 Fiddler/Postman 直接调用它);原始代理使用了这些动词,所以并不是没有配置它们,只是在我调用委托处理程序时。处理程序永远不会被调用,因此路由引擎中发生了一些事情导致 MVC PUT/DELETE 请求工作,但 WebAPI PUT/DELETE 请求失败。

【问题讨论】:

    标签: asp.net-web-api


    【解决方案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,所以它在管道的早期阶段没有以某种方式正确解决。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-20
      • 2021-03-12
      • 2017-02-22
      • 2013-09-27
      • 1970-01-01
      相关资源
      最近更新 更多