MVC View直接与Model交互 - 好还是坏?

时间:2015-09-04 14:30:31

标签: c# asp.net-mvc model-view-controller

我有一个非常基本的Web应用程序,显示表的内容。用户可以通过单击链接更改某些参数。 为了简化,我们只考虑一个简单的,用于排序行的列的名称。

用户可以单击列或从右侧边栏选择列的名称以更改排序。 我使用<option>元素来显示可用列名列表。

直接从Model对象中获取这些名称是否正确,或者我应该以某种方式从Controller传递它们?这是现在的代码

<select>
    @{
        // get list of all properties names
        List<string> EtlProceduresNames = (((new MIPortal.Models.EtlProcedure()).GetType().GetProperties()).Select(item => item.Name)).ToList();
        // display an option item for each property name
        foreach (string EtlProceduresName in EtlProceduresNames) { 
            <option value=@EtlProceduresName >@Html.DisplayName(EtlProceduresName)</option>
        }
    }
</select>

这样View直接与Model互动。这是一个概念错误吗?我应该将该代码放在Controller上,然后将名称列表存储在ViewBag对象上吗?

2 个答案:

答案 0 :(得分:4)

您不应该直接从视图访问模型,因为这是针对MVC模式(关注点分离),您也不应该将此数据放入视图包。

View bag只能用于传递最简单的东西,而不是当你的对象充满数据时。

使用Viewmodels,这是编写asp.net MVC的最佳方式。

这样的例子 -

http://www.codeproject.com/Articles/826417/Advantages-of-ViewModel-in-MVC-Model-View-Controll

答案 1 :(得分:0)

我可以建议你使用所谓的ViewBag注入。 您需要为数据声明一个动作过滤器属性类。

public class EtlProceduresNamesAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
         //you can add some caching here
         filterContext.Controller.ViewBag.EtlProcedures = (new MIPortal.Models.EtlProcedure()).GetType().GetProperties()).Select(item => item.Name)).ToList();
    } 
}

您可以使用此属性为视图操作添加注释,例如

[EtlProceduresNames]
public ActionResult Action()
{
    return View();
}

您需要用

替换视图代码
<select>
    @foreach (string EtlProceduresName in ViewBag.EtlProceduresNames) 
    { 
        <option value=@EtlProceduresName >@Html.DisplayName(EtlProceduresName)</option>
    }
</select>