2

I got a problem with my model binding. Got here following models:

public class RoomScan
{
    public RoomScan() { }

    public RoomScan(Guid id)
    {
        Room_ID = id;
        Assets = new List<AssetScanModel>();
    }
    //public Guid Soll_ID { get; set; }
    public Guid Room_ID { get; set; }
    public List<AssetScanModel> Assets { get; set; }

    [Display(Name = "Barcode", ResourceType = typeof(Dictionary))]
    public string Barcode { get; set; }

    [Display(Name = "RFID", ResourceType = typeof(Dictionary))]
    public string RFID { get; set; }
}

public class AssetScanModel
{
    public AssetScanModel(Asset asset)
    {
        Asset = asset;
        Scanned = false;
        CheckIn = false;
    }

    public Asset Asset { get; set; }

    [Display(Name = "Scanned", ResourceType = typeof(Dictionary))]
    public bool Scanned { get; set; }

    [Display(Name = "CheckIn", ResourceType = typeof(Dictionary))]
    public bool CheckIn { get; set; }
}

The View does list all the Assets:

using (Html.BeginForm("Scan", "Inventory", FormMethod.Post))
{
Html.HiddenFor(rs => rs.Room_ID);
Html.HiddenFor(rs => rs.Assets);

<div>
    <div class="editor-label">Barcode</div>
    <div class="editor-field"><input type="text" name="Barcode" value="@Model.Barcode" /></div>
</div>
<div>
    <div class="editor-label">RFID</div>
    <div class="editor-field"><input type="text" name="Barcode" value="@Model.RFID" /></div>
</div><br />

...

@for (int i = 0; i < Model.Assets.Count; i++)
{
    <tr>
        <td>@Html.DisplayFor(asm => asm.Assets[i].Asset.InventoryNumber)</td>
        <td>@Html.DisplayFor(asm => asm.Assets[i].Asset.Description)</td>
        <td>@Html.DisplayFor(asm => asm.Assets[i].Asset.Manufacturer)</td>
        <td>@Html.DisplayFor(asm => asm.Assets[i].Asset.Model)</td>
        <td>@Html.DisplayFor(asm => asm.Assets[i].Asset.SerialNumber)</td>
        <td>@Html.DisplayFor(asm => asm.Assets[i].Scanned)</td>
        <td>@Html.DisplayFor(asm => asm.Assets[i].CheckIn)</td>
    </tr>
}

I added the "Asset[i]" because I read somewhere it helps the default model binder to bind propperly (didn#t work)

My problem is: in my controller:

[HttpPost]
    public ActionResult Scan(RoomScan toVerify)

the List is empty (not null). I know this has to do with the model binder, but I am not familiar how to change it so it does work.

3
  • first change the DisplayFor to EditorFor ... then look at the generated html. Next make sure the input names look like toVerify.Assests[0].Assest.Inventory etc. Commented Feb 12, 2013 at 10:15
  • You should be using public ActionResult Scan(IEnumerable<RoomScan> toVerify){}. Please check this Commented Feb 12, 2013 at 10:46
  • @DavidPerlman I am just displaying the List, there should be no edit fields. the whole list is part of a form, in wich you can send a RFID or Barcode to the controller. Wich checks a scanned asset and sets "scanned" = true Also, the RoomScan Model is no List, it just contains one. Commented Feb 12, 2013 at 11:26

2 Answers 2

1

I have been using this for binding complex models with nested lists. I almost always replace the default model binder with this right off the bat...

A DefaultModelBinder that can update complex model graphs

I hope this helps you as much as it did me.

Sign up to request clarification or add additional context in comments.

3 Comments

Looks like the right direction. I implemented it, but in the controller the AssetScanModel List is null.. I checked the new modelBinder, and he does not even get a AssetScanModel List from the view. Thats wierd, I think there is a big blunder i coded in
found some mistakes on my side in the view (it seems html helper tend to be ignored if they are not wrapped around a html tag (div, etc)
Ah, yes. That'll get ya. Glad you were able to get it figured out.
0

Try DisplayTemplates/EditorTemplates, create template for ur nested model type. In View write:

@Html.DisplayFor(asm => asm.Assets)

in DisplayTemplate (AssetScanModel.cshtml):

@model AssetScanModel

<tr>
    <td>@Html.DisplayFor(asm => asm.Asset.InventoryNumber)</td>
    <td>@Html.DisplayFor(asm => asm.Asset.Description)</td>
    <td>@Html.DisplayFor(asm => asm.Asset.Manufacturer)</td>
    <td>@Html.DisplayFor(asm => asm.Asset.Model)</td>
    <td>@Html.DisplayFor(asm => asm.Asset.SerialNumber)</td>
    <td>@Html.DisplayFor(asm => asm.Scanned)</td>
    <td>@Html.DisplayFor(asm => asm.CheckIn)</td>
</tr>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.