我想創建一個通用函數,當給定一個枚舉類型時,將返回一個對象,當通過WebApi序列化時將提供漂亮的輸出爲XML/Json。在Web API中序列化一個動態類型
此方法在串行化爲JSON時效果很好,但我無法使用XML進行操作。如果我使用XmlSerializer或DataContractSerializer手動序列化返回的對象,我會按預期得到結果。當的WebAPI本身試圖序列化,另一方面從一個HttpRequest,我得到像下面的錯誤:
System.Runtime.Serialization.SerializationException
類型「優先級」的數據合同名稱 「優先:http://schemas.datacontract.org/2004/07/'不是預期的。 考慮使用DataContractResolver或將靜態添加到已知類型列表中的任何類型的未知類型 - 例如,使用 KnownTypeAttribute屬性或將它們添加到傳遞給DataContractSerializer的已知 類型的列表中。
我使用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());
}
網絡API控制器的方法:
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));
}
任何想法?
您是否可以包含一個web api方法,在返回XML時重現此錯誤?我想我知道問題是什麼,但我需要看看你是如何將這個枚舉作爲內容返回的。 –
@AndrasZoltan編輯我的原始問題與示例Web API方法 – dherman
正如我懷疑 - 將對象作爲一個'對象'傳遞給內容 - 從接受我可以看到,我建議工作的解決方案:) –