【问题标题】:validate an non-Input model in MVC core验证 MVC 核心中的非输入模型
【发布时间】:2020-12-03 16:36:29
【问题描述】:

我有一个带有object type 输入的操作方法,如下所示:

public async Task<IActionResult> DoSomeThing([FromBody]object input, bool options)

{
    if (options == true)
    {
        var castedInput = (A) input;
        if (TryValidateModel(castedInput))
        {
            // do some thing
        }
        else
        {
            //return validation Errors;
            //forexample:return Error("Error1")
            //??!??!!??!?!?!?!??!
        }
    }
    else
    {
        var castedInput = (B)input;
        if (TryValidateModel(castedInput))
        {
            // do some thing
        }
        else
        {
            //return validation Errors;
            //forexample:return Error("You must fill this parameter")
            //??!??!!??!?!?!?!??!

        }
    }
}

在此方法中,我首先将 Input 转换为我的 ViewModel,然后对其进行验证。现在我想返回我在模型注释上设置的验证错误。 我该怎么做?

我的视图模型:

public class A
{
    [Required(ErrorMessage = "Error1")]
    string Phone;
    .
    .
    .
}

public class B
{
    [Required(ErrorMessage = "You must fill this parameter")]
    string Name;
    .
    .
    .  
}

【问题讨论】:

  • 不知道你的输入应该是什么形状是一个非常糟糕的主意。每种方法都应该有一个不同的、已定义的模型。
  • 当你使用[FromBody]object input,并且在调试var castedInput = (A) input;时,你会得到一个类似System.InvalidCastException: Unable to cast object of type 'System.Text.Json.JsonElement' to type 'xxx.A'.的错误,所以你需要在你的action中将Object定义为A或B。例如:@ 987654327@,public async Task&lt;IActionResult&gt; DoSomeThing2([FromBody]B input)
  • 感谢您的回答,我知道此方法存在问题,但总的来说,我想获得未输入模型的验证错误消息。例如castedInput模型错误消息对此没有意见?

标签: c# asp.net-mvc validation asp.net-core


【解决方案1】:

这是一个演示:

行动:

public JsonResult DoSomeThing([FromBody]object input,bool options)

        {
            var model = new Object();
            if (options)
            {
                model = JsonConvert.DeserializeObject<A>(input.ToString());
            }
            else {
                model = JsonConvert.DeserializeObject<B>(input.ToString());
            }
            string messages = "";
            if (!TryValidateModel(model))
            {
                messages = string.Join("; ", ModelState.Values
                                 .SelectMany(x => x.Errors)
                                 .Select(x => !string.IsNullOrWhiteSpace(x.ErrorMessage) ? x.ErrorMessage : x.Exception.Message.ToString()));
            }
            return Json(messages);
        }

型号:

public class A
    {
        [Required(ErrorMessage = "Error1")]
        public string Phone { get; set; }
    }

    public class B
    {
        [Required(ErrorMessage = "You must fill this parameter")]
        public string Name { get; set; }
     
    }

结果:

【讨论】:

    【解决方案2】:

    DataAnnotation 的验证错误可以用ModelState 对象返回。

    • 可以使用通用函数并在每个Action 中调用它
    protected string ValidateModel1()
    {
        string messages = "";
        if (!ModelState.IsValid)
        {
            messages = string.Join("; ", ModelState.Values
                             .SelectMany(x => x.Errors)
                             .Select(x => !string.IsNullOrWhiteSpace(x.ErrorMessage) ? x.ErrorMessage : x.Exception.Message.ToSubString()));
        }
        return messages;
    }
    
    • 在控制器中将此方法用作:
    string modelState = ValidateModel();
    

    第二种方式

    创建一个Action Filter 并在Action Attribute 或控制器级别使用它:

    public class ValidateModelAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            if (!actionContext.ModelState.IsValid)
            {
                string messages = string.Join("; ", actionContext.ModelState.Values
                                                    .SelectMany(x => x.Errors)
                                                    .Select(x => !string.IsNullOrWhiteSpace(x.ErrorMessage) ? x.ErrorMessage : x.Exception.Message.ToSubString()));
    
                actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.BadRequest, messages);
            }
        }
    }
    

    【讨论】:

    • 谢谢解答,如何获取非输入法的消息?请举个例子或告诉我更多。
    • 非输入是什么意思?如果 Action 方法参数中没有任何模型,你要吗?
    • 是类似于castedInput
    • 认为我们有一个模型要验证它,而这个模型不是我的操作输入参数的成员
    猜你喜欢
    • 2021-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多