ASP.NET Web API中的XML命名空间
我目前正在开发一个项目,要求我从端点和JSON输出XML。 我有以下型号:
[DataContract(Namespace="http://www.yale.edu/tp/cas")] [XmlType("serviceResponse")] [XmlRoot(Namespace="http://www.yale.edu/tp/cas")] public class ServiceResponse { [XmlElement("authenticationSuccess")] public AuthenticationSuccess Success { get; set; } [XmlElement("authenticationFailure")] public AuthenticationFailure Failure { get; set; } }
当success不为null时,输出如下:
现在,我可以看到,显然,我没有为命名空间分配前缀,我告诉元素是其中的一部分。 我的问题是我找不到使用媒体格式化程序在MVC4中添加名称空间前缀的地方。 我在global.asax中有以下内容:
GlobalConfiguration.Configuration.Formatters.XmlFormatter.UseXmlSerializer = true; GlobalConfiguration.Configuration.Formatters.XmlFormatter.RemoveSerializer(typeof(Models.ServiceResponse)); GlobalConfiguration.Configuration.Formatters.XmlFormatter.SetSerializer(typeof(Models.ServiceResponse), new Infrastructure.NamespaceXmlSerializer(typeof(Models.ServiceResponse)));
我创建了一个基于XmlSerializer的自定义序列化程序,试图拦截写入请求并在那里添加命名空间列表。 这个方法的问题是,现在我在每个可重写方法中都有断点,并且在序列化时没有一个断点导致我相信我的序列化器没有被使用。
是否有一些内置的方法来完成我想要做的事情,或者我是否在重新实现XmlMediaTypeFormatter以在序列化对象时传入命名空间?
作为后续答案:对我来说最简单的解决方案是编写自己的XmlMediaTypeFormatter
。 事实certificate,它并不像我想象的那样令人生畏。
public class NamespacedXmlMediaTypeFormatter : XmlMediaTypeFormatter { const string xmlType = "application/xml"; const string xmlType2 = "text/xml"; public XmlSerializerNamespaces Namespaces { get; private set; } Dictionary Serializers { get; set; } public NamespacedXmlMediaTypeFormatter() : base() { this.Namespaces = new XmlSerializerNamespaces(); this.Serializers = new Dictionary(); } public override Task WriteToStreamAsync(Type type, object value, System.IO.Stream writeStream, System.Net.Http.HttpContent content, System.Net.TransportContext transportContext) { lock (this.Serializers) { if (!Serializers.ContainsKey(type)) { var serializer = new XmlSerializer(type); //we add a new serializer for this type this.Serializers.Add(type, serializer); } } return Task.Factory.StartNew(() => { XmlSerializer serializer; lock (this.Serializers) { serializer = Serializers[type]; } var xmlWriter = new XmlTextWriter(writeStream, Encoding.UTF8); xmlWriter.Namespaces = true; serializer.Serialize(xmlWriter, value, this.Namespaces); }); } }
以下是格式化程序: https : //gist.github.com/kcuzner/eef239003d4f99dfacea
格式化程序通过公开XmlSerializer
将要使用的XmlSerializer
来工作。 这样我就可以根据需要添加任意名称空间。
我的顶级模特看起来如下:
[XmlRoot("serviceResponse", Namespace="http://www.yale.edu/tp/cas")] public class ServiceResponse { [XmlElement("authenticationSuccess")] public CASAuthenticationSuccess Success { get; set; } [XmlElement("authenticationFailure")] public CASAuthenticationFailure Failure { get; set; } }
在我的Global.asax
我添加了以下内容以将格式化程序放在列表顶部:
var xmlFormatter = new Infrastructure.NamespacedXmlMediaTypeFormatter(); xmlFormatter.Namespaces.Add("cas", "http://www.yale.edu/tp/cas"); GlobalConfiguration.Configuration.Formatters.Insert(0, xmlFormatter);
添加格式化程序并确保我的属性设置正确后,我的XML被正确命名。
在我的例子中,我需要添加链接到http://www.yale.edu/tp/cas
的cas
命名空间。 对于使用此function的其他人,只需将Add
调用更改/复制到心脏内容添加命名空间即可。
- 在mvc4中的_layout中显示数据库中的图像
- Azure WebSites或Azure云服务上的MVC4 API :’System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption’
- DataAnnotation比较两个属性
- 如何将值从一个视图传递到另一个视图
- MVC CheckBoxList模型绑定非布尔值
- 了解MVC中的,和Complex Actionmethod参数
- 如何将资源字符串组合用于validation属性错误消息?
- MVC 4 Connectionstring到SQL Server 2012
- ASP NET MVC 4集合在post上为null