簡體   English   中英

序列化為不涉及屬性的json時如何忽略屬性

[英]How to ignore properties when serializing to json that does not involve attributes

我正在使用實體框架生成我的模型。 我想通過JSON交流其中一些模型。 問題是我不希望將EF粘貼到模型上的東西序列化(EntityKey,EntityState和所有EntityCollection <>屬性)

由於EF生成了這些模型,因此用ScriptIgnore或類似方法修飾屬性實際上是不可行的。

是否有任何json序列化器可以序列化對象並使其忽略不需要我更改模型源的字段? (不過,我可以添加到模型中,如果有幫助,因為它們被聲明為局部類)

我剛剛遇到一個類似的問題,在這種情況下,它是Linq to SQL模型上的自定義對象屬性,我寧願只是序列化數據庫中的序列和從數據庫中序列化,而不是設置許多額外的字段和額外的構造函數。 我不確定這與您的情況有多接近,但應該可以適應。

我見過的大多數解決方案都希望包含屬性(由於自動代碼生成而無法包含)或滾動自定義轉換器(過大,特別是如果要捕獲嵌套對象等)。

我的想法是,由於LinqToSql,我不需要的所有屬性已經獲得了屬性,因此與其手動獲取我想要的屬性,然后嘗試對其進行序列化,首先要序列化,然后再進行DeSerialize。 這使您的對象圖更易於使用,並且為您完成了所有嵌套。

接下來獲取我們不需要的成員名稱。 如何獲得這些取決於您自己,甚至可能是手動為您提供名稱的情況,其方式與您從MVC中的模型綁定中排除的方式相同。 在我的情況下,Linq的一點點思考和思考使我們獲得了Linq to SQL生成的所有屬性的名稱。

由於我們的對象是簡單的字典,因此我們遍歷不需要的成員並將其從字典中刪除。

最后,再次序列化您的字典。

public string JsonMinusProperties(object toSerialize)
    {
        //Replace this with your preferred way of getting your unwanted properties
        var LinqMemberNames = toSerialize.GetType().GetProperties().Where(y=>
            y.GetCustomAttributes(true).Any(x =>
                x.GetType().Namespace == "System.Data.Linq.Mapping"
            )
        ).Select(x=>x.Name);

        JavaScriptSerializer js = new JavaScriptSerializer();
        string json = js.Serialize(toSerialize);
        var tempobj = js.DeserializeObject(json) as Dictionary<string, object>;
        foreach (string linqMember in LinqMemberNames)
        {
            tempobj.Remove(linqMember);
        }
        return js.Serialize(tempobj);
    }

盡管從原則上講,如果需要刪除更深的屬性,則字典應該很容易遍歷字典,但這只會從第一級刪除。

如果使用DataContractJsonSerializer序列化為JSON,則它將僅序列化具有[ DataMember ]屬性的屬性。

要考慮的另一種選擇是為要在JSON中公開的數據提供單獨的DTO對象。 該對象將從您的實體模型構造。 這種方法的好處是您擁有一個顯式類DTO,它定義了數據協定,並且它與基礎實體模型脫鈎了。

JayRock中 ,您可以創建自己的IExporter 基本形式如下所示:

class FooExporter : IExporter
{
    public void Export(ExportContext context, object value, JsonWriter writer)
    {
        var properties = value.GetType().GetProperties();

        writer.WriteStartObject();

        foreach (var property in properties)
        {
            var propertyValue = property.GetValue(value, null);
            if (!JsonNull.LogicallyEquals(propertyValue))
            {
                writer.WriteMember(property.Name);
                context.Export(propertyValue, writer);
            }
        }

        writer.WriteEndObject();
    }

    public Type InputType
    {
        get { return typeof(Foo); }
    }
}

您可以根據需要進行任何修改(例如,忽略具有特定名稱的所有屬性;在構造函數中采用具體類型)。 然后可以像這樣使用它:

var context = JsonConvert.CurrentExportContextFactory();
context.Register(new FooExporter());
// always use this context
JsonConvert.CurrentExportContextFactory = () => context;
string json = JsonConvert.ExportToString(new Foo { … });

另一個選擇是在您的實體中實現IJsonExportable 它具有Export()方法,與上面的方法非常相似。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM