あなたがやりたい何が条件付きしかし、プリミティブを使用して、string
または辞書ですserialization surrogateでMyClass
のインスタンスを置き換えることですMicrosoftがhereで説明したように、代理人がデータコントラクトのシリアル化によってサポートされていないためです。あなたが唯一のシリアライズとデシリアライズないようにする必要がありますので、
しかし、あなたは手動でMyClass
のインスタンスはbar
が空の文字列に置き換えた代理List<object>
であなたList<MyClass>
を置き換えることにより、必要な出力を取得し、Dictionary<string, string>
することができますさもないと。手動constructDataContractJsonSerializerSettings
で次の値でDataContractJsonSerializer
:
(DataContractJsonSerializerSettings
、EmitTypeInformation
とUseSimpleDictionaryFormat
は、.NET 4.5に、すべての新しいをしていることに注意してください。)このように
あなたが定義することができ、あなたのMyType
を次のように:
public static partial class DataContractJsonSerializerHelper
{
public static string SerializeJsonSurrogateCollection<T>(this IEnumerable<T> collection) where T : IHasSerializationSurrogate
{
if (collection == null)
throw new ArgumentNullException();
var surrogate = collection.Select(i => i == null ? null : i.ToSerializationSurrogate()).ToList();
var settings = new DataContractJsonSerializerSettings
{
EmitTypeInformation = EmitTypeInformation.Never,
KnownTypes = surrogate.Where(s => s != null).Select(s => s.GetType()).Distinct().ToList(),
UseSimpleDictionaryFormat = true,
};
return DataContractJsonSerializerHelper.SerializeJson(surrogate, settings);
}
public static string SerializeJson<T>(this T obj, DataContractJsonSerializerSettings settings)
{
var type = obj == null ? typeof(T) : obj.GetType();
var serializer = new DataContractJsonSerializer(type, settings);
return SerializeJson<T>(obj, serializer);
}
public static string SerializeJson<T>(this T obj, DataContractJsonSerializer serializer = null)
{
serializer = serializer ?? new DataContractJsonSerializer(obj == null ? typeof(T) : obj.GetType());
using (var memory = new MemoryStream())
{
serializer.WriteObject(memory, obj);
memory.Seek(0, SeekOrigin.Begin);
using (var reader = new StreamReader(memory))
{
return reader.ReadToEnd();
}
}
}
}
をし、次のように手動でJSONへのあなたのリストをシリアライズ:
public interface IHasSerializationSurrogate
{
object ToSerializationSurrogate();
}
public class MyClass : IHasSerializationSurrogate
{
public string foo;
public string bar;
// If you're not going to mark MyClass with data contract attributes, DataContractJsonSerializer
// requires a default constructor. It can be private.
MyClass() : this("", "") { }
public MyClass(string f, string b = "")
{
this.foo = f;
this.bar = b;
}
public object ToSerializationSurrogate()
{
if (string.IsNullOrEmpty(bar))
return foo;
return new Dictionary<string, string> { { foo, bar } };
}
}
は、その後、次の拡張メソッドを紹介
var json = list.SerializeJsonSurrogateCollection();
次の結果を得ました:
[{"foo":"bar"},"foo1",null,{"foo2":"bar2"}]
あなたは本当にあなたが常に二重シリアル化された結果生じるDataContractJsonSerializer
とJSON 二度目に結果の文字列をシリアル化することができます(なぜ?)エスケープする文字列が必要な場合:
var jsonOfJson = json.SerializeJson();
を私はそれがSerためDataContractSerializer` `とコードベースを共有しているため、純粋にDataContractJsonSerializer``でこれを行う方法はありません信じて
"[{\"foo\":\"bar\"},\"foo1\",{\"foo2\":\"bar2\"}]"
その結果[データコントラクトタイプ](https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/types-supported-by-the-data-contract-serializer)をializingします。基になるシリアライズされたフォーマット(JSONまたはXML)へのアクセスを提供します。 – dbc
[tag:json.net]に切り替えた場合、これは簡単に実行できます。あるいは、['JsonReaderWriterFactory.CreateJsonWriter()'](https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/types-supported-by-the-data-contract)を呼び出すこともできます。 JSONとXML間のマッピング](https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/mapping-between)に記載されている規則に従って、独自のJSON出力を手動でシリアル化します。 -json-and-xml)。 – dbc
私はこの形式にシリアル化する必要があります。 – vonludi