MVC4 最佳实践数据库模型与视图模型(传递到视图)

本文关键字:视图 模型 MVC4 数据库模型 最佳 | 更新日期: 2023-09-27 17:57:13

我想从一开始就养成好习惯,所以我有这个问题和一个问题:

我一直在做以下工作,然后我读了这篇文章

这里

这个我一直在做的事情的例子:

控制器

public ActionResult OneDollar130(Int32 number)
{
    MyEDM db = new MyEDM();
    MyDBModel model = db.MyTable.Where(t => t.Current == 1 && t.No == number).First();
    return View(model);
}

视图

@model MyProject.MyDBModel
<table>
  <tr>
    @if (Model.fldNo1 == "")
    {
        <td class="numberTD">
            @Html.ActionLink("1", "Number1", "Number", new { model = Model, number = 1 }, null)
        </td>
    }
    else
    {
        <td class="numberTD2">
            @Html.ActionLink("1", "Number2", "Number", new { model = Model, number = 1 })
        </td>
     }
  </tr>
</table>

我正在使用 EDM 中的模型并将其传递给视图。

我在上面的帖子中读到我不应该将我的数据库模型传递给视图,因为这是不好的做法。这让我有些担心,因为我想把它做好。

因此,根据上面的帖子,我将代码更改为实验并遇到了障碍:

控制器

public ActionResult OneDollar112(Int32 TableNo)
{
    return View(new getOneDollar112Game(TableNo));
}

public class getMyModel
{
    MyEDM db = new MyEDM();
    public MyDBModel MyModel { get; set; }
    public getMyModel() { }
    public getMyModel(Int32 number)
    {
        MyModel = db.MyTable
            .Where(t => t.Current == 1 && t.No == numbner).First();
    }
}

视图

@model MyProject.Models.getMyModel
<table>
  <tr>
    @if (Model.fldNo1 == "")
    {
        <td class="numberTD">
            @Html.ActionLink("1", "Number1", "Number", new { model = Model, number = 1 }, null)
        </td>
    }
    else
    {
        <td class="numberTD2">
            @Html.ActionLink("1", "Number2", "Number", new { model = Model, number = 1 })
        </td>
    }
  </tr>
</table>

好的,所以我的两个问题是:

  1. 这是最佳实践...我之前所做的事情是否违反了不将数据库模型传递给视图的规则?

  2. 如果第二种方法是正确的(我假设),为什么我不断收到 fldNo1 不存在的错误?

例如:CS1061:"MyProject.Models.getMyModel"不包含"fldNo1"的定义,并且找不到接受"MyProject.Models.getMyModel"类型的第一个参数的扩展方法"fldNo1"(您是否缺少使用指令或程序集引用?

MVC4 最佳实践数据库模型与视图模型(传递到视图)

我也不喜欢使用数据库对象作为模型。

我所做的是在我的项目中依赖MVC结构。

Views - 包含视图

Models - 包含专用于视图的模型

Controllers - 包含控制器,还负责在数据库和视图模型之间进行转换。

在我的控制器中,我添加了存储库(请参阅存储库模式)以与数据库通信。如果我想在我的视图中显示用户,我最终会得到这样的东西

public ActionResult Show()
{
    // entity model
    var user = _userRepository.GetUserByName(User.Identity.Name);
    // translate to view model
    var model = new User
    {
        Name = user.Name,
        EmailAddress = user.EmailAddress
    }
    // Send the view model to the view
    return View(model);
}

这有帮助吗?

您应该拥有单独的模型和视图模型,至少有两个原因:

1. 安全

MVC 中的默认模型绑定器将与任何匹配的发布数据字段绑定到模型属性。这提供了一个安全整体,如果您具有不打算更新的属性,而是在模型中(例如,使用通常不显示的属性名称伪造回发),则可以利用该整体

通过使用 ViewModel 并将每个必需的属性从 ViewModel 显式传递到实际模型,可以防御此攻击媒介

2. 复杂性

大多数合理的应用程序将需要每个视图的大量模型和模型集合

例如,基本的CRM客户视图可能有:客户详细信息,但不包括分数,姓名和电话号码列表,最近交易的摘要列表,注册的产品列表等。这些可能存在于复杂的对象集合中,名称和电话号码在不同的模型中,最近的交易可能是订单号、订单行总数,以及只有前三个 SKU 代码等。

ViewModel 允许您仅从模型和静态数据缓存中构建显示所需的部件和摘要。结果应该简化构建视图的工作流,并使其更具可测试性

通常有一条从简单视图模型到实际使用的最终复杂视图模型的继承路径

1)我编辑了你的代码。

行动:

public ActionResult OneDollar112(Int32 tableNo)
{
    return View(new OneDollar112ViewModel(tableNo));
}

型:

public class OneDollar112ViewModel
{
    private static MyEDM db = new MyEDM();
    private MyDBModel myModel;
    public string fldNo1 
    {
        get 
        { 
            return myModel == null
                ? myModel.fldNo1
                : null;
        }
        set 
        {
            // Your set logic here 
        }
    }    
    public OneDollar112ViewModel(Int32 number)
    {
        myModel = db.MyTable
            .Where(t => t.Current == 1 && t.No == numbner).SingleOrDefault();
    }
}    

视图:

@model MyProject.Models.OneDollar112ViewModel
<table>
    <tr>
    @if (Model.fldNo1 == "")
    {
        <td class="numberTD">
            @Html.ActionLink("1", "Number1", "Number", new { model = Model, number = 1 }, null)
        </td>
    }
    else
    {
        <td class="numberTD2">
            @Html.ActionLink("1", "Number2", "Number", new { model = Model, number = 1 })
        </td>
    }
    </tr>
</table>

2) 您应该使用视图模型将业务逻辑与数据层分开,您可以将数据层封装在服务中,并在将来利用依赖注入。