【问题标题】:Why the only hidden field that is being filled from GET action is not being passed in model?为什么从 GET 操作中填充的唯一隐藏字段未在模型中传递?
【发布时间】:2012-12-07 04:00:14
【问题描述】:

对不起,标题太长了,我不知道如何使它更短。

  • 我的代码:

我的模特:

public class CarFilter {
    public String carMake { get; set; }
    public String carModel { get; set; }
    public String carEdition { get; set; }
    .
    .
    .
    public String SortBy { get; set; }
}

public class CarSearch : CarFilter {
    public List<Car> Car { get; set; }
}

我的控制器:

public ActionResult SearchResult(CarSearch search)
    {
        var cars = from d in db.Cars
                   select d;

        if (Request.HttpMethod == "POST")
        {
            search.SortBy = "Price";
        }
        search.Car = new List<Car>();
        search.Car.AddRange(cars);

        var temp = new List<CarSearch>();
        temp.Add(search);

        return View(temp);
}

我的索引视图(用户过滤结果的地方):

@model IEnumerable<Cars.Models.CarSearch>
@using (Html.BeginForm("SearchResult", "Home", FormMethod.Post)){..forms and other stuff..}

我的 SearchResult 视图(用户在其中看到过滤结果):

@model IEnumerable<Cars.Models.CarSearch>
@using (Html.BeginForm("SearchResult", "Home", FormMethod.Get))
{
@Html.Hidden("carMake")
@Html.Hidden("carModel")
@Html.Hidden("carEdition")
.
.
.
@Html.Hidden("SortBy")

<input name="SortBy" class="buttons" type="submit" value="Make"/>
  • 我的目标

我想要做的是,当用户点击排序方式时,它必须将隐藏字段中的所有变量返回到 SearchResult 操作,以便对结果进行排序(相同的过滤结果)。

  • 结果

是:&lt;input id="SortBy" name="SortBy" type="hidden" value=""/&gt;。该值为 null 并且没有被传递,但所有其他隐藏字段(例如 carMake 等)都有值。但是当我使用foreach 时,它可以完美运行。

  • 问题

为什么会这样? SortBy 与视图中的其他字段位于同一模型类中。唯一的区别是 SortBy 没有在 Index 视图中填充其他字段,而是在控制器操作中填充。对此有何解释?我是否缺少任何 C# 定义或诸如动态对象之类的东西?

【问题讨论】:

    标签: c# asp.net-mvc-3 model


    【解决方案1】:

    您没有将任何 html 元素绑定到模型中的任何内容,您只是告诉它创建具有特定名称的隐藏字段。

    不要使用@Html.Hidden("carMake") 试试@Html.HiddenFor(model =&gt; model.CarMake)

    现在,您还需要以某种方式将搜索设置发送到视图。 你在 ViewModel 上的继承让我有点失望。 我认为没有太多理由让CarSearch 继承自CarFilter 搜索真的是过滤器吗? 让动作SearchResult 接收CarFilter 并返回CarSearch 可能更清楚,其中CarSearch 可能是:

    public class CarSearch 
    {
        public CarFilter Filter { get; set; }
        public List<Car> Cars { get; set; }
    }
    

    动作看起来像:

    public ActionResult SearchResult(CarFilter filter)
    {
        ...
        return View(new CarSearch {Filter = filter, Cars = <your result>});
    }
    

    这样您的操作就更清楚地知道什么是输入和什么是输出。 使用该模型,您的隐藏字段将类似于:

    @Html.HiddenFor(model => model.Filter.CarMake)
    

    对于代表搜索结果的实际汽车,您可以使用@Html.DisplayFor() 执行foreach、局部视图或显示模板。 我可能会选择最后一个。

    注意:我更改了您的属性的大小写,因为您可能希望遵守 C# 命名约定。

    【讨论】:

    • 感谢您的回复巴勃罗·罗密欧。但是,关于问我为什么从CarFilter 继承。我试图不从 CarFilter 继承 CarSearch,但问题是当我将索引视图中的参数发布到我的 SearchResult 操作(无论是 CarFilter 还是 CarSearch)时,它只会将对象 CarSearch 本身和 CarFilter 中的所有值传递为 null .但是当我使用继承时,它工作得很好。
    • MVC 实际上不会传递任何特定的东西。它将创建您声明为参数的类型,并尝试使用请求中的任何信息填充它,查找与您的视图模型的属性名称匹配的字段。如果名称匹配,将设置属性。
    • 还有一件事。正如你提到的@Html.HiddenFor(model =&gt; model.CarMake),我不得不说@Html.Hidden("carMake") 确实有效。我提到的问题只是@Html.Hidden("SortBy", temp.SortBy)。这就是为什么它让我想知道为什么它会这样?因为它们都具有相同的条件,但唯一不同的是 SortBy 没有被索引视图传递,而是被填充到 SearchResult 操作本身中。再说一遍,我知道如何解决这个问题,但我不明白这背后的原因和理论和逻辑。
    • 也许我没有完全理解你认为的“temp”是什么。您可能只想在视图中仅使用视图模型中的内容。它使逻辑更加简单易懂。
    • 哦,我很抱歉,我认为 temp 在我的 foreach 中,我完全忘了删除它。对此我深表歉意。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-13
    • 2013-12-30
    相关资源
    最近更新 更多