.net webapi接收xml格式数据的3种情况小结

请看下面的攻略。

.NET WebAPI接收XML格式数据的3种情况小结

在Web应用程序中,接收XML格式数据是非常常见的操作。在.NET WebAPI中,我们可以通过多种方式来接收XML格式数据,下面将介绍其中的3种情况。

1. 直接读取RequestBody

直接读取Request的Body,把XML转换为对应的对象或集合:

public HttpResponseMessage Post(HttpRequestMessage request)
{
    var stream = request.Content.ReadAsStreamAsync().Result;
    var xml = XElement.Load(stream);

    var order = Deserialize<Order>(xml);
    // ...

    return Request.CreateResponse(HttpStatusCode.OK);
}

这里使用了HttpRequestMessage,它表示一个HTTP请求的消息内容,通过Content属性可以访问HTTP请求的Body。

ReadAsStreamAsync()会异步读取Body,并返回一个Stream对象。XElement.Load()将Stream转换为XElement对象,Deserialize<T>(XElement)可以将XElement转换为对象。

示例:

<?xml version="1.0" encoding="UTF-8"?>
<Order>
   <Id>1234567</Id>
   <Amount>99.9</Amount>
   <Item>test123</Item>
</Order>
public class Order
{
    public int Id {get;set;}
    public decimal Amount {get;set;}
    public string Item {get;set;}
}
var stream = new MemoryStream(Encoding.UTF8.GetBytes(xml));
var order = Deserialize<Order>(XElement.Load(stream));

2. 使用ModelBinder

通过模型绑定来自动将请求的XML转换成对应的实体类:

public HttpResponseMessage Post([ModelBinder(typeof(XmlModelBinder))] Order order)
{
    // ...

    return Request.CreateResponse(HttpStatusCode.OK);
}

在这个例子中,我们使用了一个自定义的XmlModelBinderXmlModelBinder继承自IModelBinder接口,用于将XML格式的数据绑定到对应的实体类。 在Order类上声明[XmlRoot("Order")]特性以便绑定器准确解析XML内容。

示例:

<?xml version="1.0" encoding="UTF-8"?>
<Order>
   <Id>1234567</Id>
   <Amount>99.9</Amount>
   <Item>test123</Item>
</Order>
[XmlRoot("Order")]
public class Order
{
    public int Id {get;set;}

    public decimal Amount {get;set;}

    public string Item {get;set;}
}
public class XmlModelBinder : IModelBinder
{
    public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
    {
        if (bindingContext.ModelType == typeof(Order))
        {
            try
            {
                var stream = actionContext.Request.Content.ReadAsStreamAsync().Result;
                var xml = XElement.Load(stream);
                var serializer = new XmlSerializer(typeof(Order));
                bindingContext.Model = serializer.Deserialize(xml.CreateReader());
                return true;
            }
            catch
            {
                return false;
            }
        }

        return false;
    }
}

3. 自定义MediaTypeFormatter

通过自定义MediaTypeFormatter来处理特定类型的数据。

public class XmlMediaTypeFormatter : MediaTypeFormatter
{
    public XmlMediaTypeFormatter()
    {
        SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/xml"));
    }

    public override bool CanReadType(Type type)
    {
        if (type == null)
        {
            throw new ArgumentNullException("type");
        }

        return typeof(IList).IsAssignableFrom(type) ||
            typeof(ICollection).IsAssignableFrom(type) ||
            typeof(IEnumerable).IsAssignableFrom(type) ||
            typeof(object).IsAssignableFrom(type);
    }

    public override bool CanWriteType(Type type)
    {
        if (type == null)
        {
            throw new ArgumentNullException("type");
        }

        return typeof(IList).IsAssignableFrom(type) ||
            typeof(ICollection).IsAssignableFrom(type) ||
            typeof(IEnumerable).IsAssignableFrom(type) ||
            typeof(object).IsAssignableFrom(type);
    }

    public override async Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
    {
        var encoding = content.Headers.ContentEncoding.FirstOrDefault();
        var streamReader = new StreamReader(readStream, encoding ?? Encoding.UTF8);

        var xmlSerializer = new XmlSerializer(type);
        return xmlSerializer.Deserialize(streamReader);
    }

    public override async Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext)
    {
        using (var writer = new XmlTextWriter(writeStream, Encoding.UTF8) { Formatting = Formatting.Indented })
        {
            var xmlSerializer = new XmlSerializer(type);
            xmlSerializer.Serialize(writer, value);
            await writeStream.FlushAsync();
        }
    }
}

XmlMediaTypeFormatter添加到WebAPI格式化管理中。

config.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
config.Formatters.XmlFormatter.MediaTypeMappings.Add(new UriPathExtensionMapping("xml", "application/xml"));
config.Formatters.Insert(0, new XmlMediaTypeFormatter());

在上面的代码中,我们自定义了一个新的MediaTypeFormatter,该格式可以处理application/xml类型的数据。因此,我们需要将默认的格式从WebAPI管理器中移除,并且将我们新定义的格式添加到WebAPI管理器的开头。

示例:

<?xml version="1.0" encoding="UTF-8"?>
<Orders>
   <Order>
      <Id>1234567</Id>
      <Amount>99.9</Amount>
      <Item>test123</Item>
   </Order>
   <Order>
      <Id>7654321</Id>
      <Amount>129.9</Amount>
      <Item>test456</Item>
   </Order>
</Orders>
[XmlRoot("Orders")]
public class Orders
{
    [XmlElement("Order")]
    public List<Order> OrderList {get;set;}
}
var orders = Deserialize<Orders>(xml);

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:.net webapi接收xml格式数据的3种情况小结 - Python技术站

(0)
上一篇 2023年5月17日
下一篇 2023年5月17日

相关文章

  • 本真的REST架构风格理解

    本真的REST架构风格理解 REST(Representational State Transfer)是一种架构风格,它以统一资源标识符(URI)作为唯一的资源标识,通过HTTP方法(GET、POST、PUT、DELETE等)对资源进行操作,使得客户端和服务器之间的交互方式简单明了、具有良好的可读性和可扩展性。但是,由于部分开发者对REST的不同理解,很多应…

    云计算 2023年5月17日
    00
  • Python面向对象class类属性及子类用法分析

    Python面向对象class类属性及子类用法分析 在Python中,面向对象编程是一种强大的编程方法,其中class类是面向对象编程的基本单位。 本文将讲解Python中的class类属性及其子类用法,以及提供两个示例说明。 Class类属性 class类能够定义变量,也就是属性。这些属性通常是定义在class的方法之外的,因此是公用的,即被所有的实例对象…

    云计算 2023年5月18日
    00
  • 七牛云存储使用Go语言架设网站的经验分享

    七牛云存储使用Go语言架设网站的经验分享 七牛云存储是一家提供云存储服务的公司,它提供了丰富的云存储解决方案,包括对象存储、CDN加速、数据处理等。下面是一份关于如何使用七牛云存储和Go语言架设网站的完整攻略,包括注册七牛云存储账号、使用七牛云存储API、使用Go语言编写网站等。 1. 注册七牛云存储账号 首先,你需要注册一个七牛云存储账号。注册过程非常简单…

    云计算 2023年5月16日
    00
  • python读取word文档的方法

    当我们需要处理一些Word文档时,可能会需要读取Word文档中的内容或者元数据。Python提供了多个库可以读取Word文档,其中最常用的有python-docx库和pywin32库。下面将详细讲解这两种方法的使用方法和示例。 1. 使用python-docx库读取Word文档 安装python-docx库 使用pip可以很方便地安装python-docx库…

    云计算 2023年5月18日
    00
  • 刀片服务器打造桌面云计算基础架构

    刀片服务器打造桌面云计算基础架构大家了解吗? 刀片服务器可以更有效地实现虚拟化,并承载桌面云计算应用程序,下文是小编为大家提供的专业信息,一起去看看吧。     更高的计算密度:刀片是一种更加集中的服务器类型,每个刀片的外形只有1U机架服务器的1/2甚至3/1大小,但处理器、芯片组、 内存、I/O控制芯片、硬盘等主要部件一应俱全,存储、交换机模块、管理模块、…

    云计算 2023年4月12日
    00
  • 云计算、虚拟化和容器

    “云计算”这个词,相信大家都非常熟悉。 作为信息科技发展的主流趋势,它频繁地出现在我们的眼前。伴随它一起出现的,还有 这些概念名词—— OpenStack、Hypervisor、KVM、Docker、K8S… 这些名词概念,全部都属于云计算技术领域的范畴。 对于初学者来说,理解这些概念的具体含义并不是一件容易的事情。 所以,小枣君今天这篇文章,将 给大家…

    2023年4月10日
    00
  • 云计算之路-出海记:建一个免费仓库 Amazon RDS for SQL Server

    上周由于园子后院起火,不得不调兵回去救火,出海记暂时停更,这周继续更新,“出海记”记录的是我们在 AWS 上建设博客园海外站的历程。在这一记中记录的是我们基于 AWS 免费套餐(Free Tier)创建一个 Amazon RDS for SQL Server 实例,这也是我们第一次使用 AWS RDS,之前只用过阿里云 RDS 上周由于园子后院起火,不得不调…

    云计算 2023年4月11日
    00
  • Effective HPA:预测未来的弹性伸缩产品

    作者 胡启明,腾讯云专家工程师,专注 Kubernetes、降本增效等云原生领域,Crane 核心开发工程师,现负责成本优化开源项目 Crane 开源治理和弹性能力落地工作。 余宇飞,腾讯云专家工程师,专注云原生可观测性、成本优化等领域,Crane 核心开发者,现负责 Crane 资源预测、推荐落地、运营平台建设等相关工作。 田奇,腾讯高级工程师,专注分布式…

    2023年4月9日
    00
合作推广
合作推广
分享本页
返回顶部