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 中的控制器操作

如何使用 Ajax 调用 MVC4 传递两个字符串数组

如何根据 asp.net mvc4 中的模型列表填充 ListBox?

将 Id 从一个控制器传递到另一个控制器

将模型从 jquery ajax 传递给控制器

API 控制器中的 MVC4 模型验证服务器端