【问题标题】:How to map values from a database to a view model in MVC 4如何将值从数据库映射到 MVC 4 中的视图模型
【发布时间】:2013-03-23 06:02:31
【问题描述】:

我在完成一项非常简单的任务时遇到了麻烦。我正在尝试将从数据库检索到的值映射到视图模型。然后我想将它作为模型传递给我的视图。

视图模型称为 EditAdminModelVM,它包含来自称为 UserProfile 的较大类的属性的较小子集。我选择使用视图模型是因为我不希望用户能够更新整个域模型,而只更新其中的一部分。

这是视图模型:

public class EditAdminModelVM
{
    [Required]
    [StringLength(50, ErrorMessage = "The {0} must be at least {2} characters long.")]
    [Display(Name = "First name")]
    public string FirstName { get; set; }

    [Required]
    [StringLength(50, ErrorMessage = "The {0} must be at least {2} characters long.")]
    [Display(Name = "Last name")]
    public string LastName { get; set; }

    [Required]
    [MaxLength(250)]
    [EmailAddress]
    public string Email { get; set; }

    [Required]
    //[Remote("doesUserNameExist", "Account", HttpMethod = "POST", ErrorMessage = "Username already exists. Please enter a different User Name.")] //note this checks from client-side only - server side check is built in to membership
    [Display(Name = "Username")]
    public string UserName { get; set; }

    [HiddenInput]
    public int UserId { get; set; }
}

这是控制器9,虽然它不起作用):

[Authorize(Roles = "Admin")]
    public ActionResult EditAdmin(int id = 0)
    {
        PpDB db = new PpDB();

        var viewModel = new EditAdminModelVM();

        viewModel = db.UserProfiles
             .Where(x => x.UserId == id)
             .Select(x => new EditAdminModelVM
             {
                 FirstName = x.FirstName,
                 LastName = x.LastName,
                 Email = x.Email,
                 UserName = x.UserName
             });

        return View(viewModel);
    }

在这种情况下,.Select 带有下划线,带有一个波浪线,它说明了 IQueryable 的一些内容。但是如果我尝试设置 var viewModel = new IQueryable;我收到另一个错误。

我想这可能是语法问题。这个数据库查询应该只返回一行,所以我认为 IQueryable 没有必要,但我不是专家。

如果您可以为我提供如何构建此代码块的工作示例,那么我可以通过示例学习 - 对我疲惫的大脑更好。

非常感谢!

肯更新 这是更新后的控制器:

 [Authorize(Roles = "Admin")]
    public ActionResult EditAdmin(int id = 0)
    {
        PpDB db = new PpDB();

        List<EditAdminModelVM> viewModel = new List<EditAdminModelVM>();

        viewModel = db.UserProfiles
             .Where(x => x.UserId == id)
             .Select(x => new EditAdminModelVM
             {
                 FirstName = x.FirstName,
                 LastName = x.LastName,
                 Email = x.Email,
                 UserName = x.UserName,
                 UserId = x.UserId
             }).ToList();

        return View(viewModel);
    }

这是视图:

@model List<PpModels.Models.EditAdminModelVM>


@{
    ViewBag.Title = "Edit Admin";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

@using (Html.BeginForm()) {
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)

<fieldset>
    <legend>UserProfile</legend>

    @Html.HiddenFor(model => model.UserId)

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

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

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

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

    <p>
        <input type="submit" value="Save" />
    </p>
</fieldset>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

【问题讨论】:

  • 您不需要将值重新分配给模型。您将在 ActionResult Method 参数中获得模型值。只需将这些模型值分配给 db 对象并编写代码来更新您的表。

标签: asp.net-mvc orm viewmodel


【解决方案1】:

var viewModel = new EditAdminModelVM(); 更改为List&lt;EditAdminModelVM&gt; viewModel = new List&lt;EditAdminModelVM&gt;(); 并将ToList() 附加到db.UserProfiles 查询的末尾。现在,这个将 EditAdminModelVM 的集合传递给您的视图。在您的视图中遍历此集合以获得所需的输出。

更新:对于单个实例:

[Authorize(Roles = "Admin")]
public ActionResult EditAdmin(int id = 0)
{
    PpDB db = new PpDB();

    var viewModel = new EditAdminModelVM();

    viewModel = db.UserProfiles
         .Where(x => x.UserId == id)
         .Select(x => new EditAdminModelVM
         {
             FirstName = x.FirstName,
             LastName = x.LastName,
             Email = x.Email,
             UserName = x.UserName
         }).FirstOrDefault();

    return View(viewModel);
}

为此,您无需在视图中进行迭代:

在您的视图中使用@model ProofPixModels.Models.EditAdminModelVM

【讨论】:

  • 非常感谢!我试过了,现在在我的视图中得到以下错误:传递到字典的模型项的类型是“System.Data.Entity.Infrastructure.DbQuery`1[PpModels.Models.EditAdminModelVM]”,但是这个字典需要一个模型'PpModels.Models.EditAdminModelVM' 类型的项目。这是视图顶部的声明:@model PpModels.Models.EditAdminModelVM。有什么想法吗?
  • 好的。我通过声明以下内容来解决该错误:@model IEnumerable 在我的视图顶部。然后,我将表单字段包装在 foreach 循环中。由于这个视图应该只显示视图模型的一个实例,我可能还会以错误的方式解决这个问题吗?将其包装在 foreach 循环中似乎违反直觉?感谢您的帮助!
  • 在您看来,使用@model List&lt;EditAdminModelVM&gt;() 作为您的模型
  • 谢谢。我现在在加载视图时收到以下错误:编译错误:System.Collections.Generic.List'不包含'UserId'的定义,并且没有扩展方法'UserId'接受第一个参数'System.Collections.Generic.List 类型
  • 请更新您的控制器方法并在原始问题中显示您在做什么。所以,我可以查看和纠正。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-22
  • 2019-05-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多