如何使用数据注释进行MVC2 / EF4 EntityCollection验证?

时间:2010-11-18 22:44:09

标签: validation asp.net-mvc-2 entity-framework-4

我终于遇到了一个障碍,现在可以成功创建新的模型数据。现在还有另一个问题 - 验证。大多数验证看起来很容易,因为我的很多模型数据都是标量值。然而,我链接到的是多对多的关系,所以我不确定如何验证它。我的模型是(再一次):

Game (only listing the relevant columns):
    GameID - int (primary key, auto-incr)

Platform:
    PlatformID - int (primary key, auto-incr)
    Name - string

GamePlatform (not a visible entity):
    GameID - int (foreign key from Games)
    PlatformID - int (foreign key from Platforms)

我的Create方法(是的,我知道它是草率和业余的 - 我是一个业余爱好者并且正在努力学习。我肯定会添加错误检查。我只是想得到它视图的大图 - > controller-> validation-> persist-in-db / show errors process down:

public ActionResult CreateReview([Bind(prefix = "GameData")]Game newGame, int[] PlatformIDs)
{
    try
    {
        foreach(int i in PlatformIDs)
        {
            Platform plat = _siteDB.Platforms.Single(p => p.PlatformID == i);
            newGame.Platforms.Add(plat);
        }

        newGame.LastModified = Datetime.Now;

        _siteDB.Games.AddObject(newGame);
        _siteDB.SaveChanges();

        return RedirectToAction("Index");
    }
    catch
    {
        return View();
    }
}

PlatformID的数组由我视图中的一组复选框提供。为了使我的游戏有效,它必须与至少一个平台相关联。我只是不确定如何使用数据注释来验证,或者甚至可以这样做。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

如果我正确理解你的问题,你的int []可能包含与数据库中平台ID相关联的int,并且你想确保int []包含至少一个有效的PlatformID,对吗?

在进入你的逻辑之前,你可以立即做一个简单的检查:

// If there aren't any IDs in Platform that are in PlatformIDs...
if (!_siteDB.Platforms.Any(p => PlatformIDs.Contains(p.PlatformID)))
    Return RedirectToAction("Index");
    // And probably tell the user to check a box, if they did,
    // One of your checkboxes isn't matching up with your PlatformIDs

理想情况下,您要做的是将int []添加到模型中,以便检查模型验证。由于数据库通常不存储int [],因此将其添加到您的游戏模型中。 EF可能会将您的数据库实体放在您的Models文件夹中,如果您查看它们,您会看到它们是部分类。所以在Models文件夹中添加它:

public partial class Game
{
    public Dictionary<int, bool> SupportedPlatforms { get; set; }// Edited
}

// Also add this which you'll see why below
public partial class Platform
{
    public static bool IsValidPlatformID(int PlatformID)
    {
        using (SiteDBEntities _siteDB = new SiteDBEntities())
            return _siteDB.Platforms.Any(p => p.PlatformID.Equals(PlatformID));
    }
}

然后添加自定义ValidationAttribute类:

public ContainsValidPlatformIDAttribute : ValidationAttribute
{

    public ContainsValidPlatformIDAttribute() { }

    public override bool IsValid(object value)
    {
        Dictionary<int, bool> supportedPlatforms = (Dictionary<int, bool>)value;
        if (value == null)
            return true;
        foreach (int i in values)
        {
            if (supportedPlatforms.Values.Any(b => b.Equals(true)))// Edited
                return false;
        }
        return true;
}

现在在Game类中用它装饰你的Property:

[ContainsValidPlatformID(Error = "You did not select a valid Platform.")]
public Dictionary<int, bool> SupportedPlatforms { get; set; }// Edited

(编辑)现在,不要为每个平台硬编码复选框,而是添加:

<%: Html.CheckboxFor(model => model.SupportedPlatforms[0]) %>
<%: Html.ValidationMessageFor(model => model.SupportedPlatforms[0]) %>

(编辑)现在您的复选框与模型绑定,您可以在控制器中验证模型,并且可以从Action方法中删除int []参数。这一切都是从我的脑子编码到这个编辑器中所以你可能需要在这里和那里调整一些东西,但这是你在使用视图中的模型时应该指导的方向。

另外,请查看Scott Guthrie在其博客中撰写的关于MVC Model Validation主题的内容。希望通过我的样本和Scott的博客,您将被指向正确的方向。