Web API 2 XML Serialization is ignoring MetadataType

南楼画角 提交于 2019-12-11 06:18:09

问题


I have a simple class that is generated by Entity Framework 5, similar to:

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

I have created a companion class (to keep these things from being overwritten) and a "buddy class" to hold the metadata::

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

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

When I run the application the Help page for my car at Help/Api/GET-api-car-model gives me this error:

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

The kicker is that if I put the DataAnnotations on the EF generated class it works fine. It's like it's ignoring the buddy class... but the JSON formatter is translating it as expected.

This gives the correct result, on the EF class, but it can't stay there or it's overwritten:

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

Any assistance would be greatly appreciated.


回答1:


Like Anton, I was trying to repeat your code , but it works for me too.

My guess is that you model is more complex than the example model you put in the post and you have referencing loops and/or a lot of object nesting.

Try to set config.Formatters.XmlFormatter.MaxDepth = 2 if a lot of nesting is present. (If it works, tune the value to match your needs).

Use [DataContract(IsReference=true)] if the classes contains circular references in any point of the object tree.

Use both if both issues are present. Combine with config.Formatters.XmlFormatter.UseXmlSerializer = true/false to be sure you try all the options.

It's my best try. Hope it helps.




回答2:


Honestly, I am trying to repeat your code , but it works for me.

So I generated a Model class Car

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

Next I created the same code

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


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

Next I created a wapi controller

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

After from the client side I made a call

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

And I got back an xml object that has "hello world" and Id inside (children). Sorry maybe I didn't understand the nature of your problem.So please explain it to me? Otherwise it definitely works!

Just in case ... do you use dataType: "xml"? And try to add config.Formatters.XmlFormatter.UseXmlSerializer = true; in WebApiConfig(but it works for me in both cases with and without)




回答3:


Maybe (I can't find info anywhere) XML serialization framework doesn't detect buddy classes by MetadataType itself.

Try to register the buddy class by hand in the init of your app.

Here's a example:

EF entity:

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

Metadata:

Public Class ClasificationMetadata

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

End Class

Extending partial class with metadata:

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

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

End Class  

Registering buddy class:

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


来源:https://stackoverflow.com/questions/19668964/web-api-2-xml-serialization-is-ignoring-metadatatype

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!