ServiceStack:从网址解析请求DTO

时间:2018-04-17 22:38:13

标签: c# servicestack

有没有办法利用或重用内部servicestack url路由到服务解析来获取该URL的匹配请求DTO?

例如,我们有一个服务聚合一个指向不同SS服务的URL字符串列表 - 所有这些服务都生成并返回PDF:

    public class PDFAggregationService : ServiceStack.Service
{
    public BigAssPDFResponse Any(BigAssPDFRequest request)
    {
        var response = new BigAssPDFResponse();


        //does something to fetches list of pdf generating urls
        var pdfRoutes = [
               "https://server1/route1/param/2/thing/1",
               "https://server1/route1/param/3/thing/4",
               "https://server1/route2/param/1",
               "https://server1/route3/param/1"];




        var pdfBytes = new List<object>();
        pdfRoutes.ForEach(url=>
        {

            var requestDto = ???? ;  // how to resolve a DTO from a random URL? 

            var response = Gateway.Send<object>(requestDto);

            pdfBytes.Add(response);

        })


        // does something to aggregate all pdfs into one
        // pdfBytes.ForEach(...) 

        return response;


    }
}

我们希望避免实例化JSONClient来调用URL,因为所有被调用的服务都与 PDFAggreationService 位于同一AppHost中。 (我们也希望使用网关调用,以便我们可以利用我们在各种请求/响应过滤器中实现的一些复杂逻辑。)

1 个答案:

答案 0 :(得分:2)

我添加了一个新的Metadata.CreateRequestFromUrl() API,它包含了样板文件,允许您在this commit(现在available from v5.0.3 on MyGet)中执行此操作,您可以使用它:

var requestDto = HostContext.Metadata.CreateRequestFromUrl(url);
var responseType = HostContext.Metadata.GetResponseTypeByRequest(requestDto.GetType());
var response = Gateway.Send(responseType, requestDto);
  

请注意,您的请求DTO需要IReturn<T>标记接口才能使用服务网关。

这个新的API有效地包装下面的样板文件以获取匹配的RestPath路由定义,然后您可以使用/path/info和其他可以通过网关发送的params字典填充,例如:

var pathInfo = "/route1/param/1";
var queryParams = new Dictionary<string,string> { ... };

var route = RestHandler.FindMatchingRestPath("GET", pathInfo, out _);
var reqType = route.RequestType;
var requestDto = route.CreateRequest(pathInfo, queryParams, reqType.CreateInstance());

var resType = HostContext.Metadata.GetResponseTypeByRequest(route.RequestType);
var response = Gateway.Send(resType, requestDto);