skip to Main Content

In converting from framework 4.72 to .NET 7 (VS 2022) I am having trouble passing a complex JSON object from the view to the controller.
Of course this works in Framework but I have not been able to get it to work in .NET 7.
I have simplified the problem as much as I could to work on myself and post for others to understand.

I have the following two c# data classes

    public class Foo
    {
        public int Id { get; set; }
        public List<Thing> Things { get; set; }

    }

    public class Thing
    {
        public string Name { get; set; }
    }

I want to pass a Foo Json object from the view to the controller using Ajax

     public JsonResult ProcessFoo(Foo foo)
     { 
         return Json(foo);
     }
     

I have tried many ways of passing this object to the controller and this example at least passes the root properties.
Applying JSON.stringify did not work for me. The Things List is always null.

     testPassingFooViaAjax function (itemPriceComboboxInput) {

        
        var things = [{ Name: "Shoe" }, { Name: "House" }, { Name: "Boat" }];
        var foo = { Id: 123, Things: things};
        data = foo;

        $.ajax({
            type: "Post",
            cache: false,
            url: '@Url.Action("ProcessFoo", "FooProcessor")',
            data: data,
            dataType: "json",
            async: false,
            traditional: true,
            success: function (model) {
                //Do Something
            }
        });


    },
    
    

I was able to get an example working that passed a list of strings but not a list of objects.

2

Answers


  1. I recommend you to send your data as json. Fix ajax

       ...
       data: JSON.stringify(foo),
       contentType: 'application/json; charset=utf-8',
       dataType: "json",
        ....
    

    and fix the action header

       public JsonResult ProcessFoo([FromBody]Foo foo)
    

    and I don’t know what serializer you are using, but if you use system.text.json you maybe need to add [JsonPropertyName] attribute too.

    Login or Signup to reply.
  2. I have tried many ways of passing this object to the controller and
    this example at least passes the root properties. Applying
    JSON.stringify did not work for me. The Things List is always null.

    Seems you are using MVC controller in .NET 7 project. If you use [ApiController] attribute in that case you could receive your request as ProcessFoo(Foo foo) because in APIController requests usually bind in [FromBody] by default. But in your scenario if you do not specify [FromBody] in request it would loose data which you are currently experiencing.

    Therefore, you would would like to stick to current implementation then you would need to decorate your method with form [FromBody] and at the same time request would require to parse explicitely in json as JSON.stringify(foo).

    Required Changes in Current Implementation:

    Controller:

            [HttpPost]
            public JsonResult ProcessFoo([FromBody]Foo foo)
            {
                return Json(foo);
            }
    

    Script:

    var Things = [{ Name: "Shoe" }, { Name: "House" }, { Name: "Boat" }];
                var foo = { Id: 123, Things: Things };
    
               
                console.log(foo);
             
                $.ajax({
                    type: "POST",
                    cache: false,
                    url: '@Url.Action("ProcessFoo", "FooProcessor")',
                    data: JSON.stringify(foo),
                    dataType: "json",
                    async: false,
                    success: function (model) {
                        //Do Something
                    }
                });
    

    Output:

    enter image description here

    Alternative Way Using API Controller:

        [ApiController]
        public class FooProcessorController : ControllerBase
        {
    
            [HttpPost]
            public IActionResult ProcessFoo(Foo foo)
            {
                return Ok(foo);
            }
    
        }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search