MVC4 不会将模型传递给控制器
Posted
技术标签:
【中文标题】MVC4 不会将模型传递给控制器【英文标题】:MVC4 won't pass Model to Controller 【发布时间】:2014-10-08 08:20:06 【问题描述】:我正在尝试将 C# 对象作为参数传递回控制器。这样做是这样的:
@model Models.AdvancedSearchTerms
@
ViewBag.Title = "Loading";
@html.DisplayFor(Model => Model.Keyword)
@using (Html.BeginForm("MetaSearch", "AdvancedSearch", new term = Model , FormMethod.Post))
<input id="startGatheringData" type="Submit" name="Convert" />
如您所见,如果按下按钮,我会尝试将整个模型发送回控制器。但是当控制器中的方法获取模型时,它是空的。为了确保视图中的模型不为空,您可以看到我尝试使用@Html.DisplayFor 打印变量,并且它有效。所以模型在视图中不是空的,但是当我将它传递给控制器时它消失了:
public ActionResult MetaSearch(AdvancedSearchTerms term)
//Do stuff with the model retrived from the View()
return View()
有人知道为什么这个对象是空的吗?我已经做了很多,不知道为什么这次它不起作用。我也尝试只传递一个变量,但这也是 Null。
提前谢谢!
【问题讨论】:
【参考方案1】:向控制器发送单个值
我实际上只是在我的表单中创建了一个“搜索”/过滤选项;使用类似的东西:
查看
@using (Html.BeginForm())
<div>
<hr />
Search
<hr />
Name: @Html.TextBox("SearchString", null, new @id = "thisID" )<a style="float:right; margin-top:8px" href="@Url.Action("Index", "ControllerName")">
<br />
<input type="submit" value="Filter" id="subBtn" />
<hr />
</div>
我的控制器代码是:
[Authorize]
public ActionResult Index()
return View(db.Traders.ToList());
[HttpPost]
public ActionResult Index(string searchString)
var traders = from m in db.Traders //db is my Database Entities
select m;
if (!String.IsNullOrEmpty(searchString))
traders = traders.Where(s => s.Name.Contains(searchString));
return View(traders);
所以我的控制器将接收这个 textBox 值作为方法的一部分。
使用搜索和/或组合框(两者或一个或无)过滤
我实际上使用this site 为我的项目实现了一个基本的搜索/过滤系统。它帮助很大。
它使用ViewBag
允许您创建一个组合框,然后您可以选择该组合框并将所选值返回给您的 [HttpPost] 操作方法 - 非常适合您的过滤/搜索需求!
这意味着您无需将完整的模型发送回您的控制器,而是传递一个“搜索词”,然后您可以在控制器方法中使用它 - 并在您的方法中轻松获取匹配的模型(类似于发送单个值与第一个示例相同)。
您的操作方法可能如下所示:
public ActionResult Index(string movieGenre, string searchString)
var GenreLst = new List<string>();
var GenreQry = from d in db.Movies
orderby d.Genre
select d.Genre;
GenreLst.AddRange(GenreQry.Distinct());
ViewBag.movieGenre = new SelectList(GenreLst);
var movies = from m in db.Movies
select m;
if (!String.IsNullOrEmpty(searchString))
movies = movies.Where(s => s.Title.Contains(searchString));
if (!string.IsNullOrEmpty(movieGenre))
movies = movies.Where(x => x.Genre == movieGenre);
return View(movies); //returns movies matching results
向控制器发送完整模型
在传递完整控制器的帮助方面,您可能会发现this tutorial 很有帮助,因为它创建了基本的 CRUD 操作(“创建”允许您将单个模型传递给控制器)。
在“PostBack”操作方法中,您需要“绑定”数据,例如:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "LastName, FirstMidName, EnrollmentDate")]Student student)
//do stuff with this model
return redirectToAction("Index");
这在上面的链接中有进一步的解释。
【讨论】:
似乎非常适合 OP 问题 :) 这和问题有什么关系? OP 正在实施一种搜索工具(无论如何,来自变量名)。此外,它显示/教导 OP 如何将数据从 View 传递到控制器,无论所有字段是否完整(否则您的模型可能需要更改以允许 NULL 值);) 我建议你再读一遍这个问题。 OP 正在尝试通过路由参数传递整个模型 - 不涉及文本框或“搜索/过滤器” 嘿,谢谢!非常有趣的代码和您的宝贵反馈!我可以在我当前的项目中使用很多这样的东西。我寻求 Ehsan Sajjad 的答案作为临时解决方案!但是感谢您的帮助!我可能会尽快将其更改为更有效的方式!【参考方案2】:您必须在表单中为此创建输入字段,如果您不想向用户显示它们,请使用隐藏字段:
@using (Html.BeginForm("MetaSearch", "AdvancedSearch", FormMethod.Post))
@Html.HiddenFor(x=>x.SomeProperty)
@Html.HiddenFor(x=>x.SomeProperty)
<input id="startGatheringData" type="Submit" name="Convert" />
【讨论】:
啊,我很害怕。我只是希望这是一个更简单的出路:)我会在一段时间内尝试一下,然后接受这个答案,如果它有效!谢谢! 是的,它有效,我现在将使用它。我可能会尽快将其更改为更有效的方式,但因为我只需要快速修复!感谢您的帮助!【参考方案3】:如果您想再次在控制器中使用来自视图的信息,请确保将操作设为 httppost 操作
像这样:
[HttpPost]
public ActionResult MetaSearch(AdvancedSearchTerms term)
//LOGIC
【讨论】:
谢谢,但它在那里。我刚刚在提供的代码中出于某种原因删除了它【参考方案4】:如果您的模型仅包含简单属性(没有集合或复杂对象),则可以这样做
@using (Html.BeginForm("MetaSearch", "AdvancedSearch", Model, FormMethod.Post, null))
但是你为什么要这样做。通过在它生成的查询字符串中回发大量值,您只会降低性能。最好只发回模型的唯一 ID 并从控制器中的数据库中再次获取模型。
编辑
另外,模型不能包含与路由参数同名的属性。例如,如果您使用url: "controller/action/id",
定义了一个路由,则模型不能包含名为ID
的属性。
【讨论】:
以上是关于MVC4 不会将模型传递给控制器的主要内容,如果未能解决你的问题,请参考以下文章
将复选框的值传递给 asp.net mvc4 中的控制器操作