将具有成员对象或成员列表的对象从视图传递到控制器

时间:2017-10-08 13:25:07

标签: c# asp.net-mvc

以下是我的观点:

 using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using NHibernate.AspNet.Identity;

    namespace MyProject.Web.Models
    {
        public class IdentityRoleView
        {
            public virtual string Id { get; set; }
            public virtual string Name { get; set; }
            public virtual IList<IdentityUser> Users { get; set; }
        }
    }

这是我的控制器:

  [HttpGet]
            public ActionResult Edit(string roleId)
            {
                IdentityRole role = Service.Find(roleId);

                return View("Edit", AutoMapper.Mapper.Map<IdentityRoleView>(role));
            }

            [HttpPost]
            public ActionResult Edit(IdentityRoleView role)
            {
                Service.Update(role);
                TempData["Comment"] = "The record was updated";
                return RedirectToAction("Index");
            }
        }

以下是我的观点:

@model MyProject.Web.Models.IdentityRoleView
@{
    ViewBag.Title = "Edit";
    Layout = "~/Areas/Administration/Views/Shared/_Layout.cshtml";
}

    @using (Html.BeginForm())
    {
        @Html.AntiForgeryToken()
        @Html.ValidationSummary(true)
        @Html.HiddenFor(model => model.Id);
        <div>
            Role name
        </div>
        <p>
            @Html.TextBoxFor(model => model.Name)
        </p>

         for (int items = 0; items < Model.Users.Count; items++)
            {
                @Html.DisplayFor(m => m.Users[items].Id);
                @Html.DisplayFor(m => m.Users[items].UserName);
            }

        <input type="submit" value="Save" />
    }

IdentityRoleView.Users在传递回控制器时始终为null。问题是什么?我可以在视图上看到IdentityRoleView.Users - 它们在发回服务器时都被删除,因为IdentityRoleView.Users总是为空。

2 个答案:

答案 0 :(得分:0)

这是viewmodel

  public class IdentityRoleView
    {
        public IdentityRoleView()
        {
            Users = new List<IdentityUser>();
        }
        public virtual string Id { get; set; }
        public virtual string Name { get; set; }
        public virtual IList<IdentityUser> Users { get; set; }
    }

控制器方法

  public ActionResult Edit(string roleId)
        {
            IdentityRoleView model = new IdentityRoleView();

            model.Name = "IdentityRoleViewUser";
            model.Id = "2";

            model.Users.Add(new IdentityUser {
                UserName = "testuser",
                Id = "1",
                Email = "test@test.com"
            });

            model.Users.Add(new IdentityUser
            {
                UserName = "testuser2",
                Id = "2",
                Email = "test@test2.com"
            });

            return View("Edit", model);
        }

        [HttpPost]
        public ActionResult Edit(IdentityRoleView model)
        {

            //Your logic
            return RedirectToAction("Index");
        }

然后查看

@model MyProject.Web.Models.IdentityRoleView
@{
    ViewBag.Title = "Edit";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

@using (Html.BeginForm())
{
    @Html.ValidationSummary(true)
    @Html.HiddenFor(model => model.Id);
    <div>
        Role name
    </div>
        <p>
            @Html.TextBoxFor(model => model.Name)
        </p>

for (int i = 0; i < Model.Users.Count(); i++)
{
    @Html.TextBoxFor(model => model.Users[i].Email)
    @Html.TextBoxFor(model => model.Users[i].UserName)

}

            <input type="submit" value="Save" />
}

如果您希望该用户无法编辑值,请将TextBoxFor设为只读。

答案 1 :(得分:0)

这是MVC的一个怪癖。

你所拥有的是最正确的。

你的控制器很好:

 [HttpGet]
        public ActionResult Index()
        {
            Person p1 = new Person();
            p1.name = "Ian";

            List<Sport> sports = new List<Sport>();
            Sport s1 = new Sport();
            s1.description = "Football";
            sports.Add(s1);
            Sport s2 = new Sport();
            //s1.description = "Netball";   I'm guessing this is a typo?
            s2.description = "Netball";
            sports.Add(s2);
            p1.sports = sports;

            return View("Person", p1);
        }

        [HttpPost]
        public ActionResult Index(Person p1)
        {
            return View();
        }

然而,它的观点有问题:

@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">
        <h4>Person</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        <div class="form-group">
            @Html.LabelFor(model => model.name, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.name, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.name, "", new { @class = "text-danger" })
            </div>
        </div>

        @* This is the key difference here *@
        @for (int items = 0; items < Model.sports.Count; items++)
        {
            <div>
                @Html.DisplayFor(sport => Model.sports[items].description)
                @Html.HiddenFor(sport => Model.sports[items].description)
                <hr />
            </div>
        }

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Save" class="btn btn-default"/>
            </div>
        </div>

    </div>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

让我解释一下。

我所做的是将您的体育列表移到表格(){}中。这需要完成,以便实际让表单传回对象。无论该形式是什么,它都将发布回来。

您需要做的另一件事是给表单实际绑定模型对象。 @Html.DisplayFor帮助者不会这样做,因为看起来您不希望用户更改运动,您只需创建一个@Html.HiddenFor即可。这会将值传回您的[HttpPost] Index(Person p1)方法。

之后你做了什么,取决于你。

希望这会有所帮助。