MVC4不会将Model传递给Controller

时间:2014-10-08 08:20:07

标签: c# html asp.net-mvc-4 view model

我试图将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。为确保View中的Model不为空,您可以看到我尝试使用@ Html.DisplayFor打印变量,它可以正常工作。因此,模型在视图中不为空,但在将其传递给控制器​​时消失:

 public ActionResult MetaSearch(AdvancedSearchTerms term)
    {

       //Do stuff with the model retrived from the View() 
        return View() 
    }

任何人都知道为什么这个对象是空的?我已经做了很多,并且不知道为什么这次不工作。我也尝试过只传递一个变量,但这也是空的。

事先,谢谢!

4 个答案:

答案 0 :(得分:1)


向控制器发送单个值


我真的只是在我的表单中创建了一个搜索&#39; /过滤器选项;使用类似的东西:

查看

@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操作(&#39;创建&#39;允许您传递单个模型到控制器)。

在&#39; PostBack&#39;动作方法,你需要绑定&#39;数据,如:

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

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

答案 1 :(得分:0)

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

@using (Html.BeginForm("MetaSearch", "AdvancedSearch", FormMethod.Post))
{ 
    @Html.HiddenFor(x=>x.SomeProperty)
    @Html.HiddenFor(x=>x.SomeProperty)

    <input id="startGatheringData" type="Submit" name="Convert" />
}

答案 2 :(得分:0)

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

像这样:

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

答案 3 :(得分:0)

如果模型只包含简单属性(没有集合或复杂对象),则可以执行此操作

@using (Html.BeginForm("MetaSearch", "AdvancedSearch", Model, FormMethod.Post, null))
但是你为什么要这样做呢?通过在它生成的查询字符串中回发大量值来降低性能。最好只回发模型的唯一ID,然后再从控制器中的数据库中获取模型。

修改

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