Asp.net mvc 如何在asp.net web api中将xml序列化为所需格式

Asp.net mvc 如何在asp.net web api中将xml序列化为所需格式,asp.net-mvc,xml-serialization,asp.net-web-api,Asp.net Mvc,Xml Serialization,Asp.net Web Api,我正在开发asp.NETMVC4WebAPI。我有一门课 public class Quiz { public int QuizId{get; set;} public string title{get; set;} ... ... } 现在我正试图检索Quiz的列表,所以我写下 public List<Quiz> GetQuizs() { return repository.ListQuizs(); } 我得到的回答是 <ArrayOfQuiz xmlns:xsi="ht

我正在开发asp.NETMVC4WebAPI。我有一门课

public class Quiz
{
public int QuizId{get; set;}
public string title{get; set;}
...
...
}
现在我正试图检索Quiz的列表,所以我写下

public List<Quiz> GetQuizs()
{
return repository.ListQuizs();
}
我得到的回答是

<ArrayOfQuiz xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Quiz>
<QuizId>4</QuizId>
<title>Master Minds</title>
</Quiz>
<Quiz>
<QuizId>5</QuizId>
<title>Master Minds</title>
</Quiz>
</ArrayOfQuiz>

4.
智囊团
5.
智囊团
但我希望得到这样的回应

<Quizs>
<Quiz>
<QuizId>4</QuizId>
<title>Master Minds</title>
</Quiz>
<Quiz>
<QuizId>5</QuizId>
<title>Master Minds</title>
</Quiz>
</Quiz>

4.
智囊团
5.
智囊团
我试过

public class quizs:List<Quiz>{}
public class Quiz
{
//properties here
}
公共类quizs:List{}
公开课测验
{
//这里的财产
}

但我无法将quizs列表加载到quizs类中。请指导我。

您有什么理由在DataContract Serializer上使用XmlSerializer吗

如果没有,你可以实现你想要的:

  • 移除config.Formatters.XmlFormatter.UseXmlSerializer=true;从你的配置
  • 添加对System.Runtime.Serialization的引用
  • 声明您的类和控制器
  • 代码

    [DataContract(Namespace = "")]
    public class Quiz
    {
        [DataMember]
        public int QuizId { get; set; }
        [DataMember(Name = "title")]
        public string Title { get; set; }
    }
    
    [CollectionDataContract(Name = "Quizs", Namespace = "")]
    public class QuizCollection : List<Quiz>
    {
    }
    
    public class QuizsController : ApiController
    {
        public QuizCollection Get()
        {
            return new QuizCollection
                           {
                               new Quiz {QuizId = 4, Title = "Master Minds"},
                               new Quiz {QuizId = 5, Title = "Another Title"}
                           };
        }
    }
    
    [DataContract(Namespace=”“)]
    公开课测验
    {
    [数据成员]
    public int QuizId{get;set;}
    [DataMember(Name=“title”)]
    公共字符串标题{get;set;}
    }
    [CollectionDataContract(Name=“Quizs”,Namespace=”“)]
    公共类QuizCollection:列表
    {
    }
    公共类QuizController:ApicController
    {
    公共QuizCollection Get()
    {
    返回新QuizCollection
    {
    新测验{QuizId=4,Title=“头脑大师”},
    新测验{QuizId=5,Title=“另一个标题”}
    };
    }
    }
    
    最后使用html标题“accept:application/xml”调用您的服务

    你的结果应该是:

    <Quizs xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
        <Quiz>
            <QuizId>4</QuizId>
            <title>Master Minds</title>
            </Quiz>
        <Quiz>
            <QuizId>5</QuizId>
            <title>Another Title</title>
        </Quiz>
    </Quizs>
    
    
    4.
    智囊团
    5.
    另一个标题
    
    关于你的名字空间。如何在属性中将它们设置为namespace=“”,以删除它们。您将努力删除
    xmlns:i=”http://www.w3.org/2001/XMLSchema-instance“
    它需要在那里允许XML处理空值


    有关集合的datacontract序列化程序支持的更多信息,请参见创建一个名为QuizList的类并实现IXmlSerializable,您可以准确定义XML的外观


    依我看,公开依赖于.Net类型序列化程序内部实现的wire格式是一个非常糟糕的主意。序列化程序的整体思想是,当您想要反序列化对象时,您需要具有相同的序列化程序库和相同的类型,以便重新构建对象。如果客户端不在.net平台上,会发生什么情况

    您可以删除名称空间。只需创建一个CustomXmlFormatter就可以从根元素中删除名称空间

    public class IgnoreNamespacesXmlMediaTypeFormatter : XmlMediaTypeFormatter
    {
    public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext)
    {
        try
        {
            var task = Task.Factory.StartNew(() =>
            {
                var xns = new XmlSerializerNamespaces();
                var serializer = new XmlSerializer(type);
                xns.Add(string.Empty, string.Empty);
                serializer.Serialize(writeStream, value, xns);
            });
    
            return task;
        }
        catch (Exception)
        {
            return base.WriteToStreamAsync(type, value, writeStream, content, transportContext);
        }
    }
    }
    

    当您控制该类时,实现
    IXmlSerializable
    是过分的。@Aliostad Wire格式应该完全在您的控制之下,或者由开放规范定义。依赖供应商的私有实现会带来未来的痛苦。@Darreller不是真的在谈论该格式。由媒体类型格式化程序处理的。我们讨论的是域实现。@Aliostad IMO Web API控制器签名不是域问题,域对象当然不应该通过网络传输。@Darreller我再次讨论的是服务器的公共域和CSD中的域对象。显然,映射器会将私有域转换为域对象(通常也称为viewmodel)。
    public class IgnoreNamespacesXmlMediaTypeFormatter : XmlMediaTypeFormatter
    {
    public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext)
    {
        try
        {
            var task = Task.Factory.StartNew(() =>
            {
                var xns = new XmlSerializerNamespaces();
                var serializer = new XmlSerializer(type);
                xns.Add(string.Empty, string.Empty);
                serializer.Serialize(writeStream, value, xns);
            });
    
            return task;
        }
        catch (Exception)
        {
            return base.WriteToStreamAsync(type, value, writeStream, content, transportContext);
        }
    }
    }