11

I've read all similar questions here, but i can't come up with solution. I'm trying to call web-api method:

[HttpGet]
public SearchViewModel Get(SearchTypes type, string text, [FromUri]Dictionary<string, string> toyParams)
{
    //Code here
}

and i want to get last parameter from uri. I've tried

http://localhost:39101/#!/search/toys/fox?someParameter=123

and

http://localhost:39101/#!/search/toys/fox?toyParams[0].Key=someParameter&toyParams[0].Value=123

but toyParams Dictionary always empty.

LbISS
  • 623
  • 2
  • 10
  • 25
  • What if you comma separate the values in the URL, get them back as a long string, then split them to get the toyParams. – rasharasha Oct 12 '15 at 17:14
  • Seems like a hack, not a solution.) – LbISS Oct 12 '15 at 17:17
  • 2
    passing dictionary key/values via URI in a GET request!!. Why don't you have some kind of id for the data you want to retrieve, so that you don't have to pass such huge data in URI – blogbydev Oct 12 '15 at 17:18
  • 2
    I had assumed you wanted to conform to GET request semantics. Otherwise if its a general solution considering you are passing quite some data, then you may need to do a good old POST request will have to do. – rasharasha Oct 12 '15 at 17:19
  • 1
    i don't think you will be able to do that. Reason being, web api model default model binding work with name comparison. for example if you have a parameter named "toyParams[0].Key" (although you can't have it.) that will map with the query string parameter"toyParams[0],Key" having a value "someParameter" and so on. You might be able to do it via a custom model binding. BUT, please don't do it this way. I will wait for an answer to arrive to update my knowledge. – blogbydev Oct 12 '15 at 17:25
  • @singsuyash I'm trying to organize search by params and in some usecases it'll be great if user could share link to search results. – LbISS Oct 12 '15 at 17:26
  • 1
    this talks about a POST request, and the data is being sent as a post body not via url. – blogbydev Oct 12 '15 at 17:29
  • 1
    i am thinking about your search by params problem. you must have your search params like param1=value1&param2=value2 and so on right? Now you can create a class (DTO, Data Transfer Object) that contains properties i.e. param1, param2 with their respective dataTypes. it will fill up! Would you like this approach as an answer? – blogbydev Oct 12 '15 at 17:32
  • @singsuyash I've tried to do common method, smth like "search object by params"... If it's difficult, i'll do a few methods by object types. – LbISS Oct 12 '15 at 17:36

4 Answers4

2

Just found out it is implicitly answered at another question here.

The solution it points at redirects to Model Binding in ASP.NET Core.

Or, short answer, you just compose your request like so:

http://localhost:39101/#!/search/toys/fox?toyParams[someParameter1]=123&toyParams[someParameter2]=456

tshang
  • 21
  • 4
0

Even though its quite late but following method is available to return query parameters as a name/value pair - this.Url.Request.GetQueryNameValuePairs()

I have following Url - http://localhost:49980/api/MyRestAPI/postSomeData/?a=v&d=e

Following is my method, written in Web API 2 -

[HttpPost]
public IHttpActionResult SaveDataFromRestToDB(string dataKey) {
     var parameters = this.Url.Request.GetQueryNameValuePairs();
     //parameters returns KeyValuePair<string, string>[2], containing values passed in Url Query
}

Hope this helps!!

Raj
  • 127
  • 2
  • 9
0

API Method accepting dictionary as the request object.

[HttpPost("test")]
public async Task<IActionResult> TestDictionary(Dictionary<string, List<MyList>> pairs)
{
    foreach (var pair in pairs)
    {
        var a = new 
        { 
             Id = pair.Key, 
             Name = pair.Value.FirstOrDefault().Name,
             Age = pair.Value.FirstOrDefault().Age
        };
        return Ok(a);
    }
    return NotFound();
}

class MyList
{
    string Name { get; set; };
    string Age { get; set; };
}

Request object for testing the API.

{
  "myid": [
    {
      "Name": "testName",
      "Age": "testAge"
    }
  ]
}

Response received.

{
  "Id": "myid",
  "Name": "testName",
  "Age": "testAge"
}
-4

One Simple way, instead of dictionary:

    //DTO
    public class SearchDTO
    {
        public int MyProperty1 { get; set; }
        public int MyProperty2 { get; set; }
        public int MyProperty3 { get; set; }
    }

Where MyProperty1, MyProperty2, MyProperty3 are the params based on which something has to be searched.

        //GET Method
        public string Get([FromUri]SearchDTO searchDTO)
        {
            return "search result";
        }

Below is the Calling URL :

http://localhost:56880/api/values?myproperty1=1&myproperty2=2&myproperty3=3

blogbydev
  • 1,445
  • 2
  • 17
  • 29
  • old answer but this is not a good solution, in a context that u have to pass multiple dynamics parameters this solution is invalid. – Fernando Oct 18 '16 at 16:21
  • What other way is available in case of a GET request? – blogbydev Oct 19 '16 at 11:43
  • 1
    I would really like to know "What other way is available in case of a GET request?" Downvoters, can you please explain( i want to know because i want to learn something) – blogbydev Mar 31 '17 at 13:24