gpt4 book ai didi

c# - 用于检查我的模型属性中的重复项的自定义验证属性未触发

转载 作者:太空宇宙 更新时间:2023-11-03 23:33:48 24 4
gpt4 key购买 nike

我想向我的模型添加一个自定义验证属性,以检查是否有任何答案包含重复项。也就是说,如果用户在任何字段中键入相同的答案,我想在他们键入重复答案时显示错误。

这是我的模型:

public class SecurityQuestions
{
public int Question1Id { get; set; }
public int Question2Id { get; set; }
public int Question3Id { get; set; }
public int Question4Id { get; set; }
public int Question5Id { get; set; }
public int Question6Id { get; set; }

[UniqueAnswersOnly]
public string Answer1 { get; set; }
[UniqueAnswersOnly]
public string Answer2 { get; set; }
[UniqueAnswersOnly]
public string Answer3 { get; set; }
[UniqueAnswersOnly]
public string Answer4 { get; set; }
[UniqueAnswersOnly]
public string Answer5 { get; set; }
[UniqueAnswersOnly]
public string Answer6 { get; set; }
}

这是我对自定义属性的尝试:

public class UniqueAnswersOnly: ValidationAttribute, IClientValidatable
{

protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
//Get a list of all properties that are marked with [UniqueAnswersOnly]
var props = validationContext.ObjectInstance.GetType().GetProperties().Where(
prop => Attribute.IsDefined(prop, typeof(UniqueAnswersOnly)));

var values = new HashSet<string>();

//Read the values of all other properties
foreach(var prop in props)
{
var pValue = (string)prop.GetValue(validationContext.ObjectInstance, null);
if (prop.Name!=validationContext.MemberName && !values.Contains(pValue))
{
values.Add(pValue);
}
}

if (values.Contains(value))
{
return new ValidationResult("Duplicate answer", new[] { validationContext.MemberName });
}
return null;
}

public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var rule = new ModelClientValidationRule()
{
ErrorMessage = metadata.DisplayName + " is required!",
ValidationType = "duplicateanswers"
};

yield return rule;
}
}

我现在遇到的问题是,即使我输入了重复的答案,验证也成功了。我仍然可以继续下一个对话框(如果输入重复项,我预计验证会失败)。我认为这是因为我的自定义属性没有被触发或命中,因为我添加了断点但没有命中。

在我的 Controller 中,我有 if(ModelState.IsValid) {//continue to next dialog} 并且模型状态确实返回有效。

最佳答案

您可以像这样创建自定义验证属性:

public class UniqueAnswersOnly : ValidationAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
//Get a list of all properties that are marked with [UniqueAnswersOnly]
var props = validationContext.ObjectInstance.GetType().GetProperties().Where(
prop => Attribute.IsDefined(prop, typeof(UniqueAnswersOnly)));

var values = new HashSet<string>();

//Read the values of all other properties
foreach(var prop in props)
{
var pValue = (string)prop.GetValue(validationContext.ObjectInstance);
if (prop.Name!=validationContext.MemberName && !values.Contains(pValue))
{
values.Add(pValue);
}
}

if (values.Contains(value))
{
return new ValidationResult("Duplicate answer", new[] { validationContext.MemberName });
}
return null;
}
}

这是一个测试用例:

public class SecurityQuestions
{
public int Question1Id { get; set; }
public int Question2Id { get; set; }
public int Question3Id { get; set; }
public int Question4Id { get; set; }
public int Question5Id { get; set; }
public int Question6Id { get; set; }
[UniqueAnswersOnly]
public string Answer1 { get; set; }
[UniqueAnswersOnly]
public string Answer2 { get; set; }
[UniqueAnswersOnly]
public string Answer3 { get; set; }
[UniqueAnswersOnly]
public string Answer4 { get; set; }
[UniqueAnswersOnly]
public string Answer5 { get; set; }
[UniqueAnswersOnly]
public string Answer6 { get; set; }
}


class Program
{
static void Main(string[] args)
{
var questions = new SecurityQuestions();
questions.Answer1 = "Test";
questions.Answer2 = "Test";
questions.Answer3 = "Test3";
questions.Answer4 = "Test4";
questions.Answer5 = "Test5";
questions.Answer6 = "Test6";

var vc = new ValidationContext(questions, null, null);
var results = new List<ValidationResult>();
var validationResult = Validator.TryValidateObject(questions, vc, results, true);
}
}

编辑:

我创建了一个默认的 MVC 项目并添加了您当前的代码。该验证工作得很好。

我将其添加到家庭 Controller :

    public ActionResult AskQuestions()
{
var questions = new SecurityQuestions();

return View(questions);
}

[HttpPost]
public ActionResult CheckQuestions(SecurityQuestions questions)
{
if (ModelState.IsValid)
{
return View();
}
else
{
return HttpNotFound();
}
}

AskQuestions View 如下所示:

@model WebApplicationValidation.Models.SecurityQuestions

@{
ViewBag.Title = "AskQuestions";
}

<h2>AskQuestions</h2>


@using (Html.BeginForm("CheckQuestions", "Home",FormMethod.Post))
{
@Html.AntiForgeryToken()

<div class="form-horizontal">
<h4>SecurityQuestions</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.Question1Id, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Question1Id, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Question1Id, "", new { @class = "text-danger" })
</div>
</div>

<div class="form-group">
@Html.LabelFor(model => model.Question2Id, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Question2Id, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Question2Id, "", new { @class = "text-danger" })
</div>
</div>

<div class="form-group">
@Html.LabelFor(model => model.Question3Id, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Question3Id, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Question3Id, "", new { @class = "text-danger" })
</div>
</div>

<div class="form-group">
@Html.LabelFor(model => model.Question4Id, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Question4Id, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Question4Id, "", new { @class = "text-danger" })
</div>
</div>

<div class="form-group">
@Html.LabelFor(model => model.Question5Id, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Question5Id, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Question5Id, "", new { @class = "text-danger" })
</div>
</div>

<div class="form-group">
@Html.LabelFor(model => model.Question6Id, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Question6Id, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Question6Id, "", new { @class = "text-danger" })
</div>
</div>

<div class="form-group">
@Html.LabelFor(model => model.Answer1, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Answer1, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Answer1, "", new { @class = "text-danger" })
</div>
</div>

<div class="form-group">
@Html.LabelFor(model => model.Answer2, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Answer2, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Answer2, "", new { @class = "text-danger" })
</div>
</div>

<div class="form-group">
@Html.LabelFor(model => model.Answer3, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Answer3, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Answer3, "", new { @class = "text-danger" })
</div>
</div>

<div class="form-group">
@Html.LabelFor(model => model.Answer4, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Answer4, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Answer4, "", new { @class = "text-danger" })
</div>
</div>

<div class="form-group">
@Html.LabelFor(model => model.Answer5, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Answer5, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Answer5, "", new { @class = "text-danger" })
</div>
</div>

<div class="form-group">
@Html.LabelFor(model => model.Answer6, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Answer6, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Answer6, "", new { @class = "text-danger" })
</div>
</div>

<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}

<div>
@Html.ActionLink("Back to List", "Index")
</div>

@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}

如果我运行应用程序,如果我输入两个相同的答案,则 ModelState.IsValid() 为 false。在验证例程中设置断点表明它正在运行。

关于c# - 用于检查我的模型属性中的重复项的自定义验证属性未触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31275160/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com