Optional query string parameter passing to WCF service

15,369

Solution 1

So actually you're using WCF to create a REST service. I've read what you mean in the answer to the question you're creating a possible duplicate of: How to have optional parameters in WCF REST service?

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.

So what that'd come down to is:

Change your method's signature to omit the parameter:

CityNewsList GetNewsByCity(string DeviceType,string id /*,string limit*/);

Change the attributes so that the parameter is not expected on the query string:

[OperationContract]
[WebGet(UriTemplate = "/whatever/{DeviceType}/{id}", RequestFormat = WebMessageFormat.Xml)]

instead of

[OperationContract]
[WebGet(UriTemplate = "/whatever/{DeviceType}/{id}/{limit}", RequestFormat = WebMessageFormat.Xml)]

In the end you'd have something like:

[OperationContract]
[WebGet(UriTemplate = "/whatever/{DeviceType}/{id}", RequestFormat = WebMessageFormat.Xml)]
CityNewsList GetNewsByCity(string DeviceType,string id);

And the implementation's first thing to do would be:

string limit = WebOperationContext.Current.IncomingRequest.UriTemplateMatch.QueryParameters["Limit"];

However: I have not tried that, but that's what I understand from what you've quoted in the comments to your question.

Solution 2

My way of solving that Optional/Default problem is

Interface.cs: (setting your optional parameter to have default {x=y})

[OperationContract]
[WebGet(UriTemplate = "draw/{_objectName}/{_howMany}/{_how=AnyWay}"
, ResponseFormat = WebMessageFormat.Json
)]
YourShape[] doDraw(string _objectName, string _howMany, string _how);

method.svc.cs: (testing x==default?a:x)

YourShape[] doDraw(string _objectName, string _howMany, string _how) {
    if (_how == "AnyWay")
       _how = findTheRightWay();  
    return (drawShapes(_objectName, _howMany, _how));
}

Your endpoint can be either

yoursite/draw/circle/5

or

yoursite/draw/circle/5/ThisWay

Solution 3

One had a similar issue recently and solved it by overriding the default QueryStringConverter.

1) Subclass System.ServiceModel.Dispatcher.QueryStringConverter and override its ConvertStringToValue method.

Example, that makes all enums optional (default value will be used if there is no value)

  public override object ConvertStringToValue(string parameter, Type parameterType)
        {
            if (parameterType.IsEnum)
            {
                if (string.IsNullOrEmpty(parameter))
                {
                    return Activator.CreateInstance(parameterType);
                }
            }

            return base.ConvertStringToValue(parameter, parameterType);

        }

2) Subclass System.ServiceModel.Description.WebHttpBehavior and override its GetQueryStringConverter method to return your modified querystring converter

public class ExtendedQueryStringBehavior : WebHttpBehavior
{
    protected override QueryStringConverter GetQueryStringConverter(OperationDescription operationDescription)
    {
        return new ExtendedQueryStringConverter();
    }
}

3) Hook up the new WebHttpBehavior to the desired endpoint (might need to merge this functionality with other stuff you might have there).

One can support quite complex scenarios with the QS converter, complex types, csv lists, arrays etc.. Everything will be strongly typed and conversion manageable from the single point - no need to deal with parsing nightmare in the service/method level.

Share:
15,369

Related videos on Youtube

Abhishek Mathur
Author by

Abhishek Mathur

Result oriented professional with 12 years of experience in Application & Website Development. Currently working as Technical Lead/Associate Architect for Protiviti Consulting and handling a team of 11 members. Managing all phases of the project life cycle inclusive of scoping, development, integration, deployment, testing, maintenance and production support; ensuring timely completion & delivery of project to the client and extending support for multiple applications.

Updated on June 04, 2022

Comments

  • Abhishek Mathur
    Abhishek Mathur almost 2 years

    i want to know how to use:

    string limit = WebOperationContext.Current.IncomingRequest.UriTemplateMatch.QueryParameters["Limit"];
    

    in my wcf in this method:

    CityNewsList GetNewsByCity(string DeviceType,string id,string limit);
    

    here 'devicetype' and 'id' are default parameter and what i want is 'limit' as optional parameter means user have a choice to pass this parameter he can pass or can not pass this.

    want to use limit as:

    if (limit == some value)
    {
        //do this.
    }
    if (limit == null)
    {
        // do this.
    }
    

    i go through many links but i didn't get that how to use this in my wcf.

    or if someone can tell me how to make a parameter optional in the WCF Service.

    • Abhishek Mathur
      Abhishek Mathur over 11 years
      thats what i am asking that i have read in some links that i can put an optional parameter in the wcf method. stackoverflow.com/questions/4969687/… as in this link but i dnt know i am doing ri8 or not
  • Admin
    Admin over 11 years
    Oh, this applies if one is using WebServiceHost and WebHttpBinding for the endpoint.