我如何更改ServiceStack响应DTO

时间:2013-01-30 20:24:33

标签: servicestack

我正在开发一个API,我希望能够根据客户端的参数自定义响应结构。响应过滤器似乎是一个很好的地方,以避免在每个服务或操作中这样做。问题是,虽然我可以访问操作返回的响应DTO,并且可以更改其属性,但我无法找到完全替换对象的方式或位置。

天真地替换响应过滤器中的对象不起作用,但这有助于说明我正在尝试做的事情:

public class ChangeResponseAttribute : ResponseFilterAttribute
{
    public override void Execute(IHttpRequest req, IHttpResponse res, object responseDto)
    {
        var overrideText = req.QueryString["override"];
        if (!String.IsNullOrEmpty(overrideText))
            responseDto = new { Message = overrideText };
    }
}

[ChangeResponse]
public class TodosService : Service
{
    public object Get(Todos request)
    {
        return new object[0];
    }
}

看起来另一种选择是直接编写自定义响应&结束请求,但这会绕过ServiceStack要做的任何其他处理。

有没有比响应过滤器更好的地方?或者我是否需要咬紧牙关并在每个动作中返回最佳DTO?

1 个答案:

答案 0 :(得分:4)

您无法在过滤器中更改Response DTO,但是有一个选项是在过滤器本身中写入响应(see this answer以获取如何执行此操作的示例)。

另一个选项是使用ServiceRunner并覆盖OnAfterExecute()自定义挂钩,它允许您修改返回的响应,例如:

public class MyServiceRunner<T> : ServiceRunner<T> 
{
    public override object OnAfterExecute(
        IRequestContext requestContext, object response) 
    {
        // Called just after any Action is executed
        var overrideText = req.Get<IHttpRequest>().QueryString["override"];
        return !string.IsNullOrEmpty(overrideText) 
            ? new { Message = overrideText } : null;
    }
}

要让ServiceStack使用它,您需要覆盖AppHost中的CreateServiceRunner方法,例如:

public override IServiceRunner<TRequest> CreateServiceRunner<TRequest>(
    ActionContext actionContext)
{           
    return new MyServiceRunner<TRequest>(this, actionContext); 
}