[英]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.