ServiceStack在OPTIONS请求返回405(ServiceStack returns 4

2019-07-20 00:10发布

我建立使用ServiceStack一个REST Web服务。 我想允许跨域请求,所以我注册了CorsFeature插件。

我APPHOST如下所示:

public class HomeAppHost : AppHostHttpListenerBase 
{
    public Context Context { get; set; }

    public HomeAppHost(Context context)
        : base("HomeAutomation", typeof(HomeInterfaceService).Assembly)
    {
        Context = context;
    }

    public override void Configure(Funq.Container container)
    {
        Plugins.Add(new CorsFeature());

        Routes
            .Add<HomeInterface>("/HomeInterface")
            .Add<HomeInterface>("/HomeInterface/{Id}")
            .Add<ViewModel>("/ViewModel")
            .Add<FunctionInput>("/Function")
        ;
    }
}

然后,当一个OPTIONS请求的服务进行,这导致405不允许的方法:

请求:

OPTIONS /Function HTTP/1.1
Host: localhost:1337
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:18.0) Gecko/20100101 Firefox/18.0 FirePHP/0.7.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: nl,en-us;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
DNT: 1
Origin: http://localhost
Access-Control-Request-Method: POST
Access-Control-Request-Headers: content-type
x-insight: activate
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache

响应:

HTTP/1.1 405 Method Not Allowed
Content-Length: 1837
Content-Type: application/xml
Server: Microsoft-HTTPAPI/2.0
Date: Fri, 15 Feb 2013 20:19:33 GMT

编辑


添加一个空的选项方法对服务确实防止405被触发。 然而,反应似乎是空的:

HTTP/1.1 200 OK
Transfer-Encoding: chunked
Server: Microsoft-HTTPAPI/2.0
Date: Sat, 16 Feb 2013 08:44:21 GMT

添加以下也给我一个空的回应:

RequestFilters.Add((httpReq, httpRes, requestDto) =>
{
    //Handles Request and closes Responses after emitting global HTTP Headers
    if (httpReq.HttpMethod == "OPTIONS")
        httpRes.End();
});

我不得不改变httpReq.Method到httpReq.HttpMethod和httpRes.EndServiceStackRequest()来httpRes.End()。 它是否正确?

Answer 1:

405在ServiceStack意味着方法尚未实现。

所以,你需要添加的处理程序Options动词。 该方法的主体可以是空的,例如:

public MyService : Service 
{ 
    public void Options(HomeInterface request) {}
}

如果你想允许所有选项请求(即无论它是服务),您可以注册一个全局请求过滤器,如:

this.RequestFilters.Add((httpReq, httpRes, requestDto) => {
   //Handles Request and closes Responses after emitting global HTTP Headers
    if (httpReq.Method == "OPTIONS") 
        httpRes.EndServiceStackRequest();
});

在您可以使用相同的逻辑过滤器的属性 ,如果你想在选项请求是如何处理的更细粒度的控制。



Answer 2:

不知道这是否是正确的道路要走,但我现在使用请求过滤处理CORS自己:

RequestFilters.Add((httpReq, httpRes, requestDto) =>
{
    httpRes.AddHeader("Access-Control-Allow-Origin", "*");

    if (httpReq.HttpMethod == "OPTIONS")
    {
        httpRes.AddHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
        httpRes.AddHeader("Access-Control-Allow-Headers", "X-Requested-With, Content-Type");
        httpRes.End();
    }
});


Answer 3:

我对此行为有点混乱。 没曾想,使假人的选项()上的每个服务的方法和每个DTO类添加假的路线。 所有我需要的 - 那ServiceStack APPHOST responsed对于每一个“选项”的要求,对每一个网址,以相同的行为。 因此,这是我和结束。

创建了自己的处理程序选项:

public class OptionsRequestHandler : IHttpHandler, IServiceStackHttpHandler
{
    public bool IsReusable
    {
        get { return true; }
    }

    public void ProcessRequest(HttpContext context)
    {
        ProcessRequest(null, new HttpResponseWrapper(context.Response), null);          
    }

    public void ProcessRequest(IHttpRequest httpReq, IHttpResponse httpRes, string operationName)
    {
        httpRes.EndServiceStackRequest();
        return;
    }
}

然后在主机配置方法添加它:

this.CatchAllHandlers.Add((httpMethod, pathInfo, filePath) =>
{
    if ("OPTIONS".Equals(httpMethod, System.StringComparison.InvariantCultureIgnoreCase))
        return new OptionsRequestHandler();
    else return null;
});

而肯定没有忘记CorsFeature:

host.Plugins.Add(new ServiceStack.ServiceInterface.Cors.CorsFeature());

于是就这样ServiceStack上与“OPTIONS”头,不管URL,DTO和服务声明每次请求“200 OK”响应。



文章来源: ServiceStack returns 405 on OPTIONS request