0

I'm having difficulty sending an array of values to my WebAPI2 controller. Originally asked here: Complex input to WebApi2 function

I'm also having issue trying to send the values using ajax, the ajax method is only going to be used to test this Action and the action will actually be called using a WebClient object in the production code as shown below. It seems that when I get to the Action, the VP parameter isn't being read correctly.

I've tried it using both POST and GET with same results. Any ideas on what I'm doing wrong here?

This is the URL from Request as it is being set when I examine it in the Action:

http://localhost:49494/api/GetDocs?LT=c40210542a802cac4ca5fc96eaa2c3bfef592418b5&PID=1158341&VP[0][Name]=RID&VP[0][Value]=1158341&ER=100&SR=1&SB=DOCNAME+ASC

This is the Ajax call sending the data:

var _url = "http://localhost:49494/api/GetDocs";
var postdata = {
    "LT": "c40210542a802cac4ca5fc96eaa2c3bfef592418b5",
    "PID": 1158341,
    // VP may have more than one 'set' of values
    // This is essentially a list of fields and values to filter a dataset
    "VP":[{"Name":"RID","Value":"1158341"}], 
    "ER": 100,
    "SR": 1,
    "SB": "DOCNAME ASC",
}


$.ajax({
    async: true,
    cache: false,
    traditional: true, // Yes I am setting this to true!
    contentType: 'application/x-www-form-urlencoded',
    url: _url,
    type: 'GET',
    // type: 'POST',
    data: postdata,
    beforeSend: function () {
        console.log('Fired prior to the request');
    },
    success: function (data) {
        console.log('Fired when the request is successfull');
        $('.document').append('<p>Success :' + data + '</p>');
    },
    complete: function () {
        console.log('Fired when the request is complete');
    },
    error: function (jqxhr, status, errorThrown) {
        $('.document').append('<p>Error :' + jqxhr.responseText + '</p>');
    }
});

Here is how it will be sent in the production code from another MVC application:

// request object will be passed to the method.
string returnjson = "";
using (WebClient client = new WebClient())
{
    client.Headers[HttpRequestHeader.ContentType] = "application/json";
    url = "http://mywebapiapp.com/api/GetDocs";
    string json = JsonConvert.SerializeObject(request);
    byte[] data = Encoding.UTF8.GetBytes(json);
    byte[] result = client.UploadData(url, data);
    returnjson = Encoding.UTF8.GetString(result);
}
return returnjson

And this is my WebAPI2 controller action. I have tried with both List<string> and string[]. The value of the VP parameter is ALWAYS null.

[HttpGet]
[Route("api/GetDocs")]
[EnableCors("http://localhost:49494", // Origin
    "Accept, Origin, Content-Type, Options",                                // Request headers
    "GET",                                                                 // HTTP methods
    PreflightMaxAge = 600                                                   // Preflight cache duration
)]
public IHttpActionResult GetDocs(string LT, int PID, List<string> VP, int SR = 1, int ER = 100, string SB = "")
{
    string msg = "";

    try
    {
        var result = _Repository.getDocuments(LT, PID, VP.ToArray(), SR, ER, SB);
        string resultstring = Newtonsoft.Json.JsonConvert.SerializeObject(result);
        // Now send results back...
        return Ok(result);
    }
    catch (Exception ex)
    {
        /*
        log.WriteToEventLog(msg, "error");
        log.WriteToEventLog(ex.Message, "error");
        */
        throw ex;
    }
}
Community
  • 1
  • 1
MB34
  • 4,210
  • 12
  • 59
  • 110
  • Take a look at [this answer](http://stackoverflow.com/questions/20226169/how-to-pass-json-post-data-to-web-api-method-as-object/20226220#20226220) for sending data to web api from your ajax call. – Shyju Dec 23 '15 at 17:03
  • post as answer, please – MB34 Dec 23 '15 at 17:21

1 Answers1

0

For the kind of structured data that you are sending i suggest POST instead of GET.

Btw your example working in few steps:

public class TestVm
{
    public string LT { get; set; }
    public int PID { get; set; }
    public List<KeyValuePair<string,string>> VP { get; set; }
    public int SR { get; set; }
    public int ER { get; set; }
    public string SB { get; set; }
}

[HttpPost]
public IHttpActionResult GetDocs(TestVm VM)
{
    //your code here

}

$.ajax({
   //other code removed for readability 
    contentType: 'application/json',
    type: 'POST',
    data: JSON.stringify( postdata),
});

var postdata = {
    "LT": "c40210542a802cac4ca5fc96eaa2c3bfef592418b5",
    "PID": 1158341,
    // use 'Key' and 'Value' for correct bind with List<KeyValuePair>
    "VP":[{"Key":"RID","Value":"1158341"}], 
    "ER": 100,
    "SR": 1,
    "SB": "DOCNAME ASC",
}

Summary:

  1. Declare a complex type to use as a dto

  2. Add the HttpPost attribute to GetDocs action and then replace all parameters with a TestVm instance

  3. Change the contenttype header of your request to 'application/json'

  4. Trasform your data to JSON

Hope this helps!

omar.ballerani
  • 148
  • 1
  • 2
  • 7