繁体   English   中英

ASP.NET MVC 5:将所有局部视图绑定到主控制器

[英]ASP.NET MVC 5 : Binding all the partial views to the main controller

我正在使用ASP.NET MVC 5开发Web应用程序。我有多个局部视图及其对应的模型,但是只有一个与主视图相对应的控制器,该控制器使用以下代码显示每个局部视图。

@{Html.RenderPartial("PartialViewName");} 

我的问题是,如何将表单数据从所有局部视图(包括主视图)传递到主控制器?

最初,当我仅添加1个局部视图时,将其模型作为参数添加到主控制器的public ActionResult Index(MainModelName model1, PartialModelName pmodel1) 并且工作正常,我可以从主控制器的局部视图访问数据。

但是,当我添加第二个局部视图并用附加的局部模型参数更新public ActionResult Index(...)时,它没有帮助,因为数据没有从局部视图传递到主控制器。 虽然我没有任何错误。

我的主模型类将部分模型的对象引用作为其数据成员。 从我的阅读中,我需要有一个模型列表作为主控制器中方法的参数,但是我的模型不是子类型。

处理这种情况的惯用方式是什么?

谢谢!

EDIT1:这是示例应用程序的代码,在MainController.cs中访问mainModel.PartialModel2.Pm2时出现空引用错误,而我可以正确访问mainModel.PartialModel1.Pm1

MainModel.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace TestApp.Models
{
    public class MainModel
    {
        private int mm1;
        private PartialModel1 partialModel1;
        private PartialModel2 partialModel2;

        public int Mm1 { get => mm1; set => mm1 = value; }
        public PartialModel1 PartialModel1 { get => partialModel1; set => partialModel1 = value; }
        public PartialModel2 PartialModel2 { get => partialModel2; set => partialModel2 = value; }
    }
}

PartialModel1.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace TestApp.Models
{
    public class PartialModel1
    {
        private int pm1;

        public PartialModel1()
        {
        }

        public int Pm1 { get => pm1; set => pm1 = value; }
    }
}

PartialModel2.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace TestApp.Models
{
    public class PartialModel2
    {
        private int pm2;

        public PartialModel2()
        {
        }

        public int Pm2 { get => pm2; set => pm2 = value; }
    }
}

Index.cshtml

@model TestApp.Models.MainModel

@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Index</title>
</head>
<body>
    @using (Html.BeginForm())
    {
        @Html.AntiForgeryToken()

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

            <div class="form-group">
                @{ Html.RenderPartial("Partial1", Model);  }
                @{ Html.RenderPartial("Partial2", Model);  }
            </div>

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

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

Partial1.cshtml

@model TestApp.Models.MainModel

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

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

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

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

Partial2.cshtml

@model TestApp.Models.MainModel

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

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

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

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

MainController.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using TestApp.Models;

namespace TestApp.Controllers
{
    public class MainController : Controller
    {
        // GET: Main

        [HttpGet]
        public ActionResult Index()
        {
            return View();
        }

        [HttpPost]
        public ActionResult Index(MainModel mainModel)
        {
            //Access mainModel.PartialModel1.Pm1
            //Access mainModel.PartialModel2.Pm2 

            string msg = mainModel.PartialModel1.Pm1 + " " + mainModel.PartialModel2.Pm2;
            ViewBag.message = msg;


            return View("Success");
        }
    }
}

编辑2:如果我只保留它@{ Html.RenderPartial("Partial2"); } @{ Html.RenderPartial("Partial2"); } ,我得到这个错误- The model item passed into the dictionary is of type 'TestApp.Models.Main', but this dictionary requires a model item of type 'TestApp.Models.Partial2'.

MainController.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using TestApp.Models;

namespace TestApp.Controllers
{
    public class MainController : Controller
    {
        // GET: Main

        [HttpGet]
        public ActionResult Index()
        {
            return View(new Main() { Partial1 = new Partial1(), Partial2 = new Partial2() });

        }

        [HttpPost]
        public ActionResult Index(Main mainModel)
        {
            //Access mainModel.PartialModel1.Pm1
            //Access mainModel.PartialModel2.Pm2            

            string msg = mainModel.Partial1.Pm1 + " " + mainModel.Partial2.Pm2;
            ViewBag.message = msg;

            return View("Success");
        }
    }
}

Main.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace TestApp.Models
{
    public class Main
    {
        public int Mm1 { get; set; }
        public Partial1 Partial1 { get; set; }
        public Partial2 Partial2 { get; set; }
    }
}

Partial1.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace TestApp.Models
{
    public class Partial1
    {
        public Partial1()
        {
        }
        public int Pm1 { get; set; }
    }
}

Partial2.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace TestApp.Models
{
    public class Partial2
    {
        public Partial2()
        {
        }
        public int Pm2 { get; set; }
    }
}

Index.cshtml

@model TestApp.Models.Main

@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Index</title>
</head>
<body>
    @using (Html.BeginForm())
    {
        @Html.AntiForgeryToken()

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

            </div>

            @{ Html.RenderPartial("Partial2");  }
            @{ Html.RenderPartial("Partial1");  }

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

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

Partial1.cshtml

@model TestApp.Models.Partial1


@Html.AntiForgeryToken()

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


</div>


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

Partial2.cshtml

@model TestApp.Models.Partial2


@Html.AntiForgeryToken()

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


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

您可以更改代码:

public ActionResult Index(MainModelName model1, PartialModelName pmodel1)

public ActionResult Index(NewMainModelName  newModel)

在类NewMainModelName中,您可以像这样醒来:

   public class NewMainModelName
    {
        public MainModelName model1 { get; set; }
        public PartialModelName pmodel1{ get; set; }
    }

这里有一堆东西你应该改变。 对于初学者,您不需要使用正在使用的getter形式。

代替

private int pm1;
public int Pm1 { get => pm1; set => pm1 = value; }

您只需要具备以下功能:

public int Pm1 { get; set; }

您不需要私有后备变量。

如果要实际提供执行某些操作的方法,则只需要填充get和set方法即可。

其次,您需要实例化PartialModel的。 在这种情况下,这无关紧要,因为您不引用任何实际数据,仅引用元数据..但是,一旦添加实数据,它可能会引起问题。

[HttpGet]
public ActionResult Index()
{
    return View(new MainModel() { PartialModel1 = new PartialModel1(), PartialModel2 = new PartialModel2 });
}

接下来,我不确定您要如何完成此任务,但可能不是您认为的那样:

@using (Html.BeginForm("MainModel")) 

您在这里拥有的是嵌套表单,而这不是合法的HTML。

相反,您应该从部分表格中删除表单,即使这是合法的,然后表单也只会提交该表单中的数据。 这是您的主要问题。

另外,删除部分中的提交按钮。 只需在Index.cshtml中有一个总体表单并提交按钮即可。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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