【问题标题】:MVC3 default membership properties with custom model properties in view (use ModelView?)视图中具有自定义模型属性的 MVC3 默认成员属性(使用 ModelView?)
【发布时间】:2012-10-22 00:30:20
【问题描述】:

我已经开始学习 MVC3 开发并且遇到了一些绊脚石。在我的项目中,我将默认的 aspnet_ 成员表移到了单独的 SQL Server 2008 Express 数据库中。然后我添加了自己的表格来保存额外的配置文件数据。我现在想构建一个视图,其中将列出用户名(来自 aspnet_Users)、电子邮件地址(来自 aspnet_Membership)、名字和姓氏(来自自定义构建的表 UserDetails,用户 ID 为 PK 和 FK 到 aspnet_Users)以及用户的角色( aspnet_UsersInRoles 和 aspnet_Roles)。

到目前为止,为了从我的数据库中读取和写入,我已经为每个自定义构建的表构建了模型,其中包含一个 dbcontext 类:

    public class UserDetail
{

    [Key]
    public Guid UserId { get; set; }

    public string FirstName { get; set; }

    public string LastName { get; set; }

    public string Address { get; set; }

    public string City { get; set; }

    public string State { get; set; }

    public string Zip { get; set; }

    public string Phone { get; set; }

    public DateTime DateUpdated { get; set; }
}

public class UserLinkToken
{
    [Key]
    public Guid UserId { get; set; }

    public string LinkToken { get; set; }

    public DateTime DateUpdated { get; set; }
}

public class ProShotDB : DbContext
{
    public DbSet<UserDetail> UserDetails { get; set; }
    public DbSet<UserLinkToken> UserLinkTokens { get; set; }
}

当模型和 dbcontext 的名称与我的数据库和应用程序最终创建的表名称不匹配时,我必须为我的应用程序命名我的表“UserDetails”和“UserLinkTokens”来编写和更新我的数据库另一个带有表的数据库并在那里写入数据。

据我所知,发送一个对象以查看 aspnet_ 表中的属性和我的自定义表中的属性,我将想要构建一个 ModelView。在阅读了大量模型视图示例后,我仍然不清楚它应该如何查找我的应用程序。

谁能给我一个模型视图的示例,我可以使用它来显示数据行列表并更新模型视图中给定用户 ID 引用的所有相应表列?

例如,假设我只想查看所有 FirstNames(UserDetails 表)及其对应的电子邮件(aspnet_Membership)。

我的最终目标是一个视图,该视图将显示具有分配角色的用户。列出的每个用户都有一个链接,该链接将指向一个控制器,如果他们当前不属于该角色,该控制器会将他们分配为管理员,如果他们当前是管理员,则删除管理员角色。

抱歉,如果此类问题之前已在其他问题中回答过。我读过不少,觉得他们应该回答了我的问题,但似乎没有一个完全匹配。很可能我的困惑源于没有完全理解我的应用程序是如何连接到我的数据库的。我有点理解我的模型代表表的一行数据,dbcontext 采用一组这些数据行模型并将其连接到数据库中的表 (dbset (table of datarows /一组模型对象))。由于我没有看到 aspnet_ 表/模型对象的 dbcontext 类,因此我对如何检索、更新或写入这些表中的数据没有很好的概念。

感谢任何帮助消除我对它如何工作的无知或给我一个如何完成我需要的简单示例。

【问题讨论】:

  • +1 表示新人,但对您的问题非常详细。也对答案感兴趣。
  • 不要在成员表和您的表之间创建任何外键。这会在使用会员系统的管理功能时产生问题。成员资格不期望有任何外键引用违规,并且会抛出异常。
  • 嗯,我按照asp.net/web-forms/tutorials/security/membership/… 处的说明进行了此操作,很高兴知道这可能会给我带来问题。
  • @AlecMenconi - 很难相信他们会发表那篇文章。它大部分是准确的,但是关于创建外键约束的部分只是一个糟糕的选择,我本以为 .net 团队中的某个人会审查它。我的意思是,如果你调用 Membership.DeleteUser 会发生什么?它因违反外键约束而失败。更不用说将应用与特定的成员表实现联系起来了,该实现已经改变了好几次。

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


【解决方案1】:

首先,它被称为 View Model,而不是 ModelView。视图模型只是一个为视图目的而定制的类。它通常只包含该视图所需的数据,并包含诸如数据注释之类的东西来处理验证和表示。

因此,您只需创建一个模型,其中包含您希望在视图中显示的所有数据。这就是构建视图模型的全部内容。

所以你的视图模型只是

public class MyViewModel {
    public string FirstName {get;set;}
    public string Email {get;set;}        
}

那么在你看来,你只需要这样做:

@model MyViewModel

@using(Html.BeginForm()) {
    @Html.EditorForModel()
    <input type="submit" />
}

在您的控制器中(或者更好的是,在业务层中)您只需执行查询以检索用户名和电子邮件,然后将查询结果中的值复制到视图模型中。

当您更新数据时,您会执行相反的操作。这确实是一个太大的概念,但无法在这样的帖子中讨论。你真的应该看看示例代码,例如 MVC Music Store 或 Nerd Dinner。

要记住的重要事项。会员资格是一个完全独立于其他表格的系统。您必须单独检索它们,并单独更新它们。使用 Membership API 更新成员电子邮件或其他详细信息,并使用您自己的表格来更新您的数据。

【讨论】:

  • 糟糕,我知道它是 ViewModel,我在十几个谷歌搜索中使用了它。感谢您的更正。很高兴知道将成员资格表与我的其他表完全分开,这可能会节省我一些时间。我想如果需要,我可以推出自己的自定义会员提供程序或从 github 下载一个预建的。
【解决方案2】:

好吧,我决定我真正需要的只是会员资格,所以我放弃了尝试包括名字和姓氏。

我的 ViewModel:

namespace Pro_Shot_Portal.ViewModels
{
    public class SetAdminViewModel
    {
        public string UserName { get; set; }
        public string Email { get; set; }
        public string[] Role { get; set; }
    }
}

我的控制者:

    [Authorize(Roles = "Administrator")]
    public ActionResult SetRoles()
    {

        var model = Membership
            .GetAllUsers()
            .Cast<MembershipUser>()
            .Select(x => new SetAdminViewModel
                {
                    UserName = x.UserName,
                    Email = x.Email,
                    Role = Roles.GetRolesForUser(x.UserName)
                });
        return View(model);
    }

    [Authorize(Roles = "Administrator")]
    public ActionResult AddAdmin(string username)
    {
        Roles.AddUserToRole(username, "Administrator");

        return RedirectToAction("SetRoles", "Account");
    }

    [Authorize(Roles = "Administrator")]
    public ActionResult RemoveAdmin(string username)
    {
        Roles.RemoveUserFromRole(username, "Administrator");

        return RedirectToAction("SetRoles", "Account");
    }

我的观点:

@model IEnumerable<Pro_Shot_Portal.ViewModels.SetAdminViewModel>

@{
    ViewBag.Title = "Set Roles";
}

<h2>Index</h2>

<table>
    <tr>
    <td>UserName</td>
    <td>Email</td>
    <td>Roles</td>
    </tr>

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.UserName)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Email)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Role)
        </td>

        <td>
            @if (@Html.DisplayFor(modelItem => item.Role).ToString() == "Administrator")
            {
                @Html.ActionLink("Remove Admin", "RemoveAdmin", new { username = item.UserName })
            }
            else
            {
                @Html.ActionLink("Add Admin", "AddAdmin", new { username = item.UserName })
            }
        </td>
    </tr>
}

</table>

目前看来这对我有用。

感谢您帮助我走上正确的道路 Mystere。如果我的代码有任何问题,请告诉我。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-07
    • 1970-01-01
    • 2013-09-01
    • 1970-01-01
    • 2012-01-08
    相关资源
    最近更新 更多