Enum型を指定すると、WebApiでシリアル化されたときにXML/Jsonとして見栄えのよい出力が得られるオブジェクトを返すジェネリック関数を作成しようとしています。Web APIでの動的型のシリアライズ
このメソッドは、JSONとしてシリアル化すると完全に正常に動作しますが、XMLで動作させることができません。 XmlSerializerまたはDataContractSerializerのいずれかを使用して返されたオブジェクトを手動でシリアル化すると、期待どおりの結果が得られます。 WEBAPI自体はHttpRequestのからの一方でそれをシリアル化しようとすると、私は次のようなエラーが出る:データコントラクト名 「優先順位付き
System.Runtime.Serialization.SerializationException
タイプ「優先順位」 :http://schemas.datacontract.org/2004/07/ 'は期待されていません。 KnockTypeAttribute属性を使用するか、DataContractSerializerに渡される既知の 型のリストに追加するなど、DataContractResolverを使用するか、または既知の型のリストに静的には、 型を追加することを検討してください。
私はブレークポイントを設定から作品を知って発生したタイプにシリアライザを設定するGlobalConfiguration.Configuration.Formatters.XmlFormatter.SetSerializerを使用して試してみたが、ちょうどそれを無視しているようだと、同じ例外がスローされます。列挙型は整数によってサポートされ、各エントリに対して一意の値を持つことが保証されます。ここでは、型を生成し、その型を返すために使用しているコードを示します。
public object GetSerializableEnumProxy(Type enumType) {
if (enumType == null) {
throw new ArgumentNullException("enumType");
}
if (!enumType.IsEnum) {
throw new InvalidOperationException();
}
AssemblyName assemblyName = new AssemblyName("DataBuilderAssembly");
AssemblyBuilder assemBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
ModuleBuilder moduleBuilder = assemBuilder.DefineDynamicModule("DataBuilderModule");
TypeBuilder typeBuilder = moduleBuilder.DefineType(enumType.Name, TypeAttributes.Class | TypeAttributes.Public);
// Add the [DataContract] attribute to our generated type
typeBuilder.SetCustomAttribute(
new CustomAttributeBuilder(typeof(DataContractAttribute).GetConstructor(Type.EmptyTypes), new object[] {})
);
CustomAttributeBuilder dataMemberAttributeBuilder = new CustomAttributeBuilder(
typeof(DataMemberAttribute).GetConstructor(Type.EmptyTypes), new object[] {}
);
// For each name in the enum, define a corresponding public int field
// with the [DataMember] attribute
foreach (var value in Enum.GetValues(enumType).Cast<int>()) {
var name = Enum.GetName(enumType, value);
var fb = typeBuilder.DefineField(name, typeof(int), FieldAttributes.Public);
// Add the [DataMember] attribute to the field
fb.SetCustomAttribute(dataMemberAttributeBuilder);
// Set the value of our field to be the corresponding value from the Enum
fb.SetConstant(value);
}
// Return an instance of our generated type
return Activator.CreateInstance(typeBuilder.CreateType());
}
ウェブアピコントローラ方法:
private static IEnumerable<Type> RetrievableEnums = new Type[] {
typeof(Priority), typeof(Status)
};
[GET("enum/{enumName}")]
public HttpResponseMessage GetEnumInformation(string enumName) {
Type enumType = RetrievableEnums.SingleOrDefault(type =>
String.Equals(type.Name, enumName, StringComparison.InvariantCultureIgnoreCase));
if (enumType == null) {
return Request.CreateErrorResponse(HttpStatusCode.NotFound, "The requested enum could not be retrieved");
}
return Request.CreateResponse(HttpStatusCode.OK, GetSerializableEnumProxy(enumType));
}
任意のアイデア?
XMLを返すときにこのエラーを再現するWeb APIメソッドを含めることはできますか?問題の内容を知っていると思いますが、コンテンツとしてこの列挙型を返す方法を確認する必要があります。 –
@AndrasZoltan私の疑問に思ったWeb APIの例 – dherman
を元の質問に編集しました - オブジェクトをコンテンツとしてオブジェクトに渡します - 私が提案した解決策がうまく機能していることを受け入れることができます:) –