WCF Web API UriTemplate Elements Found in Multiple Methods

Let's say I use the new WCF web API to create a RESTful service, and in my service I have a URI section that will describe the target resource, but (almost) all contract methods are used, For example, if I have a User service that has dealing with e-commerce and might look like this:

[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. } } 

If I have to constantly load the organization and test the null value, this will lead to the loss of my code and not very dry. (So ​​it's tempting to describe DRY ...) What I would like to do is load a property in the MyUserService class that populates when {OrganizationName} is included in the URI and otherwise throws a WebFaultException. Since this is different from a URI, what would be the best way to accomplish this?

EDIT:

For those who might be interested, here is an example of the HttpOperationHandler I came with. Apparently, there is not much information. I also found additional information about Processors that will come with the WCF Web Api package, and it looks like they will handle this kind of better replace HttpOperationHandlers, and it seems they might be easier to use. (This is just for the instance, to cover some things that I find difficult to find. I wrote this a little differently in my application.)

 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; } } 

And then plug it into Global.asax (I use 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); } } 

And here he is in my service:

 [ServiceContract] [ServiceBehavior (InstanceContextMode = InstanceContextMode.PerCall)] public class OrganizationService { [WebGet (UriTemplate = "{OrganizationName}/Products")] public IEnumerable<Product> GetProducts (Organization Organization) { return Organization.Products; } } 
+6
source share
1 answer

This is exactly what OperationHandlers are for. You create one OperationHandler that converts the URI parameter to a strongly typed object, which you can simply accept as a parameter in the operation.

+2
source

Source: https://habr.com/ru/post/888605/


All Articles