自动从WebApi中的snake case JSON绑定pascal case c#模型 [英] Automatically bind pascal case c# model from snake case JSON in WebApi

查看:38
本文介绍了自动从WebApi中的snake case JSON绑定pascal case c#模型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从 WebApi v2(完整框架,而不是 dot net core)中的 snake_cased JSON 绑定我的 PascalCased c# 模型.

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 类做你想做的事.您只需将其设置为 NamingStrategyDefaultContractResolver 上通过设置.

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 包含三种命名策略:SnakeCaseNamingStrategyCamelCaseNamingStrategyDefaultNamingStrategy.)

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中的snake case JSON绑定pascal case c#模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆