0

我有一个 mvc4 项目的问题。

我尝试将一些文本从视图发送到控制器,然后将其添加到模型中,然后尝试在另一个视图中检索文本。

第一个视图代码如下所示:

@{
    Html.BeginForm("Result", "Search", "test");
}

<div>
</div>

控制器代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using TheLibrary.Models;

namespace TheLibrary.Controllers
{
    public class SearchController : Controller
    {
        public ActionResult Result(string text)
        {
            var searchCriteria = new Search { searchCriteria = text };

            ViewBag.Search = searchCriteria;
            ViewData["ViewSearch"] = searchCriteria;
            TempData["TempSearch"] = searchCriteria;
            return View();
        }
    }
}

我的模型代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace TheLibrary.Models
{
    public class Search
    {
        public string searchCriteria { get; set; }
    }
}

第二个视图代码:

@Model TheLibrary.Models.Search
@{
    var text = (ViewBag.Search as TheLibrary.Models.Search).searchCriteria;
}

<div>
    @text
</div>

我得到的结果是“TheLibrary.Models.Search”而不是预期的“测试”。

我究竟做错了什么?

4

2 回答 2

1

恕我直言,您确实需要学习一些 MVC 教程。我通常不喜欢 Microsoft 文档(尤其是他们乏味的“快速入门”),但他们的MVC 教程实际上相当不错。话虽如此,让我为你澄清一些事情。

首先,创建视图模型(Search在这种情况下)的全部目的是让您不必使用ViewBagor ViewData,为您提供访问模型数据的有保证的方式。 ViewBagViewData几乎是一回事。不过这里的主要观点是摆脱这些,转而使用强类型视图。

那么,这就引出了一个问题,什么强类型视图?简而言之,强类型视图是需要将特定类型传递给它的视图。@model您可以使用视图顶部的指令指定强类型视图。在您的情况下,这将是:

@model TheLibrary.Models.Search

注意:小写的m. 不要将此与访问强类型模型 @Model的一种方式相混淆。

当我们准确地告诉我们的视图我们将传递给它什么类型时,我们可以使用它@Model来访问模型的属性,如下所示:

<div>
    @Model.searchCriteria
</div>

(另请注意,指南建议对属性使用Pascal Case。)

现在,让我们用你的控制器来解决这个问题。首先,由于我们已经在使用我们的模型,如上所述,使用ViewBagor没有意义ViewDataTempData用于完全不同的目的,与您的问题无关。(请参阅此答案以了解您何时可能想要使用它。)从这个意义上说,它也不是必需的。最后,您只需将模型传递给视图本身:

public ActionResult Result(string text)
{
    var model = new Search { searchCriteria = text };

    return View(model);
}

现在,您的完整视图将如下所示:

@model TheLibrary.Models.Search

<div>
    @Model.searchCriteria
</div>

但是,正如本答案开头所述,我真的认为您应该查看一些教程,因为这里有些事情您仍然不知道(例如searchCriteria直接传递给您的视图而无需任何验证)。

根据评论更新

您的视图希望看起来像这样:

@using (Html.BeginForm("Result", "Search", FormMethod.Get))
{
    @Html.TextBox("text")
    <input type="submit" value='Search' />
}

有几点需要注意。

首先,FormMethod.Get确保此表单的数据通过 GET 而不是 POST 发送。这就是放入text结果 URL 中的查询字符串的内容。所以它看起来像:

http://somewebsite.com/Search/Result?text=test

这很好,因为这意味着如果用户刷新页面,他们不会被要求重新提交表单,并且每次从该 URL 访问页面时它也会以相同的方式进行操作。

其次,@Html.TextBox("text")。您提供给该TextBox()方法的字符串是该文本框的名称,也是用于在该文本框中查找数据的名称。这意味着它必须与您的Result操作(或模型的一部分,但现在让我们保持简单)中的参数名称相匹配,因此这部分对于它正常工作很重要。

searchCriteria因此,这里的想法是,使用您的示例,您可以在视图中获取正确的数据Result,即用户将test在文本框中键入。然后,他们会单击Search让 MVC 调用该Result操作的按钮。这样做时,它将使用所谓的“模型绑定”将text文本框的值与text您的操作中的参数相匹配。这意味着当我们到达这里时:

public ActionResult Result(string text)
{
    // ...
}

text将具有某人在文本框中键入的任何内容的值。然后你将它传递给你的模型,然后传递给视图。

于 2013-11-07T17:38:33.523 回答
1

@Model 不应大写。然后你可以写:

@model TheLibrary.Models.Search
<div>
    @Model.SearchCriteria
</div>

需要明确的是,在声明类型时,第一个 @model 不应大写。之后,您将其大写以引用它。

另外我不确定您为什么使用 ViewBag 而不仅仅是将模型传递给视图。

return View(search);

另外我不推荐这种命名方案:

var searchCriteria = new Search{ searchCriteria = text };

因为你已经写了searchCriteria.searchCriteria。而是称它为:

var search = new Search...
于 2013-11-07T17:27:38.917 回答