与Rest动词匹配的ServiceStack新API动作

时间:2012-10-06 15:48:15

标签: c# servicestack restful-url

旧版本SomeService : RestServiceBase可以将OnGet OnPost OnPut OnDelete操作与相应的传入动词相匹配。

使用较新的版本,请说我有以下内容:

//-----------------------------------------
[Route("/todos/{id}","GET")] //display request
[Route("/todos/{id}", "POST")] //edit request
public class Todo : IReturn<TodoResponse> {
    public long Id { get; set; }
    public string Content { get; set; }
}

public class TodoService : Service {
    public object Get(Todo request) { ... } // will GET verb know this Get() function?
    public object Post(Todo request) { ... }// will POST verb know this Post() function?
}

动作名称“获取”“发布”不再标记为“覆盖”,SS如何匹配正确的动词来命中Get()和Post()函数?

// --------------------------------------------- -----------------------------

或第2轮,现在我有一个修改......

//-----------------------------------------
[Route("/todos/{id}","GET")] //display request
public class DisplayTodo : IReturn<TodoResponse> {
    public long Id { get; set; }
}
[Route("/todos/{id}", "POST")] //edit request
public class EditTodo : IReturn<TodoResponse> {
    public long Id { get; set; }
    public string Content { get; set; }
}

public class TodoService : Service {
    //different request DTOs this time ...
    public object Get(DisplayTodo request) { ... } //again, same route "/todos/{id}" 
    public object Post(EditTodo request) { ... }   //will SS get confused about the verbs? 
}

在同一路线下“/ todos / {id}”在上述情况下,SS如何区分动词?

请问你能解决两个问题吗?谢谢!

2 个答案:

答案 0 :(得分:4)

ServiceStack将尝试匹配请求VERB及其请求DTO。 如果其中任何一个不匹配,您将收到无请求处理程序消息。

您的示例似乎没问题,您是否遇到过任何问题?

答案 1 :(得分:4)

这是取自New API wiki page智能路由部分:

匹配规则

在大多数情况下,您不需要了解这一点,因为ServiceStack的路由工作正如您所期望的那样。虽然这仍然可以作为描述ServiceStack路由的解析顺序的一个很好的参考:

  1. 首先使用任何确切的文字匹配
  2. 精确动词匹配优先于所有动词
  3. 路线中的变量越多,其权重越小
  4. 当路由具有相同的权重时,顺序由服务中的操作位置或注册顺序(FIFO)决定
  5. 当有多条路由与传入请求的pathInfo匹配时,这些规则才会发挥作用。

    让我们使用新API设计测试套件中定义的路径查看这些规则的一些示例:

    [Route("/reqstars")]
    public class Reqstar {}
    
    [Route("/reqstars", "GET")]
    public class AllReqstars {}
    
    [Route("/reqstars/{Id}", "GET")]
    public class GetReqstar {}
    
    [Route("/reqstars/{Id}/{Field}")]
    public class ViewReqstar {}
    
    [Route("/reqstars/{Id}/delete")]
    public class DeleteReqstar {}
    
    [Route("/reqstars/{Id}", "PATCH")]
    public class UpdateReqstar {}
    
    [Route("/reqstars/reset")]
    public class ResetReqstar {}
    
    [Route("/reqstars/search")]
    [Route("/reqstars/aged/{Age}")]
    public class SearchReqstars {}
    

    这些是这些HTTP请求的结果

    GET   /reqstars           =>    AllReqstars
    POST  /reqstars           =>    Reqstar
    GET   /reqstars/search    =>    SearchReqstars
    GET   /reqstars/reset     =>    ResetReqstar
    PATCH /reqstars/reset     =>    ResetReqstar
    PATCH /reqstars/1         =>    UpdateReqstar
    GET   /reqstars/1         =>    GetReqstar
    GET   /reqstars/1/delete  =>    DeleteReqstar
    GET   /reqstars/1/foo     =>    ViewReqstar
    

    如果有多个完全相同的路线声明如下:

    [Route("/req/{Id}", "GET")]
    public class Req2 {}
    
    [Route("/req/{Id}", "GET")]
    public class Req1 {}
    
    public class MyService : Service {
        public object Get(Req1 request) { ... }     
        public object Get(Req2 request) { ... }     
    }
    

    首先声明的行动路线被选中,即:

    GET /req/1              => Req1