Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/269.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 调整MVC4WebAPI XmlSerializer以丢失命名空间_C#_Xml_Asp.net Mvc_Xml Serialization_Asp.net Web Api - Fatal编程技术网

C# 调整MVC4WebAPI XmlSerializer以丢失命名空间

C# 调整MVC4WebAPI XmlSerializer以丢失命名空间,c#,xml,asp.net-mvc,xml-serialization,asp.net-web-api,C#,Xml,Asp.net Mvc,Xml Serialization,Asp.net Web Api,我正在开发一个MVC WebAPI,它使用EF和POCO类进行存储。 我想做的是从XML中去掉名称空间,这样端点就可以返回并接受没有名称空间的XML对象。(json工作正常) 也许你可以试试这个: 将默认的XmlFormatter替换为您自己的: GlobalConfiguration.Configuration.Formatters.Add(new CustomXmlFormatter()); GlobalConfiguration.Configuration.Formatters.Remov

我正在开发一个MVC WebAPI,它使用EF和POCO类进行存储。 我想做的是从XML中去掉名称空间,这样端点就可以返回并接受没有名称空间的XML对象。(json工作正常)


也许你可以试试这个:

将默认的XmlFormatter替换为您自己的:

GlobalConfiguration.Configuration.Formatters.Add(new CustomXmlFormatter());
GlobalConfiguration.Configuration.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter);
并使用XmlSerializer调用它,在序列化过程中指定空命名空间,如下所示:

public CustomXmlFormatter()
{
    SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/xml"));
    SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/xml"));
    Encoding = new UTF8Encoding(false, true);
}

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

    if (type == typeof(IKeyValueModel))
        return false;

    return true;
}

protected override bool CanWriteType(Type type)
{
    return true;
}

protected override Task OnReadFromStreamAsync(Type type, Stream stream, HttpContentHeaders contentHeaders, FormatterContext formatterContext)
{
    return Task.Factory.StartNew(() =>
            {
                using (var streamReader = new StreamReader(stream, Encoding))
                {
                    var serializer = new XmlSerializer(type);
                    return serializer.Deserialize(streamReader);
                }
            });
}

protected override Task OnWriteToStreamAsync(Type type, object value, Stream stream, HttpContentHeaders contentHeaders, FormatterContext formatterContext, System.Net.TransportContext transportContext)
{
    var serializer = new XmlSerializer(type);
    return Task.Factory.StartNew(() =>
            {
                using (var streamWriter = new StreamWriter(stream, Encoding))
                {
                    XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
                    ns.Add("", "");
                    serializer.Serialize(streamWriter, value, ns);
                }
            });
    }
}
自定义XML序列化程序从中被盗,因此未经测试


这应该序列化不写入名称空间的对象。我不确定OOTB对反序列化是否有效,您可能必须尝试使用
XmlSerializer.Deserialize()
和句柄或事件。

这里的答案非常正确\

如果您根本不想装饰您的POCO,请使用第一个选项:

config.Formatters.XmlFormatter.UseXmlSerializer = true;
如果使用选项2,可能需要添加对
System.Runtime.Serialization

假设像这样的帖子接受设置正确:

获取http://anyoldserver/api/foos/5 接受:应用程序/xml

控制器

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Runtime.Serialization;
using System.Web.Http;

namespace CutomXmlFormater.Controllers
{
//[DataContract(Namespace = "")]
public class Foo
{
    //[DataMember]
    public string Bar { get; set; }
}

public class FoosController : ApiController
{
    // GET api/foos/5
    public Foo Get(int id)
    {
        return new Foo() { Bar = "Test" };
    }
}
}

配置(应用程序启动/WebApiConfig)

结果

或者(带有注释和数据联系人):

测试
或(使用XML序列化器路由):

测试

我已经有一段时间没有处理MVC 4了,但我们最终用XmlSerializer替换了默认的格式化程序,如下所示:

protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);

        GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings = GetSerializeSettings();
        GlobalConfiguration.Configuration.Formatters.XmlFormatter.UseXmlSerializer = true;
    }

    internal JsonSerializerSettings GetSerializeSettings()
    {
        return new JsonSerializerSettings
                           {
                               Formatting = Formatting.Indented,
                               ContractResolver = new CamelCasePropertyNamesContractResolver(),
                               Converters = new List<JsonConverter> { new IsoDateTimeConverter() }
                           };
    }
受保护的无效应用程序\u Start()
{
RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings=GetSerializeSettings();
GlobalConfiguration.Configuration.Formatters.XmlFormatter.UseXmlSerializer=true;
}
内部JsonSerializerSettings GetSerializeSettings()
{
返回新的JsonSerializerSettings
{
格式化=格式化。缩进,
ContractResolver=新的CamelCasePropertyNamesContractResolver(),
转换器=新列表{new IsoDateTimeConverter()}
};
}

这可能有助于。。。我知道我们还使用POCO上的属性定制了属性名称,您说您不想这样做,但那是因为我们希望它们是驼峰式的。

我已经定制了Boris对MVC Webapi 5的回答。 使用以下任一http头使用CustomFormatter呈现结果:

接受:应用程序/xml

接受:text/xml

WebApiConfig.cs:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

        GlobalConfiguration.Configuration.Formatters.Add(new CustomXmlFormatter());
        GlobalConfiguration.Configuration.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter);
    }
}
CustomXmlFormatter.cs:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Formatting;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Xml.Serialization;

namespace Custom.Formatter
{
    public class CustomXmlFormatter: MediaTypeFormatter
    {
        private  UTF8Encoding encoder;

        public CustomXmlFormatter()
        {
            SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/xml"));
            SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/xml"));
            encoder = new UTF8Encoding(false, true);
        }

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

            //Type filtering
            if (type == typeof(SendEmailMessageResponse) || type == typeof(SendSmsMessageResponse))
                return true;
            else
                return false;
        }

        public override bool CanWriteType(Type type)
        {
            return true;
        }

        public override Task<object> ReadFromStreamAsync(Type type, Stream stream, HttpContent content, IFormatterLogger formatterLogger)
        {
            return Task.Factory.StartNew(() =>
                    {
                        using (var streamReader = new StreamReader(stream, encoder))
                        {
                            var serializer = new XmlSerializer(type);
                            return serializer.Deserialize(streamReader);
                        }
                    });
        }

        public override Task WriteToStreamAsync(Type type, object value, Stream stream,    HttpContent content, TransportContext transportContext)
        {
            var serializer = new XmlSerializer(type);
            return Task.Factory.StartNew(() =>
                    {
                        using (var streamWriter = new StreamWriter(stream, encoder))
                        {
                            XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
                            ns.Add("", "");
                            serializer.Serialize(streamWriter, value, ns);
                        }
                    });
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.IO;
使用System.Linq;
Net系统;
使用System.Net.Http;
使用System.Net.Http.Formatting;
使用System.Net.Http.Header;
使用系统文本;
使用System.Threading.Tasks;
使用System.Web;
使用System.Xml.Serialization;
命名空间自定义.Formatter
{
公共类CustomXmlFormatter:MediaTypeFormatter
{
专用UTF8编码编码器;
公共CustomXmlFormatter()
{
添加(新的MediaTypeHeaderValue(“应用程序/xml”);
添加(新的MediaTypeHeaderValue(“text/xml”);
编码器=新的UTF8编码(假、真);
}
公共覆盖布尔CanReadType(类型)
{
如果(类型==(类型)为空)
抛出新的ArgumentNullException(“类型”);
//类型筛选
if(type==typeof(SendEmailMessageResponse)| | type==typeof(SendSMessageResponse))
返回true;
其他的
返回false;
}
公共重写bool CanWriteType(类型)
{
返回true;
}
公共重写任务ReadFromStreamAsync(类型类型、流、HttpContent、IFormatterLogger formatterLogger)
{
返回Task.Factory.StartNew(()=>
{
使用(var streamReader=新的streamReader(流、编码器))
{
var serializer=新的XmlSerializer(类型);
返回序列化程序。反序列化(streamReader);
}
});
}
公共重写任务WriteToStreamAsync(类型类型、对象值、流、HttpContent内容、TransportContext)
{
var serializer=新的XmlSerializer(类型);
返回Task.Factory.StartNew(()=>
{
使用(var streamWriter=新streamWriter(流、编码器))
{
XmlSerializerNamespaces ns=新的XmlSerializerNamespaces();
加上(“,”);
serializer.Serialize(streamWriter,value,ns);
}
});
}
}
}

尝试在所有可重写的方法中设置断点,但只设置了GetPerRequestFormatterInstance。是否需要通过添加新的来删除XML格式化程序类?命名空间有什么问题?删除名称空间会更改文档的语义。如果不清除该名称空间中的nil属性,就永远不会清除名称空间。如果去掉nil属性(或将其名称空间更改为空名称空间),则会更改文档的含义。突然,parent_id和status_id可能会被视为空字符串,而不是空值。不过,我想摆脱“./Platform.Services.AccountService.Data”这一部分,这是最有趣的事情。这是数据分类
//(Use this is you don't go the data contact and model annotation route)
config.Formatters.XmlFormatter.UseXmlSerializer = true;
<Foo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xmlns:xsd="http://www.w3.org/2001/XMLSchema"><Bar>Test</Bar></Foo>
<Foo xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><Bar>Test</Bar></Foo>
protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);

        GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings = GetSerializeSettings();
        GlobalConfiguration.Configuration.Formatters.XmlFormatter.UseXmlSerializer = true;
    }

    internal JsonSerializerSettings GetSerializeSettings()
    {
        return new JsonSerializerSettings
                           {
                               Formatting = Formatting.Indented,
                               ContractResolver = new CamelCasePropertyNamesContractResolver(),
                               Converters = new List<JsonConverter> { new IsoDateTimeConverter() }
                           };
    }
public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

        GlobalConfiguration.Configuration.Formatters.Add(new CustomXmlFormatter());
        GlobalConfiguration.Configuration.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter);
    }
}
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Formatting;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Xml.Serialization;

namespace Custom.Formatter
{
    public class CustomXmlFormatter: MediaTypeFormatter
    {
        private  UTF8Encoding encoder;

        public CustomXmlFormatter()
        {
            SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/xml"));
            SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/xml"));
            encoder = new UTF8Encoding(false, true);
        }

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

            //Type filtering
            if (type == typeof(SendEmailMessageResponse) || type == typeof(SendSmsMessageResponse))
                return true;
            else
                return false;
        }

        public override bool CanWriteType(Type type)
        {
            return true;
        }

        public override Task<object> ReadFromStreamAsync(Type type, Stream stream, HttpContent content, IFormatterLogger formatterLogger)
        {
            return Task.Factory.StartNew(() =>
                    {
                        using (var streamReader = new StreamReader(stream, encoder))
                        {
                            var serializer = new XmlSerializer(type);
                            return serializer.Deserialize(streamReader);
                        }
                    });
        }

        public override Task WriteToStreamAsync(Type type, object value, Stream stream,    HttpContent content, TransportContext transportContext)
        {
            var serializer = new XmlSerializer(type);
            return Task.Factory.StartNew(() =>
                    {
                        using (var streamWriter = new StreamWriter(stream, encoder))
                        {
                            XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
                            ns.Add("", "");
                            serializer.Serialize(streamWriter, value, ns);
                        }
                    });
        }
    }
}