【发布时间】:2012-03-08 05:48:38
【问题描述】:
考虑以下两个 WCF 4.0 REST 服务:
[ServiceContract]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class WorkspaceService
{
[WebInvoke(UriTemplate = "{id}/documents/{name}", Method = "POST")]
public Document CreateWorkspaceDocument(Stream stream, string id, string name)
{
/* CreateDocument is omitted as it isn't relevant to the question */
Document response = CreateDocument(id, name, stream);
/* set the location header */
SetLocationHeader(response.Id);
}
private void SetLocationHeader(string id)
{
Uri uri = new Uri("https://example.com/documents/" + id);
WebOperationContext.Current.OutgoingResponse.SetStatusAsCreated(uri);
}
/* methods to delete, update etc */
}
[ServiceContract]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class DocumentService
{
[WebGet(UriTemplate = "{id}")]
public Document GetDocument(string id)
{
}
/* methods to delete, update etc */
}
本质上,当有人在工作空间中创建文档时,Location 标头设置为文档的位置,这与调用DocumentService.GetDocument 操作基本相同。
我的 global.asax 如下所示:
public class Global : HttpApplication
{
private void Application_Start(object sender, EventArgs e)
{
RegisterRoutes();
}
private void RegisterRoutes()
{
var webServiceHostFactory = new WebServiceHostFactory();
RouteTable.Routes.Add(new ServiceRoute("workspaces", webServiceHostFactory, typeof (WorkspaceService)));
RouteTable.Routes.Add(new ServiceRoute("documents", webServiceHostFactory, typeof (DocumentService)));
/* other services */
}
}
WorkspaceService.SetLocationHeader 的实现,因为它对路由的设置方式做了一些假设。如果我要更改 DocumentService 的路线,那么生成的 Uri 将不正确。如果我更改了DocumentService.GetDocument 的UriTemplate,那么生成的Uri 也会不正确。
如果 WorkspaceService 和 DocumentService 合并为一个服务,我可以写成 SetLocationHeader 如下:
var itemTemplate = WebOperationContext.Current.GetUriTemplate("GetDocument");
var uri = itemTemplate.BindByPosition(WebOperationContext.Current.IncomingRequest.UriTemplateMatch.BaseUri, id);
WebOperationContext.Current.OutgoingResponse.SetStatusAsCreated(uri);
如何编写WorkspaceService.SetLocationHeader 以便它使用在 Global.asax 和 UriTemplates 中定义的路由表来返回用于 DocumentService 的 GetDocument 操作的 Uri?
我使用的是普通的旧 WCF 4.0(不是 WCF Web API)。
【问题讨论】: