Web API 2 XML序列化忽略MetadataType

时间:2013-10-29 20:57:42

标签: serialization xml-serialization data-annotations asp.net-web-api

我有一个由Entity Framework 5 生成的简单类,类似于:

public partial class Car
{
   public string Model {get; set;}
   // other properties follow...
}

我创建了一个伴侣类(以防止这些事情被覆盖)和一个“伙伴类”来保存元数据::

[MetadataType(typeof(CarMetadata))]
public partial class Car { }

[DataContract("Automobile")]
public partial class CarMetadata
{
   [DataMember]
   public string Model {get; set;}
}

当我运行应用程序时, Help / Api / GET-api-car-model 的汽车帮助页面给出了这个错误:

An exception has occurred while using the formatter 'XmlMediaTypeFormatter'
to generate sample for media type 'application/xml'. 
Exception message: One or more errors occurred.

踢球者是如果我将DataAnnotations放在EF生成的类上它可以正常工作。这就像它忽略了伙伴类......但是JSON格式化程序正在按预期进行翻译。

这给出了EF类的正确结果,但它不能保留在那里或被覆盖:

[DataContract("Automobile")]
public partial class Car
{
   [DataMember]
   public string Model {get; set;}
   // other properties follow...
}

非常感谢任何协助。

3 个答案:

答案 0 :(得分:1)

老实说,我正在尝试重复你的代码,但它对我有用。

所以我生成了一个Model class Car

  public partial class Car
    {
        public int Id { get; set; }
        public string Model { get; set; }
    }

接下来我创建了相同的代码

[MetadataType(typeof(CarMetadata))]
public partial class Car { }


[DataContract()]
public partial class CarMetadata
{
    [DataMember]
    public string Model { get; set; }
}

接下来我创建了一个wapi控制器

public class EFController : ApiController
{
    // GET api/values
    public Car Get()
    {
        return new Car()
        {
            Id = 1,
            Model = "Hello World!"
        };
    }
}

从客户端开始我打了个电话

 $.ajax({
       url: '/api/EF',
        type: 'Get',
        dataType: "xml",
         success: function (data) {
                alert(data);
         },
         error: function(XMLHttpRequest, textStatus, errorThrown) { 
                 alert("Status: " + textStatus); alert("Error: " + errorThrown); 
         } 
});

我找回了一个xml对象,其中包含“hello world”和Id(children)。 对不起,也许我不明白你问题的性质。所以请向我解释一下?否则肯定会有效!

以防万一......你使用dataType:“xml”? 并尝试添加config.Formatters.XmlFormatter.UseXmlSerializer = true; 在WebApiConfig中(但无论有没有,它都适用于我)

答案 1 :(得分:0)

也许(我无法在任何地方找到信息)XML序列化框架不会通过MetadataType本身检测好友类。

尝试在应用的初始化中手动注册好友类。

以下是一个例子:

EF实体:

Partial Public Class Clasificacion

    Public Property ID() As String
    End Property

    Private _ID As String

     Public Property Descripcion() As String
    End Property

    Private _Descripcion As String
End Class

元数据:

Public Class ClasificationMetadata

    <StringLength(50, ErrorMessage:="Description too long")> _
      Public Property Description() As String
        Get
        End Get
        Set
        End Set
    End Property

End Class

使用元数据扩展部分类:

<MetadataType(GetType(ClasificationMetadata))> _
Partial Public Class Clasification

    Public Function hasDescrition As Boolean
        Return not String.IsNullOrEmpty(Me.Description)
 End Function

End Class  

注册好友类:

Dim descriptionProvider = New AssociatedMetadataTypeTypeDescriptionProvider(GetType(Clasification), GetType(ClasificationMetadata))
TypeDescriptor.AddProvider(descriptionProvider, GetType(Clasification))

答案 2 :(得分:0)

和Anton一样,我试图重复你的代码,但它也适用于我。

我的猜测是你的模型比你放在帖子中的示例模型更复杂,你有引用循环和/或大量的对象嵌套。

如果存在大量嵌套,请尝试设置config.Formatters.XmlFormatter.MaxDepth = 2。 (如果有效,请根据您的需要调整值。)

如果类在对象树的任何一点包含循环引用,则使用[DataContract(IsReference=true)]

如果两个问题都存在,请同时使用两者。结合 config.Formatters.XmlFormatter.UseXmlSerializer = true/false确保您尝试所有选项。

这是我最好的尝试。希望它有所帮助。