每个视图的多个操作,包括绑定到模型的部分视图

时间:2012-02-29 13:11:42

标签: asp.net-mvc asp.net-mvc-3

扩展名为: How do you handle multiple submit buttons in ASP.NET MVC Framework?

让我们说一个视图由与相关模型绑定的部分视图组成,假设学生需要提供多个联系人(部分视图绑定到Person模型)和多个联系人编号(部分视图绑定到模型)到得到注册,抱歉这个坏榜样。一旦添加了联系人或号码,就会调用一个动作(子回发或其他)来验证相关模型(而不是学生模型),将其添加到列表中并返回到同一页面以进行进一步处理。一旦添加完所有内容,父/主动作将验证整个学生模型并对其进行处理。

如何验证要为其调用操作的特定模型,将其添加到页面并返回相同的学生视图,并在响应中添加值?

2 个答案:

答案 0 :(得分:1)

此解决方案使用#2(会话),因为它更简单的代码,但这证明了原则。

浏览

索引视图:

@using StackOverflow.Models

    <div>

    @{ Html.RenderPartial("PersonGrid", Model.Persons, new ViewDataDictionary()); }
    @Html.Partial("NewPerson", new Person())
    @{ Html.RenderPartial("ContactGrid", Model.Contacts, new ViewDataDictionary()); }
    @Html.Partial("NewContact", new Contact())

    @using(Html.BeginForm("Validate", "Home", FormMethod.Post))
    {
        <input type="submit" value="Validate" />
    }
    </div>

Person Grid


    @model IList

    <table>
        <thead>
            <tr>
                <td>First Name</td>
                <td>Last Name</td>
            </tr>
        </thead>

        <tbody>
            @if (Model != null && Model.Any())
            {
                foreach (var person in Model)
                {
                    <tr>
                        <td>@person.FirstName</td>
                        <td>@person.LastName</td>
                    </tr>
                }
            }
            else
            {
                <tr>
                    <td colspan="2" style="text-align: center">No persons available</td>
                </tr>
            }
        </tbody>
    </table>

联系网格


    @model IList

    <table>
        <thead>
            <tr>
                <td>Phone</td>
            </tr>
        </thead>
        <tbody>
            @if (Model != null && Model.Any())
            {
                foreach (var contact in Model)
                {
                    <tr>
                        <td>@contact.Phone</td>
                    </tr>
                }
            }
            else
            {
                <tr>
                    <td>No contacts available</td>
                </tr>
            }
        </tbody>
    </table>

新人


    @model StackOverflow.Models.Person


    @using (Html.BeginForm("NewPerson", "Home", FormMethod.Post))
    {
        <div>
            @Html.Hidden("PersonViewState", TempData["PersonViewState"])

            @Html.LabelFor(m => m.FirstName)<br />
            @Html.TextBoxFor(m => m.FirstName)<br />

            <br />

            @Html.LabelFor(m => m.LastName)<br />
            @Html.TextBoxFor(m => m.LastName)<br />

            <br />
            <input type="submit" value="Submit" />
        </div>
    }

新联系


    @model StackOverflow.Models.Contact

    @using (Html.BeginForm("NewContact", "Home", FormMethod.Post))
    {
        <div>
            @Html.LabelFor(m => m.Phone)<br />
            @Html.TextBoxFor(m => m.Phone)<br />
            <br />
            <input type="submit" value="Submit" />
        </div>
    }

模型



    public class Person
    {
        [Display(Name = "First Name")]
        public string FirstName { get; set; }

        [Display(Name = "Last Name")]
        public string LastName { get; set; }
    }

    public class Contact
    {
        [Display(Name = "Phone")]
        public string Phone { get; set; }
    }

    public class HomeModel
    {
        public IList<Person> Persons { get; set; }
        public IList<Contact> Contacts { get; set; }
    }

助手



    public static class PersistenceMechanism
    {
        public static IList GetPersons()
        {
            return (IList<Person>) HttpContext.Current.Session["__Persons"];
        }

        public static IList GetContacts()
        {
            return (IList<Contact>) HttpContext.Current.Session["__Contacts"];
        }

        public static void Update(IList<Person> persons)
        {
            HttpContext.Current.Session["__Persons"] = persons;
        }

        public static void Update(IList<Contact> contacts)
        {
            HttpContext.Current.Session["__Contacts"] = contacts;
        }
    }

控制器



    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            var model = new HomeModel
                            {
                                Persons = PersistenceMechanism.GetPersons(),
                                Contacts = PersistenceMechanism.GetContacts()
                            };
            return View(model);
        }

        [HttpGet]
        public ActionResult PersonGrid()
        {
            var persons = PersistenceMechanism.GetPersons();

            return PartialView(persons);
        }

        [HttpGet]
        public ActionResult ContactGrid()
        {
            var contacts = PersistenceMechanism.GetContacts();

            return PartialView(contacts);
        }

        [HttpPost]
        public ActionResult NewPerson(Person model)
        {
            var persons = PersistenceMechanism.GetPersons() ?? new List<Person>();
            persons.Add(model);
            PersistenceMechanism.Update(persons);

            return RedirectToAction("Index");
        }

        [HttpPost]
        public ActionResult NewContact(Contact model)
        {
            var contacts = PersistenceMechanism.GetContacts() ?? new List<Contact>();
            contacts.Add(model);
            PersistenceMechanism.Update(contacts);
            return RedirectToAction("Index");
        }

        [HttpPost]
        public ActionResult Validate()
        {
            var persons = PersistenceMechanism.GetPersons();
            var contacts = PersistenceMechanism.GetContacts();

            // validate
            // ...

            return RedirectToAction("Index");
        }
    }

答案 1 :(得分:0)

重复这个问题,以确保我知道你在问什么。

您的网页是使用不同模型的两个部分视图构建的。这两个部分视图都包含一个表单,该表单将在UI上提交构建记录网格。主页面将有一个进一步的验证按钮,然后在回发时验证两个网格的全部内容?

在这种情况下,我希望有两种形式,其中提交事件由Ajax提供支持。无论是jQuery / Microsoft Ajax。两个表格将提交两个单独的行动,接受他们各自的模型,人员和联系人。每个提交按钮将返回其各自的部分视图,该视图将是显示到目前为止已提交的项目集合的网格。返回的部分视图将更新指定的目标(例如div),因为我们使用的是AJAX。

当然,有必要记住到目前为止提交的先前项目,以便在添加新项目的情况下重建网格。这将意味着需要一些软持久存储。一些可用的选项是:

  1. 数据库
  2. 会话
  3. 隐藏表格字段(首选)。可以使用数组模型绑定机制在单个隐藏字段中支持此或简单的序列化对象(或对象列表)。
  4. 验证现在变得简单,因为模型在回发时通过持久存储机制在服务器端可用。