2012-10-02 31 views
11

我正在为某个viewModel属性开发客户端和服务器端验证。ValidationMessageFor与AddModelError(key,message)一起使用。关键是什么?

.cshtml文件我把这个:

@Html.DropDownListFor(model => model.EntityType.ParentId, Model.ParentTypeList, "") 
@Html.ValidationMessageFor(model => model.EntityType.ParentId) 

在控制器的业务验证

catch (BusinessException e) 
{ 
    ModelState.AddModelError("EntityType.ParentId", Messages.CircularReference); 
} 

上述工程按预期:如果一个异常被捕获,旁边出现消息下拉列表。

但是,我发现这种方式不是很优雅。在cshtml中,我使用一种方法来生成有关验证的所有必需信息。在控制器中,我必须知道确切的Key字符串并使用它。

难道没有更好的方法吗?

+0

此链接提供了一些额外的洞察力和一种不直接引用键作为字符串,而是作为表达式的方式:http://stackoverflow.com/questions/11090445/how-to-get-a-modelstate-key-of-an-item-in-列表继承人另一个资源ce提供Expression键的包装方法http://stackoverflow.com/questions/8793799/get-reference-to-object-from-c-sharp-expression – bUKaneer

回答

21

你可以写,将采取一个lambda表达式为重点,而不是一个字符串的扩展方法:

public static class ModelStateExtensions 
{ 
    public static void AddModelError<TModel, TProperty>(
     this ModelStateDictionary modelState, 
     Expression<Func<TModel, TProperty>> ex, 
     string message 
    ) 
    { 
     var key = ExpressionHelper.GetExpressionText(ex); 
     modelState.AddModelError(key, message); 
    } 
} 

,然后用这个方法:

catch (BusinessException e) 
{ 
    ModelState.AddModelError<MyViewModel, int>(
     x => x.EntityType.ParentId, 
     Messages.CircularReference 
    ); 
} 
+0

谢谢。完美作品 –

+0

为什么它不在图书馆? – UserControl

+0

@UserControl,因为并非所有东西都可以成为框架的一部分。为了使功能成为需求框架的一部分,需要编写,测试和记录。有时候你需要决定哪些功能会进入发行版,否则你将永远无法发布:-)因此,简单地说微软没有找到时间去实现,测试和记录这个功能。这就是为什么它不是图书馆的一部分。 –

0

你想验证发生无论是客户端还是服务器端,并且您还在寻找优雅的解决方案,那么为什么可以尝试创建自定义ValidationAttribute

4

我跟着@Darin Dimitrov的解决方案,但我想避免<MyViewModel, int>所以我使用了一些不同的方式,但对于需要MyViewModel object variable.

public static class ModelStateExtensions 
{ 
    public static void AddModelError<TModel, TProperty>(this TModel source,   
                Expression<Func<TModel, TProperty>> ex, 
                string message, 
                ModelStateDictionary modelState) 
    { 
     var key = System.Web.Mvc.ExpressionHelper.GetExpressionText(ex); 
     modelState.AddModelError(key, message); 
    } 
} 

如何使用:

catch (BusinessException e) 
{ 
    objMyViewModel.AddModelError(x => x.EntityType.ParentId, 
           Messages.CircularReference, 
           ModelState); 
} 
+4

对我来说,更直观的是扩展方法签名:'AddModelError (此ModelStateDictionary modelState,TModel模型,Expression > ex,字符串消息)''。 这样你就可以像使用ModelState.AddModelError(model,x => x.Email,“Invalid email”));' – benmccallum

相关问题