ViewModel上的MVC2 DataAnnotations - 不理解将它与MVVM模式一起使用

时间:2010-06-08 20:20:59

标签: c# asp.net-mvc mvvm data-annotations

我有一个使用MVVM模式的MVC2应用程序。我正在尝试使用数据注释来验证表单输入。

在我的ThingsController中,我有两种方法:

    [HttpGet]
    public ActionResult Index()
    {
        return View();
    }

    public ActionResult Details(ThingsViewModel tvm)
    {
    if (!ModelState.IsValid) return View(tvm);

        try
        {
Query q = new Query(tvm.Query);
            ThingRepository repository = new ThingRepository(q);

tvm.Things = repository.All();                
return View(tvm);
        }
        catch (Exception)
        {
            return View();
        }
    }

My Details.aspx视图是对ThingsViewModel的强类型:

<%@ Page Title="" 
         Language="C#" 
         MasterPageFile="~/Views/Shared/Site.Master"        
         Inherits="System.Web.Mvc.ViewPage<Config.Web.Models.ThingsViewModel>" %>

ViewModel是一个由返回的Thing对象的IList和Query字符串(在表单上提交)组成的类,并且具有Required数据注释:

public class ThingsViewModel
{
    public IList<Thing> Things{ get; set; }

    [Required(ErrorMessage="You must enter a query")]
    public string Query { get; set; }
}

当我运行它,并单击表单上的提交按钮而不输入值时,我得到一个YSOD并出现以下错误:

The model item passed into the dictionary is of type 
'Config.Web.Models.ThingsViewModel', but this dictionary 
requires a model item of type 
System.Collections.Generic.IEnumerable`1[Config.Domain.Entities.Thing]'.

如何让Data Annotations与ViewModel一起使用?我看不出我错过了什么或者我哪里出错了 - 在开始进行验证之前,VM工作正常。

4 个答案:

答案 0 :(得分:1)

我认为问题不在于验证。

更改此行;

tvm.Things = repository.All(); //Is this the Linq extension method 'All()'?

到这个

tvm.Things = repository.ToList();

我不知道这是什么或它做什么;

new ThingRepository(q);

它需要一个字符串参数并返回某种Linq IQueriable或List?如果那是其他原因,则可能导致问题。

答案 1 :(得分:0)

您是否启用了客户端验证?它甚至可能是一个快速的hacky修复,但对于错误消息 - 没有额外的信息很难说。你可以发布你的视图和渲染的Html吗? 您的详细信息路线是什么样的? 如果在Details方法的开头设置断点,单击提交按钮时是否会触发?

答案 2 :(得分:0)

看起来你可以像这样声明你的ThingsViewModel:

public class ThingsViewModel: IEnumerable<Thing>

然后根据需要实现接口以访问Things列表。

答案 3 :(得分:0)

我认为ASP.NET MVC可能会尝试将您的视图映射到错误的控制器。返回视图时,可能需要指定要尝试使用的视图文件名。

返回视图(“ViewName”)