ServiceStack中类似Github的路由

时间:2014-09-13 19:05:22

标签: routes servicestack

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

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)。

我只是想知道是否有一种方法可以定义自定义路由(或编写我自己的路由),这样这种情况就可以了。

1 个答案:

答案 0 :(得分: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,
        };
    }
}
相关问题