将 ModelState 转换为 JSON 以进行日志记录
Posted
技术标签:
【中文标题】将 ModelState 转换为 JSON 以进行日志记录【英文标题】:Convert ModelState to JSON for Logging 【发布时间】: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
【参考方案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);
【讨论】:
以上是关于将 ModelState 转换为 JSON 以进行日志记录的主要内容,如果未能解决你的问题,请参考以下文章
如何将 JSON 转换为 Swift Dictionary 以进行 HTTP POST