-1

I need to make a query with a string, variable long and can have several simultaneous queries: String:

http://localhost:39051/api/values​​/punto1?name=125.25
http://localhost:39051/api/values/punto1?name=125.25&name1=1&name2=23.98
http://localhost:39051/api/values/punto1?name=125.25&name1=1&name2=23.98&name3=12.5
http://localhost:39051/api/values/punto1?name=125.25&name1=1&name2=23.98&name3=12.5&name6=34&name23=3

I have this configuration in webApiConfig.cs

config.Routes.MapHttpRoute(    
  name: "name",
  routeTemplate: "api/{controller}/{id}/{name}/{name1}/{name2}",
  defaults: new { id = RouteParameter.Optional, action =    "GetProductsByName", name =   string.Empty, name1 = string.Empty, name2 = string.Empty });

And I call GetProductsByName (....), which is in ValuesController.cs, where is the GET, POST, etc.

 public string GetProductsByName (string name, string name1, string name2)
         {

             return "Requested name:" + ":" + name + ":" + name1 + ":" + name2;
         }

It works and brings me the parameters name, name1 name2 and. But if I want to see more parameters, I have to define the in config.Routes. Which makes the system more complicated.

Need to separate the data into two parts and put them in string variables. For example:

http://localhost:39051/api/values/punto1?name=125.25&name1=1&name2=23.98

string1: punto1

and the other string is put everything after the?

string2: name=125.25&name1=1&name2=23.98

or

string2: name=125.25&name1=1&name2=23.98&name3=12.5&name6=34&name23=3

Depending on the case

Then string2 separate process to scan values.

It works perfectly, I tried it and brings the data correctly.

One more query, if I get 4 different parameters, in consultation, as would be the separation of parameters for example:

 http://localhost:39051/api/values/punto1.25?name=5.25&name1=1&valor1=23.98&valor2=0.125&book2=17&book1=8&nivel15=9&nivel20=8
user3923880
  • 74
  • 1
  • 6
  • 1
    What is the question? – witrin Aug 08 '14 at 22:08
  • Have you considered 1 string with a delimiter and parsing the string for all the product names using the delimiter? Instead of what you are trying to do which is an unknown/unlimited number of parameters. There is a max length to the URL dependent on Browser. – CodeCowboyOrg Aug 08 '14 at 22:22

2 Answers2

0

So you are searching by name(s) but you could have any number of names passed in?

You could bind to a List<string> to prevent you needing to add parameters and edit your routes.

public string Get([FromUri]List<string> Names)
{
    string output = "Requested name";
    foreach (var item in Names)
    {
        output += ":" + item;
    }

    return output;
}

To get that to work with your URL you need to send the parameters in the form

names[0]=firstparam&names1=secondParam

for example: http://localhost:39051/api/values?names[0]=name1&names[1]=name2&names[2]=name3

will produce the output

Requested name:name1:name2:name3

Alternatively, as long as you keep the name the same you can remove the indexing and pass the parameters like this: http://localhost:39051/api/values?names=name1&names=name2&names=name3

Note the [FromUri] is telling the model binder to take the values from the Uri. If you have a Post rather than a Get then you won't need the [FromUri] as the data will be in the body.

This way you won't need to change your routing at all when you want to add new parameters.

Be aware that there are limits to the length of the Uri that browsers allow. See this Stackoverflow question for more information.

Edit

As you can't change the URL, the only thing I think you could do is create your own ModelBinder.

You could create a binder that checks the parameters that match a particular criteria and then convert those into a list or dictionary in your action method.

To create a ModelBinder you need to create a class that implements IModelBinder then in your action method you need to decorate the parameter you wish to be bound using your binder with the ModelBinder attribute.

A very rough example that only handles parameters on the querystring would be:

public class MyModelBinder : IModelBinder
{
    public bool BindModel(System.Web.Http.Controllers.HttpActionContext actionContext, ModelBindingContext bindingContext)
    {
        List<string> names = new List<string>();

        if (!string.IsNullOrEmpty(actionContext.Request.RequestUri.Query))
        {
            foreach (var item in actionContext.Request.GetQueryNameValuePairs().ToDictionary(x => x.Key, x => x.Value))
            {
                if (item.Key.ToLower().StartsWith("name"))
                {
                    //it's a "nameX" parameter so let's add it to the list
                    names.Add(item.Value);
                }
            }
        }

        //this is what will be bound to "name" in the action method
        bindingContext.Model = names;
        return true;
    }
}

Then in the action method you can wire up your binder:

public string Get([ModelBinder(typeof(MyModelBinder))] List<string> name)
{
    string output = "Requested name";
    foreach (var item in name)
    {
        output += ":" + item;
    }

    return output;
}

Given the querystring

http://localhost:39051/api/values?name=name1&name1=name2&name2=name3

will again produce the output

Requested name:name1:name2:name3

Community
  • 1
  • 1
petelids
  • 12,305
  • 3
  • 47
  • 57
  • Thanks for the reply, but the URL I can not change, comes from another system. I could try what you say and it works correctly, but the URL would have to change and it is impossible. Length is not a problem, would always be less than 250 characters. Thank you – user3923880 Aug 09 '14 at 20:13
  • @user3923880 - is there an upper limit on the number of names being passed in? – petelids Aug 09 '14 at 20:27
  • The URL can have an approximate length of 2000 characters, if the lists are not the same, I take this as a limit value. – user3923880 Aug 10 '14 at 22:11
0

It works perfectly, I tried it and brings the data correctly.

One more query, if I get 4 different parameters, in consultation, as would be the separation of parameters for example:

http://localhost:39051/api/values/punto1.25?name=5.25&name1=1&valor1=23.98&valor2=0.125&book2=17&book1=8&nivel15=9&nivel20=8
user3923880
  • 74
  • 1
  • 6
  • 1
    **Please do not ask another question in answer area. If you have want to clarify your original question, please append it at the end of the original question.** – Win Aug 11 '14 at 23:32