【问题标题】:How can I emulate model binding behaviour when rendering an ActionLink?渲染 ActionLink 时如何模拟模型绑定行为?
【发布时间】:2011-08-05 03:19:06
【问题描述】:

在以下代码中,get 操作返回给定比赛日期的投注卡,我使用 post 操作将绑定模型的属性转换为 的路由值>获取行动。

详细信息视图的基本方面:

@using (Html.BeginForm("Upload", "BettingCard",
                         FormMethod.Post, new { id = "uploadForm", enctype = "multipart/form-data" }))
{ 
    @Html.ValidationSummary(true, "The upload was unsuccessful.  The following error(s) occurred: ")
    <div id="date-selector">
        <div id="ymd">
            @Html.LabelFor(model => model.RaceDate)
            @Html.DropDownListFor(model => model.RaceDay, Model.YmdLists.Days)
            &nbsp; @Html.DropDownListFor(model => model.RaceMonth, Model.YmdLists.Months)
            &nbsp; @Html.DropDownListFor(model => model.RaceYear, Model.YmdLists.Years)
            &nbsp;&nbsp;<input type="submit" value="Upload for this date" />
        </div>
    </div>
    @Html.Telerik().Upload().Name("UploadedFiles")
}

控制器代码的基本方面:

[HttpGet]
public ActionResult Details(int year, int month, int day) {
    var model = new BettingCardModel
                    {
                        ResultMessage = "No betting card was located for the selected date."
                    };
    DateTime passedDate;
    if (!DateTimeHelper.TrySetDmy(year, month, day, out passedDate)) {         
        ModelState.AddModelError("", "One or more values do not represent a valid date.");
        return View(model);
    }
    model.RaceDate = passedDate;
    var bettingCard = _bettingCardService.GetByRaceDate(passedDate);
    model.MapFromEntity(bettingCard);
    return View(model);
}

[HttpPost]
public ActionResult Details(BettingCardModel model)
{
    return RedirectToAction("Details", new { year = model.RaceYear, month = model.RaceMonth, day = model.RaceDay });
}

上面的大部分代码都是实验性的和诊断性的,所以我想避免对有效的代码进行审查,而是专注于我需要实现的目标。在Details 视图中,我只需要一个“命令”,即“显示日期”,因此我使用提交按钮轻松下车,http 帖子负责模型绑定。但是,在Upload 视图中,我需要两个命令,即“显示日期”和“上传日期”,所以我想让“显示日期”严格使用 get 操作,并且仅使用 post 操作来提交上传的当日投注卡。

我的问题是,当我使用“显示日期”命令使用 ActionLink 而不是提交,使用model.RaceDay 等作为路由值时,传递给Details 的 URL 参数仍然包含它们的初始值,不是用户在下拉列表中设置的值。似乎没有为动作链接调用模型绑定代码(无论可能是什么)。我可以在这里做些什么来避免需要一个帖子来进行绑定?

我意识到这可能不是直接的模型绑定问题,但我不知道如何表达我的问题。当渲染“绑定”到模型属性的元素时,它们比简单的输入和一些基本的样式更多,但是围绕该输入“构建”了一些包含大量元数据的东西。当点击页面上的 get 链接时,我想通过某种方式使用该元数据映射到 URL。

【问题讨论】:

    标签: asp.net-mvc asp.net-mvc-3 model-binding


    【解决方案1】:

    您遇到的问题是所有模型数据和元数据都是在服务器上动态生成的,并作为静态内容提供给客户端。绑定仅在将模型提交到服务器后才知道模型的更改。所有模型元数据在客户端都是静态的,使用纯 .NET 将无法知道用户何时更改下拉列表中的值以更改静态锚标记中的值,这就是 ActionLink呈现给。答案是使用javascript。有很多方法可以通过 javascript 完成您尝试做的事情。您可能会编写一个自定义 HtmlHelper 类来为您生成 javascript。但是,如果您不想使用 javascript,那么您将不得不发布一个帖子以将用户选择的数据发送到服务器。

    如果您想避免重新编写代码,那么您可以为表单的内容创建一个局部视图并将其嵌入到两个单独的视图中。您可以尝试的另一件事是通过两个具有相同名称的提交按钮来检测哪个按钮被按下,如下所示:

        <input type="submit" name="command" value="Update" />
        <input type="submit" name="command" value="Display" />
    

    然后在您的控制器中的 [HttpPost] 操作中,您可以检测到哪个是通过 Request.Forms 推送的,如下所示:

    [HttpPost]
    public ActionResult Details(BettingCardModel model)
    {
        if (Request.Forms["command"].Equals("Display"))
        {
            return RedirectToAction("Details", new { year = model.RaceYear, month = model.RaceMonth, day = model.RaceDay });
        }
    
        // Do your update code here...
        return // Whatever it is you return for update.
    }
    

    希望这对您有所帮助。

    【讨论】:

    • 您也可以拥有public ActionResult Details(BettingCardModel model, string command),然后像if (command == "Display") 一样进行测试。使您的控制器更具可测试性。
    猜你喜欢
    • 1970-01-01
    • 2013-05-26
    • 2016-06-09
    • 2011-02-07
    • 1970-01-01
    • 2010-11-18
    • 1970-01-01
    • 2014-01-02
    • 1970-01-01
    相关资源
    最近更新 更多