我目前这样做的方式是我传回一个实现接口的响应 dto
public interface IHaveLinks
{
[IgnoreDataMember]
IEnumerable<Link> Links { get; }
}
public class Link
{
public string Name { get; set; }
public IReturn Request { get; set; }
public string Method { get; set; }
}
然后我使用响应过滤器生成 url 并使用链接填充响应标头。
this.ResponseFilters.Add((req, res, dto) =>
{
if (!(dto is IHaveLinks))
return;
var links = (dto as IHaveLinks).Links
if(links == null || !links.Any())
return;
var linksText = links
.Select(x => string.Format("<{0}>; rel={1}"), x.Request.ToUrl(x.Method), x.Name));
var linkHeader = string.Join(", ", linksText);
res.AddHeader("Link", linkHeader);
});
这似乎是最干净的方式。上面的Link
对象实际上是说“如果您使用此方法发出此请求,您将取回指定的资源”。唯一影响 BLL 的 HTTP 内容是Method
. 但是你可以摆脱它,只传回 GET url。或者将其映射到一些广义的“操作”?
举个例子:
public class ExampleService : Service
{
public ExamplesResponse Get(ExamplesRequest request)
{
var page = request.Page;
var data = // get data;
return new ExamplesResponse
{
Examples = data,
Links = new []
{
new Link { Name = "next", Request = request.AddPage(1), Method = "GET" },
new Link { Name = "previous", Request = request.AddPage(-1), Method = "GET" },
}
}
}
}
[Route("/examples/{Page}")]
public class ExamplesRequest : IReturn<ExamplesResponse>
{
public int Page { get; set; }
// ...
}
(该AddPage
方法返回请求的克隆并适当地设置 Page 属性。)
希望有帮助。