2

Basically, I would like to know if a MVC View @HTML control can handle all types of data correctly.

For instance my ViewModel is as follows:

public class ViewModel
{
 public int Id { get; set; }
 public string Name { get; set; }
 public MyClass Obj { get; set; } //custom class
}

Into the view, I ll strongly type the View with:

@modem <NameSpace>.ViewModel

Ideally, I would like the View to let the user fill the Name and keep records of the Id and Obj

I will end up with a form looking like this:

@using (Html.BeginForm("MyAction", "MyController"))
{
    @Html.Hidden("Id", Model.Id) // --> this will work
 @Html.Hidden("Obj", Model.Obj)// --> this will NOT work
@Html.TextBox("Nom", null)// --> this will work
<input type="submit" value="Submit" />
}

The Id and Name will be correctly submitted but I ll get viewModel.Obj = null into my controller:

public ActionResult MyAction(ViewModel viewModel)

So it looks that MVC can correctly handle some types and cannot some more complex types. Can someone let me know what types work and do not work?

Or did I miss something obvious??

Mr Lister
  • 45,515
  • 15
  • 108
  • 150
A D
  • 307
  • 3
  • 21
  • All types will work as long as you create custom model binding for them. Are you asking about default model binding behavior? – Alexei Levenkov Jan 26 '16 at 21:46
  • HTML inputs can only hold primitive values. So any complex object would either need to be split into multiple primitive values (on multiple inputs) or serialized to a string (on a single input). How the controller *re-assembles* values into an object is a matter of model binding. You can use the default model binder, or write any number of custom ones. – David Jan 26 '16 at 21:46

1 Answers1

4

Html.HiddenFor won't work for your custom class. What you can do is to create form elements for different properties of your Model.Obj property and name it same as the property hierarchy of your viewmodel so that when you submit the form, the DefaultModelBinder will be able to map the form field's your ViewModel object properties.

@model ViewModel
@using (Html.BeginForm())
{
    @Html.Hidden("Id", Model.Id)

    @Html.Hidden("Obj.Id", Model.Obj.Id)
    @Html.Hidden("Obj.Name", Model.Obj.Name)

    @Html.TextBox("Nom", null)
    <input type="submit" value="Submit" />
    <input type="submit" />
}

Assuming Name and Id are properties of your MyClass.

And your HttpPost action looks like

[HttpPost]
public ActionResult Index(ViewModel model)
{
    // to do  : Do something and return something
}

Another solution is to use Editor templates and calling that like Html.EditorFor(Model.Obk) as explained in this post.

Also, Unless it is absolutely needed, you should not set all the property values in the form. Instead,in the HttpPost action you should be querying the entity again with a unique identifier ( a primary key of your table? , which you kept in the form as a hidden field)from your db or somewhere and use that as needed.

Community
  • 1
  • 1
Shyju
  • 214,206
  • 104
  • 411
  • 497