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

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

问题描述

我正在尝试从WebApi v2(完整框架,而不是点网核心)中的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 类来完成您的工作想.您只需要在 NamingStrategy 通过设置href ="https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_Serialization_DefaultContractResolver.htm" rel ="noreferrer"> 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

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.)

现在,如果您要对同一个类别使用一种命名策略进行反序列化,而对另一类使用不同的策略进行 serialize ,则以上两种解决方案均不起作用为您服务,因为命名策略将在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自动绑定Pascal Case C#模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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