Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在MVC中跳过操作级别的模型验证_C#_Asp.net Mvc - Fatal编程技术网

C# 在MVC中跳过操作级别的模型验证

C# 在MVC中跳过操作级别的模型验证,c#,asp.net-mvc,C#,Asp.net Mvc,我有一个动作方法,它输出一个有多个子模型的模型。在其中一个子模型中,我有一些视图中不需要的附加属性 子模型-ProjectModel- [Required(ErrorMessage = "*")] public int Id { get; set; } [Required(ErrorMessage = "*")] public int SectorDivisionId { get; set; } [Required(ErrorMessage = "*")] [StringLength(250,

我有一个动作方法,它输出一个有多个子模型的模型。在其中一个子模型中,我有一些视图中不需要的附加属性

子模型-
ProjectModel
-

[Required(ErrorMessage = "*")]
public int Id { get; set; }
[Required(ErrorMessage = "*")]
public int SectorDivisionId { get; set; }
[Required(ErrorMessage = "*")]
[StringLength(250, ErrorMessage = "Project name should not be more than 250 characters.")]
public string Program { get; set; }

[Required(ErrorMessage = "*")]
[StringLength(25, ErrorMessage = "Project number should not be more than 25 characters.")]
public string ProjectNumber { get; set; }

public string WorkPackage { get; set; }

public string WorkPackageType { get; set; }

[Required(ErrorMessage = "*")]
public DateTime StartDate { get; set; }
[Required(ErrorMessage = "*")]
public DateTime EndDate { get; set; }
public int ProjectDirectorId { get; set; }
因此,在将子模型初始化为主模型时,我只使用我需要的属性,如下所示

model.ProjectInfo = new ProjectModel()
{
    Id = projectId,
    ProjectNumber = prj.p.ProjectNumber,
    Director = prj.Director,
    Program = prj.p.Program,
    StartDate = prj.p.StartDate,
    EndDate = prj.p.EndDate,
    ProjectReviewPeriodList = projectReviewPeriodList.AsEnumerable().
                                Select(o => new ProjectReviewPeriodModel
                                {
                                    Id = o.Id,
                                    ProjectReviewTypeId = o.ProjectReviewTypeId,
                                    ProjectId = o.ProjectId,
                                    ReviewPeriod = o.ReviewPeriod,
                                    ReviewPeriodDate = o.ReviewPeriodDate                                                    
                                }).ToList()
};
现在,在发布表单时,我有一个全局级别的操作过滤器,用于验证模型。子模型中的一些字段的验证(
ModelState.IsValid
)失败,我没有根据需要初始化这些字段

我想到了两个选择-

  • 使用
    ModelState.Remove()
    跳过验证。这是不可能的,因为我正在使用全局级别的操作筛选器
  • 创建新的视图模型
是否有其他方法可以做到这一点,最好是在操作方法级别

如果有任何疑问,请告诉我,否则我可以解释得更清楚


谢谢。

干净的方法是针对不同的用例使用不同的视图模型

也就是说,您可以使用数据注释属性而不是使用数据注释属性来实现验证逻辑

在ViewModel中引入一个指示用例的标志,例如,
IsEditUsecase
。将此标志设置在您知道用例的某个位置,例如控制器中

然后只执行此用例所需的验证

public class ProjectModel : IValidatableObject {

    public bool IsEditUsecase { get; set; }

    [Required(ErrorMessage = "*")] // required for every usecase
    public int Id { get; set; }

    // no [Required] and [StringLength] attributes 
    // because only required in some of the usecases
    public string Program { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) {
         // validation that occurs only in Edit usecase
         if (IsEditUsecase) {

             // Validate "Program" property
             if (string.IsNullOrWhiteSpace(Program)) {
                 yield return new ValidationResult(
                        "Program is required",
                        new[] { "Program" }
                 );
             } 
             else if (Program.Length > 250) {
                 yield return new ValidationResult(
                     "Project name should not be more than 250 characters.",
                     new[] { "Program" }
                 );
             }

             // validate other properties for Edit usecase ...
         }

         // validate other usecases ...
    }
}
公共类ProjectModel:IValidatableObject{
公共布尔IsEditUsecase{get;set;}
[必需(ErrorMessage=“*”)//每个用例都必需
公共int Id{get;set;}
//没有[Required]和[StringLength]属性
//因为只有在某些用例中才需要
公共字符串程序{get;set;}
公共IEnumerable验证(ValidationContext ValidationContext){
//仅在编辑用例中发生的验证
如果(IsEditUsecase){
//验证“程序”属性
if(string.IsNullOrWhiteSpace(程序)){
返回新的ValidationResult(
“程序是必需的”,
新[]{“程序”}
);
} 
否则如果(Program.Length>250){
返回新的ValidationResult(
“项目名称不应超过250个字符。”,
新[]{“程序”}
);
}
//验证编辑用例的其他属性。。。
}
//验证其他用例。。。
}
}

作为一个肮脏的黑客,我在我的razor页面中为所有导致ModelState验证错误的属性添加了隐藏字段。基本上,我为隐藏字段添加了一些默认值,现在效果很好。
虽然不推荐,但这是一个快速修复方法。

您的编辑数据,因此一如既往,请使用视图模型(该视图模型将只包含您在视图中需要的属性)@StephenMuecke是的,但在这种情况下,我将不得不复制大量字段,这可能会导致我以后添加/删除的每个属性在将来重复。是否有其他解决方案?使用自定义ActionFilter,重写OnActionExecuting并调用modelState[“ProjectModel”]。Errors.Clear()@IvanZaruba我可以同时使用自定义筛选器和继承筛选器吗?或者它会冲突/覆盖-
modelState[“ProjectModel”]。Errors.Clear()另一个想法-[Bind(Exclude=“ProjectModel”)]属性