ServiceStack:Routes.AddFromAssembly仍然使用/ json / reply路径,并且没有属性的URL-niceness

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (12)

我有一个ServiceStack自托管的Web服务,使用AppSelfHostBase

在执行Configure方法时,我有:

public override void Configure(Container container)
{
    Config.RouteNamingConventions = new List<RouteNamingConventionDelegate> {
        RouteNamingConvention.WithRequestDtoName,
        RouteNamingConvention.WithMatchingAttributes,     
        RouteNamingConvention.WithMatchingPropertyNames,  
    };

    Routes.AddFromAssembly(typeof(ServiceStackHost).Assembly);

我希望以下服务在/StartBankIdAuthentication路径下执行,但它位于/json/reply/StartBankIdAuthentication相反的位置。

public class StartBankIdAuthentication : IReturn<StartBankIdAuthenticationResponse>
{
    public string IdNbr { get; set; }
}

另外,是否有一种自动方式使DTO中的属性位于“子路径”下,/StartBankIdAuthentication/1234而不是/StartBankIdAuthentication?IdNbr=1234

我知道我可以手动添加Route属性,但它看起来很麻烦,而且在很多方面也很混乱(不是Typed,容易出错等)。

提问于
用户回答回答于

我希望在/StartBankIdAuthentication路径下执行以下服务,但它位于其下/json/reply/StartBankIdAuthentication

/json/reply/StartBankIdAuthentication是一个预定义的路由,默认情况下始终可用,它们与自动生成的路由无关。

您列出的默认路由生成策略已默认注册,并且是您使用时应用的策略Routes.AddFromAssembly()。除了默认值之外,您应该仅使用所需的路由策略覆盖,并且应该SetConfig()用于ServiceStack中的任何配置,例如:

SetConfig(new HostConfig {
    RouteNamingConventions = { MyCustomRouteStrategy }
});

ServiceStack中可用的不同路径策略的实现在RouteNamingConvention.cs中,您需要为任何其他路径策略注册自己的策略。

默认情况下,会为任何IdIDs属性生成其他路由,路由文档会显示如何自定义它们的示例

可以通过修改相关的静态属性来进一步自定义现有规则,例如:

RouteNamingConvention.PropertyNamesToMatch.Add("UniqueId");
RouteNamingConvention.AttributeNamesToMatch.Add("DefaultIdAttribute");

这将使这些请求DTO:

class MyRequest1
{
    public UniqueId { get; set;}
}

class MyRequest2
{
    [DefaultId]
    public CustomId { get; set;}
}

生成以下路由:

/myrequest1
/myrequest1/{UniqueId}
/myrequest2
/myrequest2/{CustomId}

我知道我可以手动添加Route属性,但它看起来很麻烦,而且在很多方面也很混乱(不是Typed,容易出错等)。

如果你真的想要你可以使用nameof()Typed Routes:

[Route("/" + nameof(StartBankAuthentication) +"/"+ nameof(StartBankAuthentication.IdNbr))]
用户回答回答于

我不确定Mythz是否会想出一个更好的解决方案,但我设法通过覆盖GetRouteAttributes来实现我想要的,并且通过使用反射,我可以创建我想要的东西。它看起来像这样:

public override RouteAttribute[] GetRouteAttributes(Type requestType)
{
    string fullname = requestType.FullName.Replace("AlfaOnlineServiceModel.Api.", "");
    string path = "/" + fullname.ToLower().Replace(".", "/");

    RouteAttribute[] routes = base.GetRouteAttributes(requestType);
    if (routes.Length == 0)
    {
        routes = new RouteAttribute[1];

        PropertyInfo[] pInfos = requestType.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.DeclaredOnly);
        foreach(PropertyInfo pi in pInfos)
        {
            path += "/{" + pi.Name + "}";
        }

        routes[0] = new RouteAttribute(path);
    }
    return routes;
}

举例来说:

MyMethodResult
The following routes are available for this service:
All Verbs   /myCoolPath/mySubPath/myMethod/{MyProperty}     

扫码关注云+社区

领取腾讯云代金券