繁体   English   中英

自定义验证属性的ValidationContext缺少一个字段

[英]Custom validation attribute's ValidationContext is missing a field

我正在MVC 5中工作。我正在编写一个表单,供用户向内部应用程序提交索赔,并且在创建索赔时,我需要根据他们当前的余额来验证用户的索赔额。 它拒绝该金额是否大于余额,例如10美元对5美元,并要求他们将余额归零。

我觉得最好让余额成为CurrentBalance上的(不可编辑)属性CurrentBalance ,并带有一个自定义验证属性来比较这两个值。 我将其呈现为表单上的只读字段。 当用户选择他们要提交给哪个程序(例如HRA)时,Ajax请求将根据他们选择的程序来填写当前余额。

问题在于,当将viewmodel实例作为ValidationContext一部分传递给我的属性时, CurrentBalance 始终显示为零。 这是调试时的片段: https : //i.imgur.com/syDEuJ2.png

因此,无论余额如何,验证都将毫无例外地失败。

我尝试将CurrentBalance设置为视图上的普通非只读字段,并在提交之前CurrentBalance设置值。 在渲染视图之前,我还尝试在控制器中设置值。 无论哪种情况,它仍为零,如上图所示。

我的自定义属性如下:

public class ClaimAmountAttribute : ValidationAttribute
{
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        var claim = (ClaimCreateViewModel)validationContext.ObjectInstance;
        var amount = (decimal)value;

        if (claim.CurrentBalance - amount < 0)
        {
            return new ValidationResult(GetErrorMessage());
        }

        return ValidationResult.Success;
    }

    public string GetErrorMessage() => "Amount must be less than balance; please zero out balance instead.";
}

这是我观点的相关部分,不过,无论是否存在readonly属性,似乎都没有什么不同:

@model ClaimCreateViewModel

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

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

最后,这是viewmodel的片段:

public class ClaimCreateViewModel
{
    [Key]
    public int TransactionID { get; set; }
    // ...

    [Required]
    [ClaimAmount] //my custom attribute
    public decimal Amount { get; set; }

    [Display(Name = "Balance")]
    public decimal CurrentBalance { get; set; }
    // ...
}

看来我没有做任何事情在ValidationContext产生CurrentBalance的值。 请帮帮我。

好吧,这很尴尬。 事实证明, 我的POST操作上的[Bind]属性缺少CurrentBalance 验证在操作之前进行,但这无关紧要; 在此之前, [Bind]正在采取行动,以防止发布过多消息。 我已经更新了该操作,它现在可以工作:

public ActionResult Create([Bind(Include = "TransactionID,Amount,CurrentBalance")] ClaimCreateViewModel claim)
{ 
    // ...
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM