Optional query string parameters in URITemplate in WCF?
Asked Answered
K

5

45

I'm developing some RESTful services in WCF 4.0. I've got a method as below:

[OperationContract]
    [WebGet(UriTemplate = "Test?format=XML&records={records}", ResponseFormat=WebMessageFormat.Xml)]
    public string TestXml(string records)
    {
        return "Hello XML";
    }

So if i navigate my browser to http://localhost:8000/Service/Test?format=XML&records=10, then everything works as exepcted.

HOWEVER, i want to be able to navigate to http://localhost:8000/Service/Test?format=XML and leave off the "&records=10" portion of the URL. But now, I get a service error since the URI doesn't match the expected URI template.

So how do I implement defaults for some of my query string parameters? I want to default the "records" to 10 for instance if that part is left off the query string.

Kemberlykemble answered 3/6, 2010 at 19:47 Comment(0)
M
54

Note: This question is out of date, please see the other answers.


This does not appear to be supported.

However, Microsoft has been made aware of this issue and there is a work-around:

You can get the desired effect by omitting the Query string from the UriTemplate on your WebGet or WebInvoke attribute, and using WebOperationContext.Current.IncomingRequest.UriTemplateMatch.QueryParameters from within your handlers to inspect, set defaults, etc. on the query parameters.

https://connect.microsoft.com/VisualStudio/feedback/details/451296/

Mouthy answered 5/6, 2010 at 17:0 Comment(2)
So that appears to work well. However, if I try to run the unit test against this, it no longer works since a unit test doesn't have a WebOperationContext. I looked up a few examples, but does anyone have a simple example of how to mock the WebOperationContext?Kemberlykemble
Try Googling "mock WebOperationContext". There are lot's of different ideas on how to do this.Mouthy
D
17

According to this answer this is fixed in .NET 4.0. Failing to supply the query string parameter seems to result in its being given the default value for the type.

Decibel answered 11/7, 2012 at 12:58 Comment(0)
B
4

Check this blog post out. Makes sense to me, and comes with a class to parse out the query string parameters.

http://blogs.msdn.com/b/rjacobs/archive/2009/02/10/ambiguous-uritemplates-query-parameters-and-integration-testing.aspx

Basically don't define the query string parameters in the UriTemplate so it matches with/without the parameters, and use the sample class to retrieve them if they're there in the method implementation.

Barram answered 30/9, 2010 at 14:23 Comment(0)
S
2

This seems to work in WCF 4.0.
Just make sure to set your default value in your "Service1.svc.cs"

public string TestXml(string records)
{
  if (records == null)
      records = "10";

  //... rest of the code
}
Swordcraft answered 30/4, 2013 at 10:8 Comment(0)
T
0

While this is an old question, we still come to this scenario from time to time in recent projects.

To send optional query parameters, I created WCF Web Extensions nuget package.

After installation, you can use the package like this:

using (var factory = new WebChannelFactory<IQueryParametersTestService>(new WebHttpBinding()))
{
    factory.Endpoint.Address = new EndpointAddress(ServiceUri);
    factory.Endpoint.EndpointBehaviors.Add(new QueryParametersServiceBehavior());
    using (var client = factory.CreateWebChannel())
    {
        client.AddQueryParameter("format", "xml");
        client.AddQueryParameter("version", "2");
        var result = client.Channel.GetReport();
    }
}

Server side you can retrieve the parameters using WebOperationContext:

WebOperationContext.Current.IncomingRequest.UriTemplateMatch.QueryParameters;
Trabue answered 13/11, 2018 at 19:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.