2014-09-13 35 views
2

是否可以在ServiceStack中定义类似Github的路线?我想定义一个REST API,如:ServiceStack中类似Github的路线

home     /
account home   /{account} 
project detail   /{account}/{project} 
project issues index /{account}/{project}/issues 
project issues detail /{account}/{project}/issues/1 

我曾尝试:

[Route("/{Account}"] 
public class GetAccount : IReturn<AccountDto> { 
    public string Account { get; set; } 
} 

[Route("/{Account}/{Project}"] 
public class GetProject : IReturn<ProjectDto> { 
    public string Account { get; set; } 
    public string Project { get; set; } 
} 

// DTOs for issues, etc... 

以上的DTO抛出此NotSupportedException异常在启动时:

RestPath '/{Account}' on Type 'GetAccount' is not Valid 

似乎很清楚,ServiceStack 4不应该支持这个用例(因此NotSupportedException)。

我只是想知道是否有一种方法可以定义自定义路由(或写我自己的路由),所以这种情况下将工作。

回答

3

只有像/{Account}这样的特殊FallbackRoute can handle routes from the root path和它匹配根路径中的任何字符串只能定义一个[FallbackRoute]

不包含字面文本以便能够匹配的路由,例如/{Account}/{Project}也是无效的。你可以做的反而是有所有匹配的路由和重新路由请求匹配基于路径信息多少分量的后退服务,例如:

[FallbackRoute("/{Path*}")] //matches all unmatched routes 
public class RootPathRoutes 
{ 
    public string Path { get; set; } 
} 

public class GetAccount : IReturn<Account> 
{ 
    public string Account { get; set; } 
} 

public class GetProject : IReturn<Project> 
{ 
    public string Account { get; set; } 
    public string Project { get; set; } 
} 

public class Account 
{ 
    public string Name { get; set; } 
} 

public class Project 
{ 
    public string Account { get; set; } 
    public string Name { get; set; } 
} 

然后在你的后备服务,您可以使用组件在路径信息中调用所需的服务,例如:

public class GitHubServices : Service 
{ 
    public object Any(RootPathRoutes request) 
    { 
     if (request.Path != null) 
     { 
      var parts = request.Path.Split('/'); 
      if (parts.Length == 1) 
       return Any(new GetAccount { Account = parts[0] }); 
      if (parts.Length == 2) 
       return Any(new GetProject { Account = parts[0], Project = parts[1] }); 
     } 

     return request; //passed to default page i.e. default.cshtml 
     //return HttpResult.Redirect("/metadata"); //e.g. of redirect response 
    } 

    public object Any(GetAccount request) 
    { 
     return new Account { Name = request.Account }; 
    } 

    public object Any(GetProject request) 
    { 
     return new Project { 
      Account = request.Account, 
      Name = request.Project, 
     }; 
    } 
} 
+1

优秀。对于我的最终体系结构,我决定为我的所有DTO(帐户:/ a/{Id}/{NameSlug},项目:/ p/{Id}/{NameSlug})和我的Web客户端的备用路由上面的URL方案(/ {account}/{project})。目前效果很好! – 2014-09-25 18:36:38