带有标准格式的全局验证在asp.net核心中提交

时间:2019-06-07 22:44:49

标签: asp.net asp.net-mvc asp.net-core

在asp.net核心中,我通过添加全局ActionFilterAttribute

来进行全局验证
public class ValidateRequestAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        if (context.ModelState.IsValid == false)
        {
            context.Result = new BadRequestObjectResult(context.ModelState);                
        }
    }
}

然后在启动时注册

services.AddMvc(options =>
{
    options.Filters.Add(typeof(ValidateRequestAttribute));
})

我有带有服务器端验证和相应表格的简单模型

public class TaskModel: IValidatableObject
{
    public int? TaskID { get; set; }

    [Required(ErrorMessage = "Task Name is required.")]
    public string TaskName { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        // Do server side validation
        if (TaskName != "MyTask")
        {
            yield return new ValidationResult("Server validation failed.", new string[] { nameof(TaskName) });
        }
        else
        {
            yield return ValidationResult.Success;
        }
    }
}

表格

<button form="createForm" type="submit" id="btnSave">Save</button>

<form id="createForm" asp-action="Create" asp-controller="Tasks">    
    <div class="form-group">
        <label for="TaskName">Task Name</label>
        <input type="text" class="form-control w-25" asp-for="TaskName" />
        <span asp-validation-for="TaskName" class="text-danger"></span>
    </div>
</form>

我还包括jquery.validatejquery.validate.unobtrusive

当我在不输入“任务名称”的情况下单击提交时,客户端验证会按预期工作,并在UI上显示错误消息。
enter image description here

当服务器验证失败时,并且由于启用了全局验证,服务器将返回400,并具有预期的序列化模型状态。 但是,UI呈现字符串消息{"TaskName":["Server validation failed."]}

enter image description here

我了解为什么会这样,但是当然这不是预期的行为。

是否有更好的方法来处理标准表单提交场景中的全局验证?

或者,如果我正在进行全局验证,我们应该只坚持使用Ajax POST。

1 个答案:

答案 0 :(得分:0)

我在某篇SO帖子中找到了解决方案,

public class ValidateRequestAttribute : ActionFilterAttribute
{
    public ValidateRequestAttribute()
    {
    }

    public override void OnActionExecuting(ActionExecutingContext context)
    {
        if (!context.ModelState.IsValid)
        {
            Controller controller = context.Controller as Controller;
            object model = context.ActionArguments.Any()
               ? context.ActionArguments.First().Value
               : null;

            context.Result = (IActionResult)controller?.View(model)
               ?? new BadRequestObjectResult(context.ModelState);
        }

        base.OnActionExecuting(context);          
    }
}