简体   繁体   中英

ViewModel complex objects returning null when passed from view to controller

I'm trying to pass a ViewModel from controller to view and back. The data moves from controller to view just fine, displaying all the necessary fields. However, upon sending the data back, the field values are gone.

Sending the ViewModel

public ActionResult Process()
        {
            MugshotImportProcessViewModel model = new MugshotImportProcessViewModel();

            FooRecord query_one = _service.QueryFooRecord(abc);
            BarRecord query_two = _service.QueryBarRecord(xyz);


                model.recordA = query_one;
                model.recordB = query_two;
                model.testNum = 42;


                return View(model);
        }

The View, using and then returning the ViewModel

@model Foo.ViewModels.MugshotImport.MugshotImportProcessViewModel

...
// Display some HTML data
...

@using (Html.BeginForm("AddRecord", "MugshotImport", FormMethod.Post))
                {
                     @Html.HiddenFor(x => x.recordA)
                     @Html.HiddenFor(x => x.recordB)
                     @Html.HiddenFor(x => x.testNum)

                    <input type="submit" class="btn btn-primary" value="submit"/>
                }

Receiving the ViewModel back in the controller

        [HttpPost]
        public ActionResult AddRecord(MugshotImportProcessViewModel returnVal)
        {
            if (returnVal == null )
            {
                _log.LogDebug("Model is null.");
            }
            else
            {
                _log.LogDebug($"testnum is {returnVal.testNum}, recordA.foo is {returnVal.recordA.foo}, recordB.bar is {returnVal.recordB.bar}");
            }

            return RedirectToAction("Process");
        }

The model itself is not returning null, but I receive a NullReferenceException whenever I try to reference returnVal.recordA.foo or returnVal.recordB.bar .

If I remove those two and simply request returnVal.testNum, it returns testnum is 0 .

How can I get the values to return properly back to the controller?

Since you did not provide the structure of FooRecord and BarRecord , I customized them as the following.

 public class MugshotImportProcessViewModel
    {
        public FooRecord recordA { get; set; }
        public BarRecord recordB { get; set; }
        public int testNum { get; set; }
    }
    public class FooRecord
    {
        public int id { get; set; }
        public string Name{ get; set; }
    }
    public class BarRecord
    {
        public int id { get; set; }
        public string Name { get; set; }
    }

Because they are not simple types of fields, but an entity field, you need to store each of their fields separately when you use the hidden control in the view.

@using (Html.BeginForm("AddRecord", "MugshotImport", FormMethod.Post))
{
    @Html.HiddenFor(x => x.recordA.id)
    @Html.HiddenFor(x => x.recordA.Name)
    @Html.HiddenFor(x => x.recordB.id)
    @Html.HiddenFor(x => x.recordB.Name)
    @Html.HiddenFor(x => x.testNum)
    <input type="submit" class="btn btn-primary" value="submit" />
}

Here is the test result:

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM