Jim*_*elo 6 rest wcf dry uritemplate wcf-web-api
假设我正在使用新的WCF Web API来构建RESTful服务,并且在我的服务中,我有一段描述目标资源的URI,但用于(几乎)合同的所有方法.例如,如果我有一个处理电子商务的用户服务,可能看起来像:
[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.
}
}
Run Code Online (Sandbox Code Playgroud)
如果我必须不断加载组织并测试null,这将使我的代码陷入困境并且不是很干.(所以很想拼出DRY ......)我想要做的是在MyUserService类中加载一个属性,该类在URI中包含{OrganizationName}时填充,否则抛出WebFaultException.因为这是URI的一部分,实现这一目标的最佳方法是什么?
编辑:
对于那些可能感兴趣的人,这里是我想出的HttpOperationHandler的一个例子.似乎没有很多信息可以涵盖这一点.我还发现了有关将与WCF Web Api套件一起使用的处理器的更多信息,看起来它们将更好地替代HttpOperationHandler 处理这类事情,看起来它们可能更容易使用.(这只是一个例子来涵盖我发现很难找到的一些东西.我在我的应用程序中写了一些不同的东西.)
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;
}
}
Run Code Online (Sandbox Code Playgroud)
然后在Global.asax中连接它(我正在使用Ninject for 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);
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的服务:
[ServiceContract]
[ServiceBehavior (InstanceContextMode = InstanceContextMode.PerCall)]
public class OrganizationService
{
[WebGet (UriTemplate = "{OrganizationName}/Products")]
public IEnumerable<Product> GetProducts (Organization Organization)
{
return Organization.Products;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1345 次 |
| 最近记录: |