Abhishek Mathur
Abhishek Mathur

Reputation: 316

Optional query string parameter passing to WCF service

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.

Upvotes: 2

Views: 16628

Answers (4)

Bharati Mathapati
Bharati Mathapati

Reputation: 119

I understand it quite old post but may help someone else.

In Interface : deviceType is not optional below, but Id and limit is optional while invoking endpoint.

        [OperationContract]
        [WebGet(UriTemplate = "newsbycity/{DeviceType}/{id=1}/{limit=10}", ResponseFormat = WebMessageFormat.Json)]
        CityNewsList GetNewsByCity(string DeviceType,string id,string limit);

Service :

CityNewsList GetNewsByCity(string DeviceType,string strid,string strlimit)
{
int ID = id; // perform null check 
}

Upvotes: 0

Jenna Leaf
Jenna Leaf

Reputation: 2472

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

Upvotes: 1

Harri Koppel
Harri Koppel

Reputation: 11

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.

Upvotes: 1

Thorsten Dittmar
Thorsten Dittmar

Reputation: 56727

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.

Upvotes: 2

Related Questions