我正在尝试将我的 PascalCased c# 模型与 WebApi v2 中的 snake_cased JSON 绑定(完整框架,而不是 dot net core).
I am trying to bind my PascalCased c# model from snake_cased JSON in WebApi v2 (full framework, not dot net core).
这是我的 api:
public class MyApi : ApiController
{
[HttpPost]
public IHttpActionResult DoSomething([FromBody]InputObjectDTO inputObject)
{
database.InsertData(inputObject.FullName, inputObject.TotalPrice)
return Ok();
}
}
这是我的输入对象:
public class InputObjectDTO
{
public string FullName { get; set; }
public int TotalPrice { get; set; }
...
}
我遇到的问题是 JSON 看起来像这样:
The problem that I have is that the JSON looks like this:
{
"full_name": "John Smith",
"total_price": "20.00"
}
我知道我可以使用 JsonProperty 属性:
I am aware that I can use the JsonProperty attribute:
public class InputObjectDTO
{
[JsonProperty(PropertyName = "full_name")]
public string FullName { get; set; }
[JsonProperty(PropertyName = "total_price")]
public int TotalPrice { get; set; }
}
但是我的 InputObjectDTO 巨大,而且还有很多其他人喜欢它.它有数百个属性都是蛇形的,最好不必为每个属性指定 JsonProperty 属性.我可以让它自动"工作吗?也许使用自定义模型绑定器或自定义 json 转换器?
However my InputObjectDTO is huge, and there are many others like it too. It has hundreds of properties that are all snake cased, and it would be nice to not have to specify the JsonProperty attribute for each property. Can I make it to work "automatically"? Perhaps with a custom model binder or a custom json converter?
无需重新发明轮子.Json.Net 已经有一个 SnakeCaseNamingStrategy
类做你想做的事.您只需将其设置为 NamingStrategy
通过设置在 DefaultContractResolver
上.
No need to reinvent the wheel. Json.Net already has a SnakeCaseNamingStrategy
class to do exactly what you want. You just need to set it as the NamingStrategy
on the DefaultContractResolver
via settings.
将此行添加到 WebApiConfig
类中的 Register
方法:
Add this line to the Register
method in your WebApiConfig
class:
config.Formatters.JsonFormatter.SerializerSettings.ContractResolver =
new DefaultContractResolver { NamingStrategy = new SnakeCaseNamingStrategy() };
这是一个演示(控制台应用程序)来证明这个概念:https://dotnetfiddle.net/v5siz7
Here is a demo (console app) to prove the concept: https://dotnetfiddle.net/v5siz7
如果您想将蛇形外壳应用于某些类而不是其他类,您可以通过应用 [JsonObject]
属性来指定命名策略,如下所示:
If you want to apply the snake casing to some classes but not others, you can do this by applying a [JsonObject]
attribute specifying the naming strategy like so:
[JsonObject(NamingStrategyType = typeof(SnakeCaseNamingStrategy))]
public class InputObjectDTO
{
public string FullName { get; set; }
public decimal TotalPrice { get; set; }
}
通过属性设置的命名策略优先于通过解析器设置的命名策略,因此您可以在解析器中设置默认策略,然后在需要时使用属性覆盖它.(Json.Net 包含三种命名策略:SnakeCaseNamingStrategy
、CamelCaseNamingStrategy
和DefaultNamingStrategy
.)
The naming strategy set via attribute takes precedence over the naming strategy set via the resolver, so you can set your default strategy in the resolver and then use attributes to override it where needed. (There are three naming strategies included with Json.Net: SnakeCaseNamingStrategy
, CamelCaseNamingStrategy
and DefaultNamingStrategy
.)
现在,如果您想反序列化使用一种命名策略并序列化对同一类使用不同的策略,那么上述解决方案都不起作用对你来说,因为命名策略将在 Web API 中双向应用.因此,在这种情况下,您将需要像 @icepickle 的 answer 中所示的自定义内容来控制每个应用的时间.
Now, if you want to deserialize using one naming strategy and serialize using a different strategy for the same class(es), then neither of the above solutions will work for you, because the naming strategies will be applied in both directions in Web API. So in in that case, you will need something custom like what is shown in @icepickle's answer to control when each is applied.
这篇关于从 WebApi 中的蛇案例 JSON 自动绑定帕斯卡案例 c# 模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!