请看下面的攻略。
.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);
}
在这个例子中,我们使用了一个自定义的XmlModelBinder
。XmlModelBinder
继承自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技术站