User Routing in WCF Data Services

I need to create a custom route for a WCF data service that contains a segment that needs to be retrieved for use in filtering data.

Example:

http://mysample.net/mysamplesvc/client123/Users

I need to extract client123 from the route. It looks like the Route class might provide something like this, but I'm not sure how to implement IRouteHandler for the data service.

Is this the right way? Are there any good examples?

TIA!

UPDATE:

I managed to find the solution that I needed using special rewriting of URLs in IDispatchMessageInspector. The code below is my initial hack and requires a bunch of cleanup. but it seems to work. If anyone sees anything inaudible, let me know.

public object AfterReceiveRequest(ref System.ServiceModel.Channels.Message request, IClientChannel channel, InstanceContext instanceContext) { HttpRequestMessageProperty httpmsg = (HttpRequestMessageProperty)request.Properties[HttpRequestMessageProperty.Name]; ...Additional logic for handling Query formats in OData UriTemplate template = new UriTemplate("mysamplesvc/{ClientId}", true); Uri prefix = new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority)); Uri uri = new Uri(HttpContext.Current.Request.Url.AbsoluteUri); UriTemplateMatch results = template.Match(prefix, uri); if (results != null && !string.IsNullOrEmpty(results.BoundVariables["ClientId"])) { _clientId = results.BoundVariables["clientId"].ToString(); } if (!string.IsNullOrEmpty(_clientId)) { httpmsg.Headers.Add("ClientId", _clientId); rewriteRequest(); } return null; } private void rewriteRequest() { if (HttpContext.Current != null && HttpContext.Current.Session != null) { if (WebOperationContext.Current.IncomingRequest.UriTemplateMatch != null) { Uri serviceUri = HttpContext.Current.Session["ServiceUri"] as Uri; Uri requestUri = null; UriTemplateMatch match = WebOperationContext.Current.IncomingRequest.UriTemplateMatch; if (serviceUri == null) { UriBuilder serviceUriBuilder = new UriBuilder(match.BaseUri); serviceUri = serviceUriBuilder.Uri; HttpContext.Current.Session["ServiceUri"] = serviceUri; } if (serviceUri != null) { OperationContext.Current.IncomingMessageProperties["MicrosoftDataServicesRootUri"] = serviceUri; UriBuilder requestUriBuilder = new UriBuilder(match.RequestUri); string path = string.Empty; if (match.RelativePathSegments[0] == _clientId) { foreach (var seg in match.RelativePathSegments.Select((x, i) => new { Value = x, Index = i })) { if (seg.Index != 0) { path += "/"; path += seg.Value; } } } else { foreach (var seg in match.RelativePathSegments.Select((x, i) => new { Value = x, Index = i })) { path += "/"; path += seg.Value; } } UriBuilder serviceUriBuilder = new UriBuilder(match.BaseUri + path); // because we have overwritten the Root URI, we need to make sure the request URI shares the same host // (sometimes we have request URI resolving to a different host, if there are firewall re-directs serviceUriBuilder.Host = serviceUri.Host; requestUri = serviceUriBuilder.Uri; OperationContext.Current.IncomingMessageProperties["MicrosoftDataServicesRequestUri"] = requestUri; OperationContext.Current.IncomingMessageProperties["Via"] = requestUri; } } } } 

Thanks everyone!

+4
source share
2 answers

I assume this is an MVC project

typical routes in MVC, I believe, work as follows:

 //url looks like /controller/Details/42 public ViewResult Details(int id) { //do something } 

You can add custom routes as follows:

 routes.MapRoute( "my special little route", // Route name "customer/{Cid}/programs/{Pid}", new { controller = "customer", action = "Details" } ); 

therefore, the view is as follows:

 //url looks like /customer/{21}/programs/42 public ViewResult Details(int Cid, int Pid) { //do something } 

so that in theory you can do this for your WCF service. If I do not fully understand what you are saying, I will gladly try to update my answer.

0
source

Another option is to use an IncomingWebRequestContext obtained from WebOperationContext . IncomingRequest . This will allow you to directly access the URI. The downside is that you have to deal with Uri.Segments and then add another code tied to the uri format.

You ultimately stem from the fact that WCF, by all accounts, does not support REST. REST must be a set of operations that are performed on a resource identified by a URI. Instead, WCF provides a โ€œstaticโ€ endpoint and a set of methods more similar to the old XML / SOAP than true REST.

I personally found WCF very problematic when working with REST services that act on a URI / resource. Honestly, this is of little value and just interfered. There are many REST architectures, many of them suffer from the same restriction. You might consider using WCF and finding a payload serialization library that supports the formats you want to view.

My current favorite is protobuf-csharp-port , which supports XML, JSON, protocol buffers, and encoded message URIs. There is a brief introduction to creating a REST service using protobuf-csharp-port . Although this example is also a service endpoint, not a resource-based REST, a basic serialization pattern is what you need.

+4
source

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


All Articles