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

时间:2012-12-06 08:20:37

标签: asp.net-mvc xml-serialization asp.net-web-api

我正在使用asp.net mvc 4 web api。我有一个类,

public class Quiz
{
public int QuizId{get; set;}
public string title{get; set;}
...
...
}

现在我正在尝试检索测验列表,所以我写了像,

public List<Quiz> GetQuizs()
{
return repository.ListQuizs();
}

我需要xml响应,所以我在webapi.config文件中进行了配置,如

config.Formatters.XmlFormatter.UseXmlSerializer = true;

我收到了回复,

<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>

但我想要像

这样的回复
<Quizs>
<Quiz>
<QuizId>4</QuizId>
<title>Master Minds</title>
</Quiz>
<Quiz>
<QuizId>5</QuizId>
<title>Master Minds</title>
</Quiz>
</Quiz>

我试过了,

public class quizs:List<Quiz>{}
public class Quiz
{
//properties here
}

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

3 个答案:

答案 0 :(得分:11)

你有没有理由在DataContract序列化器上使用XmlSerializer?

如果没有,你可以达到你想要的效果:

  1. 删除config.Formatters.XmlFormatter.UseXmlSerializer = true;来自您的配置
  2. 添加对System.Runtime.Serialisation
  3. 的引用
  4. 声明您的班级和控制员
  5. <强>代码

    [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"}
                           };
        }
    }
    

    终于使用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>
    

    关于您的命名空间NB。它们如何在属性中设置为namespace =“”以删除它们。你将要删除xmlns:i="http://www.w3.org/2001/XMLSchema-instance"它需要在那里允许XML处理空值。

    有关datacontract序列化程序对集合的支持的详细信息,请参阅here

答案 1 :(得分:3)

您可以删除命名空间。只需创建一个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);
    }
}
}

答案 2 :(得分:2)

创建一个名为QuizList的类并实现IXmlSerializable,您可以准确定义XML的外观。

恕我直言,揭示依赖于.Net类型序列化程序的内部实现的有线格式是一个非常糟糕的主意。序列化程序的整个想法是,当您想要反序列化对象时,您需要具有相同的序列化程序库和可用于重构对象的相同类型。如果您的客户不在.net平台上会发生什么?