Asp.net web api 放置/删除操作时WebAPI返回404

Asp.net web api 放置/删除操作时WebAPI返回404,asp.net-web-api,Asp.net Web Api,这似乎是一个相当普遍的问题,但我看过的所有文章都没有为我解决这个问题 我正在开发一个ASP.NET WebForms/MVC应用程序,该应用程序在Windows 10(而不是IIS Express)上的IIS上运行,它使用jQuery AJAX在单独的服务器上调用WebAPI应用程序。为了解决CORS问题,并为所有API调用添加额外的处理,我们使用MVC控制器实现了一个服务器端代理,因此每个调用都会以如下方式结束: [HttpPost] public ActionResult Timesheet

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

我正在开发一个ASP.NET WebForms/MVC应用程序,该应用程序在Windows 10(而不是IIS Express)上的IIS上运行,它使用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);
}
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;
    }
}
这一切都非常成功

然而,我们已经厌倦了每次添加新的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;
    }
}
公共类透明Proxy DelegatingHandler:DelegatingHandler
{
私有静态只读Uri BaseUri=新Uri(“https://my.apiserver.com");
受保护的覆盖异步任务SendAsync(HttpRequestMessage请求,CancellationToken CancellationToken)
{
Add(“X-Forwarded-For”,request.GetClientIpAddress());
request.RequestUri=newURI(BaseUri,request.RequestUri.PathAndQuery.Replace(“/Proxy”,string.Empty));
ProcessRequestsModeWay(请求);
var response=wait Client.sendaync(请求,HttpCompletionOption.ResponseHeadersRead,cancellationToken);
返回响应;
}
}
因此,对
POST/Proxy/Timesheets
的请求将转换为对
POST的调用https://my.apiserver.com/Timesheets
,响应返回的内容与原样基本相同


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

结果表明我没有正确注册TransparentProxy DelegatingHandler;我在我的WebApiConfig中这样注册它:

configuration.MessageHandlers.Add(new TransparentProxyDelegatingHandler());
但事实证明(多亏了),我真正想要的是:

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,所以在管道的早期阶段,它没有正确地解析