2013-02-15 47 views
3

我正在使用ServiceStack構建REST Web服務。我想允許跨域請求,所以我註冊了CorsFeature插件。ServiceStack在選項請求上返回405

我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()。它是否正確?

回答

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(); 
    } 
}); 
+0

任何想法VB.net版本如何? – Iladarsda 2013-07-19 12:34:56

+0

嘗試http://converter.telerik.com/ – sroes 2013-07-21 17:28:12

2

in ServiceStack意味着該方法尚未實施。

因此,您需要爲Options動詞添加處理程序。該方法的主體可以是空的,如:

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

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

如果你想允許所有選項請求(即無論哪個服務的是),你可以像註冊一個全局請求過濾器

如果您想更好地控制Option請求的處理方式,您可以在Filter Attributes中使用相同的邏輯。

+0

CorsFilter應該處理CORS對OPTIONS的使用。所以我不確定你的答案是否真的回答了這個問題。 – bmargulies 2013-02-15 21:49:57

+0

[EnableCors屬性](https://github.com/ServiceStack/ServiceStack/blob/master/src/ServiceStack.ServiceInterface/Cors/EnableCorsAttribute.cs)只會發出指定的CORS標頭。它不處理隱式處理** Options **或任何其他HTTP動詞。 – mythz 2013-02-15 23:15:48

+0

謝謝,但這並不適合我。看我的編輯。 – sroes 2013-02-16 08:50:24

2

我對此行爲有點混亂。不想在每個服務上製作虛擬的Options()方法,並在每個Dto類上添加虛假的路線。 所有我需要的 - 即ServiceStack AppHost響應每個'選項'請求,在每個網址上,具有相同的行爲。 所以這就是我所結束的。

創建了自己的處理程序選項:

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()); 

所以這無論url,dto和servi如何,使用「OPTIONS」標題的每個請求都使用雙向ServiceStack以「200 OK」響應ce聲明。

+0

我試過你的方法,現在,而不是404,我得到一個500,因爲「拋出新的System.NotImplementedException()」。你不明白嗎? – Dema 2013-09-24 21:12:37

+0

沒有。看起來像你遇到了條件,這個過濾器被原始IHttpHandler路由而不是IServiceStackHttpHandler調用。也許在某處內部或其他地方,只需將第一個ProcessRequest()方法內容更改爲[此處](https://github.com/ServiceStack/ServiceStack/blob/master/src/ServiceStack/ServiceStackHttpHandler.cs) – justmara 2013-09-30 08:36:48

+0

@Dema修改ProcessRequest(HttpContext上下文)'方法的內容 - 而不是引發異常,添加:'ProcessRequest(null,new HttpResponseWrapper(context.Response),null);' – eXavier 2013-10-31 15:17:41

相關問題