我正确使用viewModels(MVC4)吗?

时间:2013-02-19 17:33:04

标签: asp.net-mvc asp.net-mvc-3 asp.net-mvc-4

我有一个对象,我想在详细信息视图中显示。该对象具有视图所需的一组属性。

该对象还有父母和祖父母,我需要在视图中显示。

我的对象viewModel的内容是:

public class ObjectViewModel
{
    // Used when creating a new object under a parent object
    [HiddenInput(DisplayValue = false)]
    public int? ParentObjectId { get; set; }

    [Required]
    public Object Object { get; set; }

    // Info that only the view needs, which is defined in the Controller based on some logic
    public string ActiveTitle { get; set; }

    // A bre
    public IList<Object> ParentObjects { get; set; } 
}

然后我在我的Detail控制器方法中使用它:

public ActionResult Detail(int objectId)
{

    // TODO: Make this a service call
    var object = _db.Objects.FirstOrDefault(s => s.ObjectId == objectId);

    if (object == null)
    {
        return View("Error");
    }

    var model = new SetViewModel() { 
         ActiveTitle = object.Name, 
         Object = object, 
         ParentObjectId = object.ParentObject.ObjectId, 
         ParentObjects = _objectService.GetParentObjects(set.ParentObject)
    };

    return View(model);
}

这看起来不错吗?或者我应该将对象模型中所需的字段拉到viewModel中,而不是对象本身?

3 个答案:

答案 0 :(得分:0)

任何一个选项都可以使用,并且在给定的应用程序中通常会混合使用这两种技术。

关键的想法是,您的视图模型应包含视图所需的内容,以便向用户显示数据。

如果您的视图仅显示简单控件中的单个原始字段,例如一系列标签或文本框控件,那么您的视图模型应该只指定字段,而不是父对象。

但是,您的视图很可能包含模板化或自定义控件,该控件“知道如何”完整地显示复杂对象。在这种情况下,您的视图模型需要包含整个对象。 (实际上,我发现自己在WPF中比ASP-MVC更频繁地做这件事,但我已经做到了。)

答案 1 :(得分:0)

看起来答案将是上下文。许多使用分层体系结构的团队可能采用体系结构约定,其中X下面的层不应该由您的视图直接引用,并且数据访问类可能是这种限制的候选者。在您的情况下,看起来您将视图的结构直接绑定到数据库模式(假设,因为您正在使用“_db”),这可能被认为是不合理的紧耦合。

另外,我假设你使用“object”来表示“任何一般的东西”,而不是字面上的System.Object,因为你的对象似乎在你的lambda表达式中有一个ObjectId属性。

答案 2 :(得分:0)

在视图模型中使用对象类型是非常模糊的,如果您不是原始程序员,则很难支持您的代码。我会将类类型添加到实际模型或使用泛型来指定类类型,如下所示:

public class ObjectViewModel<T>
{
    // Used when creating a new object under a parent object
    [HiddenInput(DisplayValue = false)]
    public int? ParentObjectId { get; set; }

    [Required]
    public T Object { get; set; }

    // Info that only the view needs, which is defined in the Controller based on some logic
    public string ActiveTitle { get; set; }

    // A bre
    public IList<T> ParentObjects { get; set; } 
}