第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

Json.NET 中僅一個(gè)屬性的自定義序列化程序,無需更改模型類

Json.NET 中僅一個(gè)屬性的自定義序列化程序,無需更改模型類

C#
一只斗牛犬 2022-06-12 15:15:15
我需要做類似以下的事情,但我需要在不將屬性放在模型類上或以其他方式污染模型類的情況下這樣做。理想的解決方案將通過 . 工作JsonSerializerSettings,而不會(huì)干擾其他自定義序列化。public class Person{    public string FirstName { get; set; }    [JsonConverter(typeof(AllCapsConverter))]    public string LastName { get; set; }    // more properties here in the real example, some of which nest to properties that use their own JsonConverters.}對(duì)于JsonConverter這個(gè)玩具示例(內(nèi)容并不真正相關(guān);相關(guān)的是我將它用于屬性):public class AllCapsConverter : JsonConverter{    public override bool CanConvert(Type objectType)        => objectType == typeof(string);    public override bool CanRead => false;    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)    {        throw new NotSupportedException();    }    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)    {        var str = value as string;        var upper = str.ToUpperInvariant();        JToken j = JToken.FromObject(upper);        j.WriteTo(writer);    }}通過單元測(cè)試:public class PersonSerializationTest{    [Fact]    public void SerializePerson_LastNameCaps()    {        var person = new Person        {            FirstName = "George",            LastName = "Washington"        };        var serialized = JsonConvert.SerializeObject(person);        var expected = @"{""FirstName"":""George"",""LastName"":""WASHINGTON""}";        Assert.Equal(expected, serialized);    }}
查看完整描述

2 回答

?
慕尼黑5688855

TA貢獻(xiàn)1848條經(jīng)驗(yàn) 獲得超2個(gè)贊

您可以以編程方式將 aJsonConverter應(yīng)用于模型類中的一個(gè)或多個(gè)屬性,而無需通過 custom 使用屬性ContractResolver。這是一個(gè)簡(jiǎn)單的示例,它將您應(yīng)用于您班級(jí)AllCapsConverter中的LastName財(cái)產(chǎn)。Person(如果您正在尋找更強(qiáng)大的解決方案,請(qǐng)查看@dbc 的答案。我的目的是展示可能可行的最簡(jiǎn)單示例。)


public class CustomResolver : DefaultContractResolver

{

    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)

    {

        JsonProperty prop = base.CreateProperty(member, memberSerialization);

        if (prop.DeclaringType == typeof(Person) && prop.UnderlyingName == "LastName")

        {

            prop.Converter = new AllCapsConverter();

        }

        return prop;

    }

}

這是更新的測(cè)試和Person模型,顯示了如何使用解析器:


public class PersonSerializationTest

{

    [Fact]

    public void SerializePerson_LastNameCaps()

    {

        var person = new Person

        {

            FirstName = "George",

            LastName = "Washington"

        };

        var settings = new JsonSerializerSettings

        {

            ContractResolver = new CustomResolver()

        };

        var serialized = JsonConvert.SerializeObject(person, settings);

        var expected = @"{""FirstName"":""George"",""LastName"":""WASHINGTON""}";

        Assert.Equal(expected, serialized);

    }

}


public class Person

{

    public string FirstName { get; set; }

    public string LastName { get; set; }

}


查看完整回答
反對(duì) 回復(fù) 2022-06-12
?
溫溫醬

TA貢獻(xiàn)1752條經(jīng)驗(yàn) 獲得超4個(gè)贊

您可以使用從IContractResolverDefaultContractResolver.


首先,ConfigurableContractResolver從這個(gè)答案中獲取如何添加元數(shù)據(jù)來描述 JSON.Net 中哪些屬性是日期:


public class ConfigurableContractResolver : DefaultContractResolver

{

    // This contract resolver taken from the answer to

    // https://stackoverflow.com/questions/46047308/how-to-add-metadata-to-describe-which-properties-are-dates-in-json-net

    // https://stackoverflow.com/a/46083201/3744182


    readonly object contractCreatedPadlock = new object();

    event EventHandler<ContractCreatedEventArgs> contractCreated;

    int contractCount = 0;


    void OnContractCreated(JsonContract contract, Type objectType)

    {

        EventHandler<ContractCreatedEventArgs> created;

        lock (contractCreatedPadlock)

        {

            contractCount++;

            created = contractCreated;

        }

        if (created != null)

        {

            created(this, new ContractCreatedEventArgs(contract, objectType));

        }

    }


    public event EventHandler<ContractCreatedEventArgs> ContractCreated

    {

        add

        {

            lock (contractCreatedPadlock)

            {

                if (contractCount > 0)

                {

                    throw new InvalidOperationException("ContractCreated events cannot be added after the first contract is generated.");

                }

                contractCreated += value;

            }

        }

        remove

        {

            lock (contractCreatedPadlock)

            {

                if (contractCount > 0)

                {

                    throw new InvalidOperationException("ContractCreated events cannot be removed after the first contract is generated.");

                }

                contractCreated -= value;

            }

        }

    }


    protected override JsonContract CreateContract(Type objectType)

    {

        var contract = base.CreateContract(objectType);

        OnContractCreated(contract, objectType);

        return contract;

    }

}


public class ContractCreatedEventArgs : EventArgs

{

    public JsonContract Contract { get; private set; }

    public Type ObjectType { get; private set; }


    public ContractCreatedEventArgs(JsonContract contract, Type objectType)

    {

        this.Contract = contract;

        this.ObjectType = objectType;

    }

}


public static class ConfigurableContractResolverExtensions

{

    public static ConfigurableContractResolver Configure(this ConfigurableContractResolver resolver, EventHandler<ContractCreatedEventArgs> handler)

    {

        if (resolver == null || handler == null)

            throw new ArgumentNullException();

        resolver.ContractCreated += handler;

        return resolver;

    }

}

然后,創(chuàng)建一個(gè)方法來配置JsonObjectContractfor Person,如下所示:


public static class JsonContractExtensions

{

    public static void ConfigurePerson(this JsonContract contract)

    {

        if (!typeof(Person).IsAssignableFrom(contract.UnderlyingType))

            return;

        var objectContract = contract as JsonObjectContract;

        if (objectContract == null)

            return;

        var property = objectContract.Properties.Where(p => p.UnderlyingName == nameof(Person.LastName)).Single();

        property.Converter = new AllCapsConverter();

    }

}

最后序列化如下:


// Cache the contract resolver statically for best performance.

var resolver = new ConfigurableContractResolver()

    .Configure((s, e) => { e.Contract.ConfigurePerson(); });


var settigs = new JsonSerializerSettings

{

    ContractResolver = resolver,

};


var person = new Person

{

    FirstName = "George",

    LastName = "Washington"

};

var serialized = JsonConvert.SerializeObject(person, settigs);

筆記:


ConfigurableContractResolver與其創(chuàng)建它,不如對(duì)那里的必要邏輯進(jìn)行子類化DefaultContractResolver、覆蓋DefaultContractResolver.CreateProperty和硬編碼Person.LastName。然而,創(chuàng)建一個(gè)允許在運(yùn)行時(shí)組合定制的可配置解析器似乎更有用且可重用。


用它來寫你的大寫字符串AllCapsConverter.WriteJson()會(huì)更簡(jiǎn)單:writer.WriteValue(string)


public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)

{

    var upper = ((string)value).ToUpperInvariant();

    writer.WriteValue(upper);

}

您可能希望緩存合約解析器以獲得最佳性能。


查看完整回答
反對(duì) 回復(fù) 2022-06-12
  • 2 回答
  • 0 關(guān)注
  • 188 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)