我有以下模型:
public class MyModel
{
[JsonProperty("screen_width")]
[Required(ErrorMessage = "Required width")]
public string ScreenWidth { get; set; }
}
并在我的控制器中进行验证:
public class MyController
{
[Route("/api/v1.0/test")]
[HttpPatch]
public async Task<IActionResult> SomeAction([FromBody] MyModel viewModel)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
}
}
预期的JSON正文为:
{
"screen_width": "1900"
}
但是我将通过例如:
{
"hello": "azazazazazaa!"
}
那么,我将看到什么作为回应?以下:
但这是奇怪的行为!我的客户不知道ScreenWidth
。这是我班的财产。为什么客户必须知道这一点?他们只知道screen_width
。
因此,我的问题是:如何更改此行为以获得此验证消息:
{
"screen_width": [
"Required width"
]
}
PS我使用.NET Core 3.1,并且using Newtonsoft.Json;
用于[JsonProperty]
属性。
我来到这里的以下有趣的文章
请尝试以下操作:
public class MyModel
{
[JsonProperty("screen_width")]
[Required(ErrorMessage = "Required width")]
[DisplayName("screen_width")]
public string ScreenWidth { get; set; }
}
但是,这本身是行不通的。您需要禁用内部模型状态过滤器。
public void ConfigureServices(IServiceCollection services)
{
...
services.Configure<ApiBehaviorOptions>(options =>
{
options.SuppressModelStateInvalidFilter = true;
});
...
}
然后,创建另一个过滤器
public class DisplayNameValidationFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext context)
{
if (context.ModelState.ErrorCount > 0)
{
var modelType = context.ActionDescriptor.Parameters
.FirstOrDefault(p => p.BindingInfo.BindingSource.Id.Equals("Body", StringComparison.InvariantCultureIgnoreCase))?.ParameterType; //Get model type
var expandoObj = new ExpandoObject();
var expandoObjCollection = (ICollection<KeyValuePair<String, Object>>)expandoObj; //Cannot convert IEnumrable to ExpandoObject
var dictionary = context.ModelState.ToDictionary(k => k.Key, v => v.Value)
.Where(v => v.Value.ValidationState == ModelValidationState.Invalid)
.ToDictionary(
k =>
{
if (modelType != null)
{
var property = modelType.GetProperties().FirstOrDefault(p => p.Name.Equals(k.Key, StringComparison.InvariantCultureIgnoreCase));
if (property != null)
{
//Try to get the attribute
var displayName = property.GetCustomAttributes(typeof(DisplayNameAttribute), true).Cast<DisplayNameAttribute>().SingleOrDefault()?.DisplayName;
return displayName ?? property.Name;
}
}
return k.Key; //Nothing found, return original vaidation key
},
v => v.Value.Errors.Select(e => e.ErrorMessage).ToList() as Object); //Box String collection
foreach (var keyValuePair in dictionary)
{
expandoObjCollection.Add(keyValuePair);
}
dynamic eoDynamic = expandoObj;
context.Result = new BadRequestObjectResult(eoDynamic);
}
base.OnActionExecuting(context);
}
}
现在只需使用以下命令:
public class MyController
{
[Route("/api/v1.0/test")]
[DisplayNameValidationFilter]
[HttpPatch]
public async Task<IActionResult> SomeAction([FromBody] MyModel viewModel)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句