MVC4赢得';t将模型传递给控制器

本文关键字:模型 控制器 赢得 MVC4 | 更新日期: 2023-09-27 18:25:51

我正试图将一个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" />
}

正如你所看到的,如果按下按钮,我会尝试将整个模型发送回控制器。但是当控制器中的方法获取Model时,它为null。为了确保视图中的模型不为空,您可以看到我已经尝试使用@Html.DisplayFor打印变量,并且它有效。因此,模型在视图中不是空的,而是当我将其传递给控制器时消失:

 public ActionResult MetaSearch(AdvancedSearchTerms term)
    {
       //Do stuff with the model retrived from the View() 
        return View() 
    }

有人知道为什么这个物体是空的吗?我已经做了很多,不知道为什么这次不起作用。我也尝试过只传递一个变量,但这也是Null。

提前,谢谢!

MVC4赢得';t将模型传递给控制器


向控制器发送单个值


我只是在表单中创建了一个"搜索"/筛选选项;使用类似的东西

查看

@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值作为方法的一部分。


使用搜索和/或组合框进行筛选(两者都有或一个或无)


实际上,我使用这个网站为我的项目实现了一个基本的搜索/过滤系统。它帮了很多忙。

它使用ViewBag来允许您创建一个comboBox,然后您可以选择该comboBox并将所选值返回给您的[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
} 

向控制器发送完整模型


关于传递完整控制器的帮助,您可能会发现本教程很有帮助,因为它创建了基本的CRUD操作("创建"允许您将单个模型传递给控制器)。

在"PostBack"Action方法中,您需要"绑定"数据,如:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "LastName, FirstMidName, EnrollmentDate")]Student student)
{
//do stuff with this model
return redirectToAction("Index");
}

这将在上面的链接中进一步解释。

如果您不想使用隐藏字段显示给用户,则必须在表单中为此创建输入字段:

@using (Html.BeginForm("MetaSearch", "AdvancedSearch", FormMethod.Post))
{ 
    @Html.HiddenFor(x=>x.SomeProperty)
    @Html.HiddenFor(x=>x.SomeProperty)
    <input id="startGatheringData" type="Submit" name="Convert" />
}

如果您想再次使用控制器中视图中的信息,请确保将该操作设置为httppost操作

像这样:

[HttpPost]
public ActionResult MetaSearch(AdvancedSearchTerms term)
{
//LOGIC
}

如果您的模型只包含简单的属性(没有集合或复杂的对象),则可以做到这一点

@using (Html.BeginForm("MetaSearch", "AdvancedSearch", Model, FormMethod.Post, null))

但是你为什么要这么做。您只是通过在它生成的查询字符串中返回大量值来降低性能。最好只是发布回模型的唯一ID,然后从控制器中的数据库中再次获取模型。

编辑

此外,模型中不能包含与管线参数同名的特性。例如,如果使用url: "{controller}/{action}/{id}",定义了路线,则模型不能包含名为ID的特性。