gpt4 book ai didi

asp.net - 将多个模型从一个 View 传递到 Controller

转载 作者:行者123 更新时间:2023-12-02 03:36:08 24 4
gpt4 key购买 nike

如果我在谷歌上搜索“一个 View 中的多个模型”,我只能找到关于如何将模型传递给一个 View 的结果。但我对“从 View 到 Controller ”的方向感兴趣。

让我们假设:

  • 我在一个 View 中有 3 种不同的表单和 1 个表 (WebGrid)。
  • 我有一个模型用于每个表单和一个用于表格的模型。
  • 让我的模型类为 ModelF1ModelF2ModelF3ModelT

到目前为止我看到的所有示例都使用容器 ViewModel 之类的

class MyViewModel {
ModelF1 inst1,
ModelF2 inst2,
ModelF3 inst3,
ModelT instT
}

然后他们以两种方式在 View <-> Controller 之间传递它。

但我想在不使用 View 模型的情况下以这种方式捕捉我的模型:

class MyController {
ActionResult Index() {
return new View(modelF1Instance, modelF2Instance, modelF3Instance, modelTInstance);
}

ActionResult Form1Action(ModelF1 inst1, ModelT instT) {
// process models after a form1 submit
}

ActionResult Form2Action(ModelF2 inst2, ModelT instT) {
// process models after a form2 submit
}

ActionResult Form3Action(ModelF3 inst3, ModelT instT) {
// process models after a form3 submit
}
}

如果不解析 CustomBinder 中的整个表单元素,这是否可能?

最佳答案

首先,您只能使用以下方式将强类型 View 模型发送回您的 View

return View(model);

View 是基类上的一个方法,不是要用 return new View(...

实例化的类

那么对于您真正的问题:是的,您可以做到这一点,但是使用包含不同表单项的顶级 ViewModel 在大多数用例中要容易得多强>.顶级容器 ViewModel 处理得很好的主要问题是值持久化和服务器端验证以及往返之间的错误消息。

如果您只是担心创建顶级 ViewModel 容器会让人觉得效率低下,那就别担心。这比您可能必须采取的所有变通办法要有效得多,以便在没有顶级 ViewModel 的情况下使表单表现良好。

下面有一些示例代码。下面的代码应该证明使用包含在顶层 ViewModel 中的模型更简单、更整洁:一些表单故意不往返某些状态。请注意 HiddenForModelState.Clear 的用法,它们都与您尝试执行的操作相关,但即使是这些也不会保留 inst4 的值。 Form4Submit 的名称。探索的各种选项是:

  1. 使用查询参数来表示正在发布的表单
  2. 使用不同的表单名称,但仍使用 View 模型。
  3. 对表单使用仅重定向操作(发送新实例,并且仅发送部分 View 模型)
  4. 混合使用上述方法
public class TestController : Controller
{
//
// GET: /Test/
[System.Web.Mvc.HttpGet]
public ActionResult Index(string msg = null)
{
var model = new MyViewModel
{
Inst1 = new ModelF1 { Name = "Name of F1" },
Inst2 = new ModelF2 (),
InstT = new ModelT {Name = "Name of T"},
PostNumber = 0,
Message = msg
};
return View(model);
}

[System.Web.Mvc.HttpPost]
public ActionResult Index(MyViewModel model, int option = 1)
{
// process models after a form1/2 submit
model.Message = "You posted " +
((option == 1) ? model.Inst1.Name : model.Inst2.Name)
+ " to Index for "
+ ((option == 1) ? "inst1" : "inst2");
model.PostNumber ++;
// This, and the hiddenFor are required to allow us to update the PostNumber each time
ModelState.Clear();
return View(model);
}

[System.Web.Mvc.HttpPost]
public ActionResult Form2Submit(MyViewModel model)
{
// process models after a form2 submit
model.Message = "You posted " + model.Inst2.Name + " to Form2Submit";
model.PostNumber++;
ModelState.Clear();
return View("Index", model);
}

[System.Web.Mvc.HttpPost]
public ActionResult Form3Submit(ModelF3 inst3, ModelT instT)
{
// process models after a form3 submit
var n = instT.Name;
var msg = "You posted " + inst3.Name + ", " + n + " to Form3Submit";
// We no longer have access to pass information back to the view, so lets redirect
return RedirectToAction("Index", new { msg = msg });
}

[System.Web.Mvc.HttpPost]
public ActionResult Form4Submit(ModelF4 inst4, MyViewModel model)
{
// process models after a form4 submit
var n = model.InstT.Name;
model.Message = "You posted " + inst4.Name + ", " + n + " to Form4Submit";
model.PostNumber++;
ModelState.Clear();
return View("Index", model);
}

public class MyViewModel
{
public int PostNumber { get; set; }
public string Message { get; set; }
public ModelF1 Inst1 { get; set; }
public ModelF2 Inst2 { get; set; }
public ModelT InstT { get; set; }
}

public class ModelBase { public string Name { get; set; } }

public class ModelF1 : ModelBase {}
public class ModelF2 : ModelBase { }
public class ModelF3 : ModelBase { }
public class ModelF4 : ModelBase { }
public class ModelT : ModelBase { }
}

然后对于多表单 View :

@using MyWebSite.Controllers;
@model TestController.MyViewModel
@{
Layout = null;
}

<!DOCTYPE html>

<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
</head>
<body>
<p>
@Html.Raw(Model.PostNumber) : @Html.Raw(Model.Message)
</p>
<p>
@Html.LabelFor(m => Model.InstT) : <br />
@Html.DisplayFor(m => Model.InstT)
</p>
<div>
<p>Default form submit</p>
@using (Html.BeginForm())
{
<div>
@Html.HiddenFor(m => m.PostNumber)
@Html.LabelFor(m => Model.Inst1.Name)
@Html.TextBoxFor(m => Model.Inst1.Name)
</div>
<input type="submit" value="Submit Index" />
}
</div>
<div>
<p>Use a parameter to denote the form being posted</p>
@using (Html.BeginForm("Index", "Test", new { option = 2 }))
{
<div>
@* Omitting these will not persist them between trips
@Html.HiddenFor(m => Model.Inst1.Name)
@Html.HiddenFor(m => Model.InstT.Name)*@
@Html.HiddenFor(m => m.PostNumber)
@Html.LabelFor(m => Model.Inst2.Name)
@Html.TextBoxFor(m => Model.Inst2.Name)
</div>
<input type="submit" value="Submit with option parameter" />
}
</div>
<div>
<p>Use a different form name, but still use the ViewModel</p>
@using (Html.BeginForm("Form2Submit", "Test"))
{
<div>
@Html.HiddenFor(m => Model.Inst1.Name)
@Html.HiddenFor(m => Model.InstT.Name)
@Html.HiddenFor(m => m.PostNumber)
@Html.LabelFor(m => Model.Inst2.Name)
@Html.TextBoxFor(m => Model.Inst2.Name)
</div>
<input type="submit" value="Submit F2" />
}
</div>
<div>
<p>Submit with a redirect, and no ViewModel usage.</p>
@using (Html.BeginForm("Form3Submit", "Test"))
{
var inst3 = new TestController.ModelF3();
<div>
@Html.HiddenFor(m => Model.InstT.Name)
@Html.LabelFor(m => inst3.Name)
@Html.TextBoxFor(m => inst3.Name)
</div>
<input type="submit" value="Submit F3" />
}
</div>
<div>
<p>Submit with a new class, and the ViewModel as well.</p>
@using (Html.BeginForm("Form4Submit", "Test"))
{
var inst4 = new TestController.ModelF4();
<div>
@Html.HiddenFor(m => Model.Message)
@Html.HiddenFor(m => Model.PostNumber)
@Html.HiddenFor(m => Model.Inst1.Name)
@Html.HiddenFor(m => Model.Inst2.Name)
@Html.HiddenFor(m => Model.InstT.Name)
@Html.LabelFor(m => inst4.Name)
@Html.TextBoxFor(m => inst4.Name)
</div>
<input type="submit" value="Submit F4" />
}
</div>

</body>
</html>

关于asp.net - 将多个模型从一个 View 传递到 Controller ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23322416/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com