How to pass complex class as argument to httpget

Viewed 7114

I would like to be able to handle a complex type as an argument to my HttpGet method.

The method pickNFirstElements works when the api method does not take any parameters, but not when i try to pass the object.

I have an idea that i need to inform my ajax query that the data is a single object, but i don't know how that is done, as i thought that was the point of BindProperties tag in the TodoItem class.

[HttpGet]
        [Route("search")]
        public async Task<ActionResult<TodoItem>> GetMatchingTodoItem([FromQuery]TodoItem todo)
        {
            // var name = todo.Name;
            // var completed = todo.IsComplete;
            return await _context.TodoItems.FirstAsync();
        }
function pickNFirstElements() {
    const item = {
        Name: "dope",
        IsComplete: false,
        Id: 2
    }
    $.ajax({
        type: "GET",
        url: uri+"/search",
        data: { name: item.Name, isComplete: item.IsComplete, Id: Item.Id },
        cache: false,
        success: function (return1) {
            alert(return1.name);
        }
    })
};
namespace TodoApi.Models
{
    [Microsoft.AspNetCore.Mvc.BindProperties(SupportsGet =true)]
    public class TodoItem
    {
        public long Id { get; set; }
        public string Name { get; set; }
        public bool IsComplete { get; set; }
    }
}
2 Answers

Your code is actually working (almost) fine. You only have a typo in this line:

data: { name: item.Name, isComplete: item.IsComplete, Id: Item.Id },

should be lowercase 'item' instead of 'Item':

data: { name: item.Name, isComplete: item.IsComplete, Id: item.Id },

Check your console in the browser, you'll see that it cannot find the object 'Item'.

HTTP Get are meant to be stateless and immutable. You cannot pass something in the request body using HTTP Get.

So you can either send query / route parameters.

I suggest to refactor your code to this:

Javascript:

function pickNFirstElements() {
    const item = {
        Name: "dope",
        IsComplete: false,
        Id: 2
    };
    const queryParams = new URLSearchParams(item).toString();

    $.ajax({
        type: "GET",
        url: `${uri}/search?${queryParams}`,
        cache: false,
        success: function (return1) {
            alert(return1.name);
        }
    })
};

C#:

[HttpGet("search")]
public async Task<ActionResult<TodoItem>> GetMatchingTodoItem(string name, bool isComplete, int Id)
{
    return await _context.TodoItems.FirstAsync();
}
Related