【问题标题】:Passing Querystring value into View Model将查询字符串值传递到视图模型
【发布时间】:2012-05-25 05:42:06
【问题描述】:

我有一个父子情况,例如我的用户类和我的用户工作子类(实体框架脚手架类)。我使用控制器向导来搭建 CRUD 方法和视图。它构建了两个 Create 方法,Get 和 httpPost 方法。

在正常情况下,我希望将用户的 id 传递到 get 中,以便将其传递到填充在 html.beginform() 部分中的模型中,然后将其传递到 post 中。

我不确定执行此操作的正确方法是什么?我已将 Get 修改如下

public ActionResult Create(int id)
 {
     this.ViewData.Add("id", id);
     return View();
 }

和下面的 Create.shtml

@model UserWork

@{
    ViewBag.Title = "Create";
    int id = (int)ViewData["id"];
}

<h2>Create</h2>
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")"></script>

@using (Html.BeginForm(routeValues:new {user_id = @id})) {
    @Html.ValidationSummary(true)

    <fieldset>
        <legend>Userwork</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.user_id)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.user_id)
            @Html.ValidationMessageFor(model => model.user_id)
        </div>
......

(我将脚手架的 user_id 字段保留为可编辑,因此我可以测试在表单加载时看到它们预填充)表单加载的字段中没有我的 id 值,这是实现此目的的正确方法吗?

干杯 蒂姆

【问题讨论】:

    标签: asp.net-mvc-3 razor asp.net-mvc-routing


    【解决方案1】:

    在 ViewData 中传递 Id 很好,但我会改用 ViewBag,因为您使用的是 MVC3。它基本上是一个基于动态的 ViewData 包装器,无需强制转换

    控制器:

    this.ViewBag.UserId = userId;
    

    然后您可以在视图中以ViewBag.UserId 的身份访问 ViewBag 属性

    【讨论】:

    • 好的,我将其更改为使用 viewbag,但为什么它没有填充到模型中,因此当我在文本框中看到页面时可见?
    【解决方案2】:

    您没有将任何模型传递给您的视图。这对我来说是错误的。您的视图被强类型化为 UserWork 模型,因此控制器操作通常应该将该模型的实例传递给视图,而不是使用任何 ViewData 或 ViewBag:

    public ActionResult Create(int id)
    {
        var model = new UserWork();
        model.user_id = id;
        return View(model);
    }
    

    在视图中:

    @model UserWork
    
    @{
        ViewBag.Title = "Create";
    }
    
    <h2>Create</h2>
    <script src="@Url.Content("~/Scripts/jquery.validate.min.js")"></script>
    <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")"></script>
    
    @using (Html.BeginForm() {
        @Html.ValidationSummary(true)
    
        <fieldset>
            <legend>Userwork</legend>
    
            <div class="editor-label">
                @Html.LabelFor(model => model.user_id)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.user_id)
                @Html.ValidationMessageFor(model => model.user_id)
            </div>
    ......
    

    还请注意,在Html.BeginForm 中,您不需要重新传递user_id,因为您在表单中具有该字段的相应编辑器模板。但通常不应该有文本输入字段,以便用户可以修改正在编辑的实体的 id。在这种情况下,您可以使用路线数据或隐藏字段。

    【讨论】:

    • 如果我调试它,我可以看到模型为空。但是在 httppost create 方法中,即使我已经指定 user_id 字段应该设置为这个值,它们也有额外的值,当我检查 httppost 中的对象时,我可以看到 id 字段有这个值。我的 id 字段是这个用户工作表的主键,外键是 user_id,虽然我在路由中指定了值,但没有传入。
    • 如果我按照您的建议删除更改,user_id 仍然正确存在于接收到 get 的模型中,因此在我调试它时出现在 httppost Create 中,但奇怪的是我传入的 id 值page 也出现在 id 列中。我将删除用于编辑这些主键和外键值的文本字段,但它们仅用于测试。我最初确实将我的 get 指定为 public ActionResult Create(int user_id) {} 但路由没有找到这个值。如果我想在路由中填充不同的命名参数,是否需要添加不同的路由?
    【解决方案3】:

    所以我最初的问题提出了其他几个关于我对 MVC 和路由的理解的问题。我确定如果我将一个参数作为整数传递给表单中的路由

    http://mydomain/controller/myaction/123 
    

    如果我的操作方法在表单中

    public ActionResult Create(int id)
            {}
    

    一切都很酷,但如果是形式

     public ActionResult Create(int user_id)
            {}
    

    然后我得到一个异常,即未填充所需的参数 user_id。 我添加了一个额外的映射,如下所示,这似乎正确地填充了视图。

    routes.MapRoute("Create", "{controller}/Create/{user_id}",new {action = "Create"});
    

    我决定不实例化模型并将其传递到视图中,因为使用上面的路由将用户 ID 正确地传递到模型的 user_id 字段中。

    干杯 蒂姆

    【讨论】:

      【解决方案4】:

      我在父->子关系方面遇到了同样类型的问题。但我通过创建以下路线解决了这个问题:

      routes.MapRoute(
                      "route_name",
                      "Parents/{parent_id}/{controller}/{action}/{id}",
                      new { action = "list", id = UrlParameter.Optional },
                      new { parent_id= @"\d+" }
                  );
      

      在你的情况下它会变成-

      routes.MapRoute(
                      "User_Route",
                      "Users/{user_id}/{controller}/{action}/{id}",
                      new { action = "list", id = UrlParameter.Optional },
                      new { user_id= @"\d+" }
                  );
      

      和 UserWorke 的示例 url-

      (siteurl)/Users/1/UserWork/list
      (siteurl)/Users/1/UserWork/New
      (siteurl)/Users/1/UserWork/Edit/1
      

      等等……

      通过这条路线,它可以轻松地从一个动作导航到另一个动作,因为您不需要在重定向时一次又一次地传递 user_id。并在 URL 中清晰地显示您正在导航的内容。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-05-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多