aspnet / AspNetWebStack

ASP.NET MVC 5.x, Web API 2.x, and Web Pages 3.x (not ASP.NET Core)
Other
858 stars 354 forks source link

MVC Modelbinding change from 4.0.30506.0 to 5.2.6 #201

Closed luizfbicalho closed 6 years ago

luizfbicalho commented 6 years ago

I have this code in my mvc razor page

    <form action="/Home/Index" method="post">
        <input name="ListValues[]" class="form-control" id="ListValues[]" type="hidden" value="">
        <input type="submit"> submit </input>
    </form>

and this code in my controller

namespace ModelBinding.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        [HttpPost]
        public ActionResult Index(Obj obj)
        {
            return View();
        }
    }

    public class Obj
    {
        public List<Item> ListValues { get; set; }
    }

    public class Item
    {
        public string XX { get; set; }
    }
}

In the previous version (4.0.30506.0) my object received was this after the submit

{
  "ListValues": null
}

And now the value that is received in 5.2.6 is

{
  "ListValues": [
    null
  ]
}

How can I change it back to the 4.0 result?

dougbu commented 6 years ago

@luizfbicalho a great deal has changed since 4.0 and the previous behaviour was simply incorrect. You've got a form that unconditionally submits data for ListValues[] (an alternate name for the first entry in the ListValues collection). If the user hits "Submit" without changing the form field, the submitted value is empty and model binding converts that to a null entry in the collection.

It's not possible to revert to the earlier behaviour.

luizfbicalho commented 6 years ago

Ok, I understand.

Let me change the question:

How can I pass the inputs to get the Empty list? It's important to me to have different values for empty list and nothing, because if I pass nothing, I get the list from the server, if I pass an empty list, I clear the list from the server.

Thanks

dougbu commented 6 years ago

@luizfbicalho it's probably better to add a checkbox for the "delete all" case. That way, users don't need to clear multiple entries.

Separately, your action should ignore null entries in the collection. Or, you could do something nifty with JavaScript (or an additional round trip to the service) and add new entries when the user clicks a button. Then you could require the new field to be filled in.

dougbu commented 6 years ago

Thank you for your feedback. We're closing this issue as the questions asked here have been answered.