Strange behaviour in ASP.NET MVC: removing item from a list in a nested structure always removes the last item

混江龙づ霸主 提交于 2019-12-03 09:01:34

I believe that problem lies with ModelState. When the view gets rendered, which I assume is where the issue lies, after the POST, the last value is not displayed i.e. removed from the view.

The issue is that Model.Children.Count will return the correct number of elements to display.

Lets break this down...

So if you have initially had 5 then removed the first one which is at index 0 based on the Guid, you now have items 4 items left with indexes 1 to 4.

However, when rendering the view after the post, the HtmlHelpers do not look at the values in model posted, but rather the values contained within the ModelState. So in the ModelState, item with index 0 still exists and since the loop is now looping to 4, the last element will not be displayed.

The solution, use ModelState.Clear()

ModelState.Clear() will Solved this problem.

ModelState.Clear() is used to clear errors but it is also used to force the MVC engine to rebuild the model to be passed to your View.

OK, as Ahmad pointed out, ModelState is the key to the issue. It contains the collection as such:

  • FirstName
  • LastName
  • ...
  • Sings[0].OneSing
  • Sings[0].AnozerSing
  • Sings[1].OneSing
  • Sings[1].AnozerSing
  • Sings[2].OneSing
  • Sings[2].AnozerSing

Now if I delete item 0 from the list, now the items will move up in the list and the data in the ModelState will go out of sync with the model. I had expected ASP.NET MVC to be clever enough to find out and re-order, but well that is asking for too much.

I actually implemented PRG (post-redirect-get) and by keeping the model in session, I was able to display correct information but again, this will remove all the validation in the collection and if model itself is valid, it will happily save and redirect back to home "/". Clearly this is not acceptable.

So one solution is to remove all items in the ModelState and then add a new entry for the model itself (with key of EmptyString). This can actually work alright if you populate it with error "Item deleted" as this will be displayed in the validation summary.

Another solution is to manually change the items in the model state and re-arrange them based on the new indexes. This is not easy but possible.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!