假設我正在使用新的WCF Web API來構建RESTful服務,並且在我的服務中,我有一部分URI將描述目標資源,但是用於(幾乎)合同的所有方法。舉例來說,如果我有一個用戶服務與電子商務交易,並可能看起來像:WCF Web API在多種方法中找到的UriTemplate元素
[ServiceContract]
public class MyUserService
{
private MyUserRepository _UserRepo;
private MyOrganizationRepository _OrgRepo;
[WebGet (UriTemplate = "{OrganizationName}/Users")]
public IEnumerable<User> GetUsers (string OrganizationName)
{
IEnumerable<User> Users = null;
var Organization = _OrgRepo.GetOrgByName (OrganizationName);
if (Organization != null)
{
Users = Organization.GetUsers();
}
else
{
throw new WebFaultException<string> ("Organization not found.", HttpStatusCode.NotFound);
}
return Users;
}
[WebInvoke (UriTemplate = "{OrganizationName}/Users", /*yada...yada...yada*/)]
public User AddNewUser (string OrganizationName, User User)
{
// Find the organization, like above, and throw if null.
}
}
如果我要不斷地加載的組織和測試空,這樣會拖垮我的代碼,是不是很乾燥。 (很想拼出DRY ...)我想要做的是在MyUserService類中加載一個屬性,該屬性在{OrganizationName}包含在URI中時填充,否則將引發WebFaultException。因爲這是URI的一部分,那麼完成此操作的最佳方法是什麼?
編輯:
對於那些可能有興趣,這裏是我想出了HttpOperationHandler的例子。這裏似乎並沒有太多的信息。我還發現有關Processors的更多信息,
將與WCF Web Api套件一起提供,看起來他們將更好地處理這種事情
替換HttpOperationHandlers,看起來它們可能更易於使用。 (這只是一個爲實例來介紹一些東西,我發現很難找到的。我在我的應用程序不同的寫了一下。)
using Microsoft.ApplicationServer.Http.Dispatcher; // For HttpOperationHandler
using Microsoft.ApplicationServer.Http.Description; // For HttpOperationHandlerFactory
public class OrganizationHandler : HttpOperationHandler<string, Organization>
{
private Repository<Organization> _OrganizationRepository;
public OrganizationHandler (UnitOfWork Work)
: base ("OrganizationName")
{
_OrganizationRepository = Work.Organizations;
}
public override Organization OnHandle (string OrganizationName)
{
var Result = _OrganizationRepository
.Get (O => O.UrlSafeName.Equals (OrganizationName,
StringComparison.InvariantCultureIgnoreCase));
if (Result == null)
{
throw new WebFaultException<string> ("Organization not found.");
}
return Result;
}
}
public class OrganizationHandlerFactory : HttpOperationHandlerFactory
{
private UnitOfWork _Work;
public OrganizationHandlerFactory (UnitOfWork Work)
{
_Work = Work;
}
protected override Collection<HttpOperationHandler> OnCreateRequestHandlers
(ServiceEndpoint endpoint, HttpOperationDescription operation)
{
var Collection = base.OnCreateRequestHandlers (endpoint, operation);
if (operation.InputParameters.Any (IP => IP.Type.Equals (typeof (Organization))))
{
var Binding = endpoint.Binding as HttpBinding;
if (Binding != null)
{
Collection.Add (new OrganizationHandler (_Work));
}
}
return Collection;
}
}
然後在Global.asax中連線起來(我使用Ninject爲IOC):
// Add this reference to get the MapServiceRoute<T> extension
using Microsoft.ApplicationServer.Http.Activation;
public class Global : HttpApplication
{
protected void Application_Start (object sender, EventArgs e)
{
var Kernel = BuildKernel();
var Config = HttpHostConfiguration.Create()
.SetOperationHandlerFactory
(Kernel.Get (typeof (OrganizationHandlerFactory)) as OrganizationHandlerFactory)
.SetResourceFactory (new NinjectResourceFactory (Kernel));
RouteTable.Routes.MapServiceRoute<OrganizationService> ("Organizations", Config);
}
protected IKernel BuildKernel()
{
IKernel Kernel = new Ninject.StandardKernel();
// Load up the Kernel
return Kernel;
}
}
public class NinjectResourceFactory : IResourceFactory
{
private readonly IKernel _Kernel;
public NinjectResourceFactory (IKernel Kernel)
{
_Kernel = Kernel;
}
public object GetInstance (Type serviceType, InstanceContext instanceContext, HttpRequestMessage request)
{
return Resolve (serviceType);
}
public void ReleaseInstance (InstanceContext instanceContext, object service)
{
throw new NotImplementedException();
}
private object Resolve (Type type)
{
return _Kernel.Get (type);
}
}
這裏,它是我的服務:
[ServiceContract]
[ServiceBehavior (InstanceContextMode = InstanceContextMode.PerCall)]
public class OrganizationService
{
[WebGet (UriTemplate = "{OrganizationName}/Products")]
public IEnumerable<Product> GetProducts (Organization Organization)
{
return Organization.Products;
}
}
處理器只是HttpOperationHandler的舊名稱 – 2011-05-21 00:56:55
@Darrel Miller - 謝謝!我試圖跟上所有的變化,缺乏可以與其他「WCF REST」鏈接混合的信息(可以理解),這使得它變得非常困難。感謝您抓住這個! – 2011-05-21 00:59:00
OperationHandler幹得不錯! – 2011-05-21 00:59:09