I need to create a custom route for a WCF data service that contains a segment that must be extracted for use in filtering data.
Example:
http://mysample.net/mysamplesvc/client123/Users
I need to extract the client123 from the route. It looks like the Route class might provide something similar but I am not sure how to implement an IRouteHandler for a Data service.
Is this the correct path? Are there good examples around?
TIA!
UPDATE:
I have managed to achieve the solution I needed via some custom URL re-writing in the IDispatchMessageInspector. The below code is my initial hack and needs a bunch of clean-up. but, it appears to be working. If anybody sees anything galringly wrong, please 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 all!
I’m assuming this is a MVC project
the typical routes in MVC, I believe, work like this:
You can add custom routes like this:
so the view then looks like:
so you should, in theory, be able to do that to your WCF service. Unless I’m completely misunderstanding what you’re saying at which I will happily try to update my answer