【问题标题】:Convert ModelState to JSON for Logging将 ModelState 转换为 JSON 以进行日志记录
【发布时间】:2019-01-31 06:40:26
【问题描述】:

如何将ModelState 转换为与 ASP.NET Core 相同格式的 JSON?

我知道我可以做到BadRequest(ModelState),它会将 JSON 返回给客户端。它如何将ModelState 转换为 JSON?更重要的是,我该如何使用它正在使用的东西

我的目标是将ModelState 作为 JSON 记录在我们的日志“文件”中。

var blah = ModelState.ToJson()

【问题讨论】:

  • JSON.NET 是内置的。这是 ASP.NET Core 用来序列化响应对象的方法,所以你可以简单地做同样的事情:JsonCovert.SerializeObject(ModelState)
  • 嗨@ChrisPratt - 序列化整个对象。 ASP.NET 返回更简洁的版本:{ "Name": [ "The Name field is required." ] }
  • 然后使用ModelState.Errors
  • 仅供参考,没有ModelState.Errors。显然,每个字典条目都有一个 Errors 属性。无论哪种方式都会输出太多信息。 SerializableError 提供了我正在寻找的东西! @ChrisPratt

标签: c# json validation asp.net-core logging


【解决方案1】:

它如何将 ModelState 转换为 JSON?

SerializableError 类提供此功能。

更重要的是,我该如何使用它正在使用的东西?

using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;

//get key(s) and error message(s) from the ModelState
var serializableModelState = new SerializableError(ModelState);

//convert to a string
var modelStateJson = JsonConvert.SerializeObject(serializableModelState);

//log it
logger.LogInformation("Bad Model State", modelStateJson);

样本输出

{
    "Name": ["The Name field is required."]
}

我能够通过挖掘ASP.NET Core MVC source code 来解决这个问题。 source code 的有趣部分来自 SerializableError 类:

foreach (var keyModelStatePair in modelState)
{
    var key = keyModelStatePair.Key;
    var errors = keyModelStatePair.Value.Errors;
    if (errors != null && errors.Count > 0)
    {
        var errorMessages = errors.Select(error =>
        {
            return string.IsNullOrEmpty(error.ErrorMessage) ?
                Resources.SerializableError_DefaultError : error.ErrorMessage;
        }).ToArray();

        Add(key, errorMessages);
    }
}

【讨论】:

    【解决方案2】:

    只是为了获取每个模型属性的错误消息列表,这些模型属性以您想要的方式验证失败,如上所述,使用扩展方法。即ModelState.ToJson(),您需要创建一个带有静态函数ToJson(...)static 类。代码示例将如下所示。

    public static class ModelStateExtensions
    {
        /// <summary>
        /// Reads all the error messages in a <see cref="ModelStateDictionary"/> as 
        /// a collection and returns a JSON <see cref="string"/> of the list.
        /// </summary>
        /// <param name="modelstate">Current modelstate assuming that you've checked
        /// and confirmed that is Invalid using <see 
        /// cref="ModelStateDictionary.IsValid"/>
        /// </param>
        /// <returns>
        /// Collection of validation errors for the model as a JSON string.
        /// </returns>
        public static string ToJson(this ModelStateDictionary modelstate)
        {
            List<string> errors = modelstate.Values
                                            .SelectMany(x => x.Errors)
                                            .Select(x => x.ErrorMessage)
                                            .ToList();
            return JsonConvert.SerializeObject(errors);
        }
    }
    

    每个控制器上的ModelState 属性通常是ModelStateDictionary,所以如果我们想要一个额外的方法,那就是我们需要扩展的类。您可以通过关注Link 了解更多关于 C# 中的扩展方法的信息。

    现在让我们看看如何在示例控制器操作中使用我们的扩展方法:

    public IActionResult Create(UserViewModel model)
    {
        if(!ModelState.IsValid)
        {
            string json = ModelState.ToJson();
    
            // insert code to log json to file here
    
            return BadRequest(ModelState);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2019-02-16
      • 1970-01-01
      • 1970-01-01
      • 2014-02-24
      • 1970-01-01
      • 2023-04-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多