- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试使用 [FromBody]
在 ASP.NET Core Web API 项目中实现 HttpPost 方法查看模型和枚举。过去,使用 [FromBody]
绑定(bind) View 模型属性运作良好。
在我的特定场景中,我想提供一个 JSON 端点,在其中将给定值转换为具有不同名称的 C# 枚举。这个例子应该解释我想要实现的目标:
public enum WeatherEnum { [EnumMember(Value = "good")] Good, [EnumMember(Value = "bad")] Bad }
Internally, I want to use WeatherEnum.Good
and WeatherEnum.Bad
and the consumer of my endpoint wants to use lowercase values. Therefore, I'm trying to map the values which will be passed in the JSON body to my Enum representation.
I've read about the EnumMember
attribute and StringEnumConverter
. I've created a minimal example from the new ASP.NET Core Web API 3.0 template (You need to add these NuGet packages Microsoft.Extensions.DependencyInjection
, Microsoft.AspNetCore.Mvc.NewtonsoftJson
, and Newtonsoft.Json
)
ConfigureServices:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(options =>
{
}).SetCompatibilityVersion(CompatibilityVersion.Version_3_0)
.AddNewtonsoftJson(json =>
{
json.SerializerSettings.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter());
json.SerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;
});
services.AddControllers();
}
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System.Runtime.Serialization;
namespace WebAPITestEnum.Controllers
{
[ApiController]
[Produces("application/json")]
[Consumes("application/json")]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
[HttpPost]
[Route("method")]
public ActionResult<QueryResponseClass> TestMethod([FromBody] QueryRequestClass request)
{
// do something with the request ...
return new QueryResponseClass()
{
Foo = "bar"
};
}
}
public class QueryRequestClass
{
public WeatherEnum Weather { get; set; }
}
public class QueryResponseClass
{
public string Foo { get; set; }
}
[JsonConverter(typeof(StringEnumConverter))]
public enum WeatherEnum
{
[EnumMember(Value = "good")]
Good,
[EnumMember(Value = "bad")]
Bad
}
}
{
"Weather": "good"
}
{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"traceId": "|245d862e-4ab01d3956be5f60.",
"errors": {
"$.Weather": [
"The JSON value could not be converted to WebAPITestEnum.Controllers.WeatherEnum. Path: $.Weather | LineNumber: 1 | BytePositionInLine: 18."
]
}
}
FromBody
在 View 模型中使用枚举属性?
最佳答案
我发布的问题中的代码确实有效。在我的最小示例中,我忘记设置 [Required]
枚举上的属性。但是,如果没有设置值,那么我遇到了该方法应该如何 react 的问题。它正确地(?)假设了枚举的默认值,这不是我想要的。
我四处寻找,找到了这个解决方案https://stackoverflow.com/a/54206737/225808枚举是可空的,这并不理想,但至少我有验证,如果缺少值,我会收到一条错误消息
更新/警告 : 你可以使用上面提到的解决方案,但是!似乎代码会编译,但会从问题中抛出错误消息。我进一步将我自己的项目与测试项目进行了比较,并注意到我还需要两个包含 2 个 NuGet 包才能使一切正常运行:
[JsonConverter(typeof(CustomStringToEnumConverter<WeatherEnum>))]
public enum WeatherEnum
{
[EnumMember(Value = "123good")]
Good,
[EnumMember(Value = "bad")]
Bad
}
public class CustomStringToEnumConverter<T> : StringEnumConverter
{
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (string.IsNullOrEmpty(reader.Value?.ToString()))
{
return null;
}
try
{
return EnumExtensions.GetValueFromEnumMember<T>(reader.Value.ToString());
}
catch (Exception ex)
{
return null;
}
}
}
public static class EnumExtensions
{
public static T GetValueFromEnumMember<T>(string value)
{
var type = typeof(T);
if (!type.IsEnum) throw new InvalidOperationException();
foreach (var field in type.GetFields())
{
var attribute = Attribute.GetCustomAttribute(field,
typeof(EnumMemberAttribute)) as EnumMemberAttribute;
if (attribute != null)
{
if (attribute.Value == value)
return (T)field.GetValue(null);
}
else
{
if (field.Name == value)
return (T)field.GetValue(null);
}
}
throw new ArgumentException($"unknow value: {value}");
}
}
关于c# - 如何在 Web API 请求的 FromBody ViewModel 中使用具有 EnumMember 属性的枚举?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58270237/
我有这组用于货币目的的枚举 [DataContract] public enum PaymentCurrency { /// /// Canadian dollar. ///
public enum Status { Pending, [EnumMember(Value = "In Progress")] InProg
我将 WCF 服务与枚举作为数据协定。如何获取枚举值列表。这是代码: 在 WCF 中 [DataContract] public enum MyEnum { [EnumMember(Value=
我的 D 程序中有一些相当奇怪的行为,我已将其缩小为: import std.algorithm; import std.stdio; import std.traits; enum E { a, b
[DataContract] public enum Color { Red, Blue } [DataContract] public enum Color1 { [Enum
TypeScript 文档中的所有枚举示例 write enum members作为 PascalCase,例如: enum Direction { Up = 1, Down, Left,
我正在尝试使用 [FromBody] 在 ASP.NET Core Web API 项目中实现 HttpPost 方法查看模型和枚举。过去,使用 [FromBody] 绑定(bind) View 模型
我在 .NET 6 Microsoft.NET.Sdk.Web 项目中有一个端点,它使用标准 [FromQuery] 将查询字符串反序列化为 .NET 对象 [Route("[controller]"
我安装了 Visual Studio 2015 和 ASP.NET 5 Beta 6 的发布版本。我正在尝试将现有网站转换为新的 ASP.net,并为美国各州提供一个简单的枚举,其中我使用 EnumM
我有一个枚举,并为其值指定了 EnumMemberAttribute: public enum HireStrategy { [EnumMember(Value = "30-days")]
我是一名优秀的程序员,十分优秀!