1

My controller method with WebApi2

    [HttpGet]
    public IEnumerable<Products> GetProducts(ProductSearchCriteria searchCriteria)
    {
        //searchCriteria is always null here!!! Why?
        return db.Instance.LoadProducts(searchCriteria);
    }

My search criteria class

public class ProductSearchCriteria
{
    private int id;
    private string name;
    private DateTime createdOn;

    [JsonProperty]
    public string Name
    {
        get { return this.name; }
        set { this.name = value; }
    }

    [JsonProperty]
    public DateTime CreatedOn
    {
        get { return this.createdOn; }
        set { this.createdOn = value; }
    }

    [JsonProperty]
    public int ID
    {
        get { return this.id; }
        set { this.id = value; }
    }
}

My script in the html page

<script>
    $("#btnTest").on("click", function () {
        var searchCriteria = {};
        searchCriteria.ID = 0;
        searchCriteria.Name = "";
        //searchCriteria.CreatedOn = "";
        var url = "http://localhost:8080/api/products"
        $.getJSON(url, searchCriteria).done(processResponse);
    });

    function processResponse(response){
    }
</script>

I reach my controller method (debug mode) but the ProductSearchCriteria searchCriteria parameter is always null. How can I send my JSON object using get method with JQuery and WebApi2?

Maximus Decimus
  • 4,901
  • 22
  • 67
  • 95
  • a GET request shouldn't have a body as it will be ignored by the server, so you must pass the data on the query string as plain parameters and mark the handler with [FromUri] or even better, use the POST method. – Gusman Mar 23 '17 at 21:36

4 Answers4

0

You could try to decorate your parameter with [FromUri].

[HttpGet]
public IEnumerable<Products> GetProducts([FromUri] ProductSearchCriteria searchCriteria)
{
    //searchCriteria is always null here!!! Why?
    return db.Instance.LoadProducts(searchCriteria);
}

Another option is to stringify your JSON object and deflate it in your server side code. You can do this using converters such as JSON.NET or you could use a custom type converter, model binder or value provider. More info can be found here.

hbulens
  • 1,872
  • 3
  • 24
  • 45
0

Use post rather :

$("#btnTest").on("click", function () {
    var searchCriteria = {};
    searchCriteria.ID = 0;
    searchCriteria.Name = "";
    //searchCriteria.CreatedOn = "";
    var url = "http://localhost:8080/api/products"
    $.post(url, data, processResponse, 'json');

});

And change method attribute to:

[HttpPost]
public IEnumerable<Products> GetProducts(ProductSearchCriteria searchCriteria)
Chester Cobus
  • 701
  • 4
  • 12
0

You are sending the query to the server using $.getJSON(url, searchCriteria) and getJSON sends the searchCriteria as a url-encoded query string because your searchCriteria would fit the definition of a plain object

On the server side, the default parameter binding for .NET Web API will look in the URL for "simple" data types (e.g. int, double, string), otherwise it will fall back to the body Content.

To get Web API model binding to extract a complex type from the url, like your ProductSearchCriteria class you need to add the [FromUri] attribute in front of the parameter like this:

[HttpGet]
public IEnumerable<Products> GetProducts([FromUri] ProductSearchCriteria searchCriteria) {}

See here for more detail Parameter Binding in ASP.NET Web API

I would argue it is worth trying to preserve the GET semantics rather than switching to POST, as some have suggested, because your code is effectively doing what looks like a read operation and as long as you're not modifying data or state... a GET seems applicable.

Neil Fenwick
  • 6,106
  • 3
  • 31
  • 38
-1

Try this code

[HttpGet]
public IEnumerable<Products> GetProducts([FromUri]ProductSearchCriteria searchCriteria)
{
    //searchCriteria is always null here!!! Why?
    return db.Instance.LoadProducts(searchCriteria);
}
muratoner
  • 2,316
  • 3
  • 20
  • 32