1

I need a way to configure my contract (method) to take a variable number of parameters. Because you should be able to pass 2 or 10 parameters to this end point.

Btw, the reason I return a Stream is because I serialize my data to XML manually (not important).

ServiceInterface:

[OperationContract]
Stream UpdateAgent(string token, string agentId, string newAgentName, string param1);

Service implementation:

[WebGet(UriTemplate = "/update_agent/{token}/{agentId}/{newAgentName}/{param1}")]
public Stream UpdateAgent(string token, string agentId, string newAgentName, string param1)
    {
        //do stuff here
    }

This method is only available with this URI request:

/update_agent/<long number of chars and numbers>/123456/John Silver/<some ID of associated data>

But I want to be able to pass more params of strings, if I want to. I know that alters the end point of the contract - but is this possible?

To clarify, the following should trigger the same endpoint:

/update_agent/<long number of chars and numbers>/123456/John Silver/dom_81/pos_23

/update_agent/<long number of chars and numbers>/123456/John Silver/dom_120/dat_12/pos_10

/update_agent/<long number of chars and numbers>/123456/John Silver/con_76

Can anyone help me - because clearly I can't make 10,000 methods taking care of each extra parameter...

KristianB
  • 1,403
  • 3
  • 25
  • 46

3 Answers3

1

You can do a template like so:

/update_agent/{token}/{agentId}/{newAgentName}/{*params}

to put the rest of the path into the params variable, and then parse each param out for yourself inside the method.

Rostyslav Dzinko
  • 39,424
  • 5
  • 49
  • 62
metaforge
  • 911
  • 10
  • 11
1

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/ViewFeedback.aspx?FeedbackID=451296&wa=wsignin1.0

From SO : Optional query string parameters in URITemplate in WCF?

Community
  • 1
  • 1
Amar Palsapure
  • 9,590
  • 1
  • 27
  • 46
  • Thanks for the answer. I have read about it, tried a few things out, and looked at the `WebOperationContext` to see what I can do with this. Although I'm not interested in optional query parameters - I need my operation to be triggered no matter how many parameters I fire at it... – KristianB Feb 08 '12 at 09:23
1

I have solved my own problem, by doing the following:

  • Installing URL Rewrite 2.0 (link)
  • Configured a rewrite rule through my Web.config file:

Web.config section: configuration/system.webServer/

<rules>
    <rule name="UpdateAgentUrlRewrite" stopProcessing="true">
        <match url="^service/update_agent/([^/]+)/(agent_\d+)/([^/]+)/(.*)$" />
        <action type="Rewrite" url="Service.svc/update_agent/{R:1}/{R:2}/{R:3}?input={R:4}" appendQueryString="false" logRewrittenUrl="true" />
    </rule>
</rules>

This regex, I made, will transform an URL like this:

/service/update_agent/123a456b789c012d/agent_1/New Agent Name/d_1/e_2/f_3/g_4

||

/Service/update_agent/123a456b789c012d/agent_1/New%20Agent%20Name?input=d_1/e_2/f_3/g_4

Which means I can hit the same Service Endpoint no matter how much I append in the URL, and then just extract the query parameters with this code:

var context = WebOperationContext.Current;
if(context != null)
{
    NameValueCollection queryParams = context.IncomingRequest.UriTemplateMatch.QueryParameters;
    //contains a keyvalue pair:
    // {
    //  key = "input";
    //  value = "e_2/f_3/g_4";
    // }
}
KristianB
  • 1,403
  • 3
  • 25
  • 46