如何在自托管 API 上添加此代码
本文关键字:添加 代码 API | 更新日期: 2023-09-27 18:35:16
根据这个问题,当在Windows服务上自行连接Web api时,我无法实现IHttp模块
有没有办法在webApi与HttpSelfHostServer一起运行时添加httpModule?
但是,我仍然需要在自托管的 Web API 中的某个位置添加此代码。我找到了这个关于如何解决这个问题的博客:http://www.silver-it.com/node/182
代码如下,但是我不能在自身托管的API上实现IhttpModule
。public class CORSPreflightModule : IHttpModule
{
private const string OPTIONSMETHOD = "OPTIONS";
private const string ORIGINHEADER = "ORIGIN";
private const string ALLOWEDORIGIN = "https://yourspodomain.sharepoint.com";
void IHttpModule.Dispose()
{
}
void IHttpModule.Init(HttpApplication context)
{
context.PreSendRequestHeaders += (sender, e) =>
{
var response = context.Response;
if (context.Request.Headers[ORIGINHEADER] == ALLOWEDORIGIN)
{
response.Headers.Add("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS");
response.Headers.Add("Access-Control-Allow-Headers", "Content-Type");
}
if (context.Request.HttpMethod.ToUpperInvariant() == OPTIONSMETHOD && context.Request.Headers[ORIGINHEADER] == ALLOWEDORIGIN)
{
response.Headers.Clear();
response.Headers.Add("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS");
response.Headers.Add("Access-Control-Allow-Origin", "https://yourspodomain.sharepoint.com");
response.Headers.Add("Access-Control-Allow-Credentials", "true");
response.Headers.Add("Access-Control-Allow-Headers", "Content-Type");
response.Clear();
response.StatusCode = (int)HttpStatusCode.OK;
}
};
}
}
我的自托管 Web API 如下所示:
程序.cs
static void Main()
{
try
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new APIServiceTest()
};
ServiceBase.Run(ServicesToRun);
}
catch (Exception ex)
{
throw ex;
}
}
class Startup
{
// Hack from https://stackoverflow.com/a/17227764/19020 to load controllers in
// another assembly. Another way to do this is to create a custom assembly resolver
//Type valuesControllerType = typeof(OWINTest.API.ValuesController);
// This code configures Web API. The Startup class is specified as a type
// parameter in the WebApp.Start method.
public void Configuration(IAppBuilder appBuilder)
{
try
{
//Debugger.Launch();
// Configure Web API for self-host.
HttpConfiguration config = new HttpConfiguration();
config.MessageHandlers.Add(new CustomHeaderHandler());
var corsAttr = new EnableCorsAttribute(System.Configuration.ConfigurationManager.AppSettings["DominioSharePoint"].ToString(), "*", "*");
config.EnableCors(corsAttr);
// Enable attribute based routing
// http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
appBuilder.UseWebApi(config);
}
catch (Exception ex)
{
throw ex;
}
}
}
我的控制器:
[EnableCors(origins: "https://xx.sharepoint.com", headers: "*", methods: "*")]
public class CuentasCobroController : ApiController
{
但是,由于它是自托管的,我无法如上所述在那里实现 IHttpModule,但我可以创建自定义处理程序,如何在自定义处理程序中从博客中实现上述代码?
public class CustomHeaderHandler : DelegatingHandler
{
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
{
return base.SendAsync(request, cancellationToken)
.ContinueWith((task) =>
{
HttpResponseMessage response = task.Result;
response.Headers.Add("Access-Control-Allow-Origin", "*");
return response;
});
}
}
问题是,如何将第一个代码集成到我的 Windows 服务的启动中?
通过使用 DelegatingHandler
而不是 IHttpModule
,您几乎就在那里。
config.MessageHandlers.Add(new CorsHeaderHandler());
DelegatingHandler.SendAsync 可以访问请求和响应。
public class CorsHeaderHandler : DelegatingHandler
{
private const string OPTIONSMETHOD = "OPTIONS";
private const string ORIGINHEADER = "ORIGIN";
private const string ALLOWEDORIGIN = "https://yourspodomain.sharepoint.com";
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
{
return base.SendAsync(request, cancellationToken).ContinueWith(task =>
{
var allowedOrigin = request.Headers.Any(t => t.Key == ORIGINHEADER && t.Value.Contains(ALLOWEDORIGIN));
if (allowedOrigin == false) return task.Result;
if (request.Method == HttpMethod.Options)
{
var emptyResponse = new HttpResponseMessage(HttpStatusCode.OK);
emptyResponse.Headers.Add("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS");
emptyResponse.Headers.Add("Access-Control-Allow-Origin", ALLOWEDORIGIN);
emptyResponse.Headers.Add("Access-Control-Allow-Credentials", "true");
emptyResponse.Headers.Add("Access-Control-Allow-Headers", "Content-Type");
return emptyResponse;
}
else
{
task.Result.Headers.Add("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS");
task.Result.Headers.Add("Access-Control-Allow-Headers", "Content-Type");
return task.Result;
}
});
}
}
简单地说,不能将IHttpModule
与自承载的 Web API 或任何非 IIS 一起使用。 IHttpModule
只是一个 IIS 概念。
正如你所发现的,你可以改为修改 Web API 管道,并在其中插入代码(或 Web API 等效项)。这可以通过DelegatingHandler
或动作过滤器来完成。
但是,最简单的解决方案是简单地使用 Microsoft.AspNet.WebApi.Cors
NuGet 包。对于 HttpConfiguration
对象,调用 .EnableCors(...)
并按照此处的说明传入EnableCorsAttribute
对象Microsoft。
这是您在上面的代码中已经完成的操作,但您似乎也在尝试从 HTTP 模块添加自定义 CORS 代码。如果从控制器中删除 EnableCors
属性并删除CustomHeaderHandler
,它应该按预期工作。