MVC4最佳实践数据库模型v查看模型(传递给视图)

时间:2013-02-02 09:03:15

标签: c# entity-framework asp.net-mvc-4

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

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

Here

我一直在做的这个例子:

CONTROLLER

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中的模型并将其传递给View。

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

基于上面的帖子,我将我的代码更改为实验并遇到障碍:

CONTROLLER

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

MODEL

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不存在的错误?

  3. 例如:CS1061:'MyProject.Models.getMyModel'不包含'fldNo1'的定义,并且没有可以找到接受类型'MyProject.Models.getMyModel'的第一个参数的扩展方法'fldNo1'(你丢失了吗?) using指令或程序集引用?)

3 个答案:

答案 0 :(得分:4)

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

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

Views - 包含观点

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

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

在我的控制器中,我添加了存储库(请参阅Repository Pattern)以与数据库进行通信。如果我想在我的视图中显示用户,我最终会得到类似这样的内容

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 :(得分:1)

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

1。安全

MVC中的默认模型绑定器将与任何匹配的发布数据字段绑定到模型属性。这提供了一个安全性整体,如果你有不想更新但属于模型的属性,可以被利用(例如伪造一个带有通常不显示的属性名称的帖子)

通过使用ViewModel并将每个必需属性从ViewModel显式传递到实际模型,您可以抵御此攻击向量

2。复杂性

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

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

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

通常存在从简单的ViewModel到实际使用的最终复杂ViewModel的继承路径

答案 2 :(得分:0)

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)您应该使用视图模型将业务逻辑与您可以封装在服务中的数据层分开,并在将来利用依赖注入。