Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/314.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/wcf/4.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# 为数组属性指定xsi:type_C#_Wcf_Xmlserializer - Fatal编程技术网

C# 为数组属性指定xsi:type

C# 为数组属性指定xsi:type,c#,wcf,xmlserializer,C#,Wcf,Xmlserializer,我正在编写一个使用XmlSerializer的WCF服务。该服务是一个基于WSDL和XSD的实现,XSD是由使用该服务的组提供给我的。基本上,它是他们的系统和我的系统之间的数据适配器 一个特定类具有一个属性,该属性是项目中定义的另一个引用类型的数组。我需要为此属性指定xsi:type 我使用svcutil从WSDL和XSD生成代码,然后在几个地方“修复”生成的代码。这个财产是我必须修复的 类定义如下(仅限于问题区域): 调用服务方法时生成的XML是(userData是getUserRespons

我正在编写一个使用XmlSerializer的WCF服务。该服务是一个基于WSDL和XSD的实现,XSD是由使用该服务的组提供给我的。基本上,它是他们的系统和我的系统之间的数据适配器

一个特定类具有一个属性,该属性是项目中定义的另一个引用类型的数组。我需要为此属性指定
xsi:type

我使用svcutil从WSDL和XSD生成代码,然后在几个地方“修复”生成的代码。这个财产是我必须修复的

类定义如下(仅限于问题区域):

调用服务方法时生成的XML是(
userData
getUserResponse
类的属性):


一些钥匙
一些价值
其他的钥匙
其他价值
我需要
元素如下所示:

<myprop xsi:type="ns1:MapType"
    xmlns:ns1="urn:example.com:types"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

如何让XmlSerializer为数组属性
myprop
生成
xsi:type

我发现这些类似的问题最接近我的问题,但它们不适用于数组:

我是否需要使用自定义序列化程序执行此操作


如果我需要发布任何服务合同,请告诉我。服务中的其他一切都很好,只是这一点点。

我找不到任何方法使用任何内置机制(属性、配置等)来实现这一点,因此我最终编写了一个自定义消息检查器,在响应中发送XML之前动态修改XML。代码如下:

自定义Ispector—执行XML重写以添加所需的标记

using System.IO;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Dispatcher;
using System.Xml;

namespace MyProj
{
    public class CustomInspector : IDispatchMessageInspector
    {
        public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
        {
            return null;
        }

        public void BeforeSendReply(ref Message reply, object correlationState)
        {
            if (reply.Headers.Action == "urn:example:wsdl/Adapter/getUserResponse")
            {
                MessageBuffer copy = reply.CreateBufferedCopy(int.MaxValue);
                XmlDictionaryReader xdr = copy.CreateMessage().GetReaderAtBodyContents();
                XmlDocument doc = new XmlDocument();
                doc.Load(xdr);
                xdr.Close();

                doc.InnerXml = doc.InnerXml.Replace(@"<myprop>",
                    @"<myprop xsi:type=""ns1:MapType"" xmlns:ns1=""urn:example.com:types"" xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"">");
                doc.InnerXml = doc.InnerXml.Replace(@"<item>", @"<item xmlns=""urn:example.com:types"">");

                MemoryStream ms = new MemoryStream();
                XmlWriter xw = XmlWriter.Create(ms);
                doc.Save(xw);
                xw.Flush();
                xw.Close();
                ms.Position = 0;
                XmlReader reader = XmlReader.Create(ms);


                Message newMsg = Message.CreateMessage(reply.Version, reply.Headers.Action, reader);
                reply = newMsg;
            }

        }
    }
}
自定义行为扩展元素-定义新行为

using System;
using System.ServiceModel.Configuration;

namespace KeypadIdmAdaptor
{
    public class CustomBehaviorExtensionElement : BehaviorExtensionElement
    {
        protected override object CreateBehavior()
        {
            return new CustomBehavior();
        }

        public override Type BehaviorType
        {
            get { return typeof(CustomBehavior); }
        }
    }
}
将其连接到web.config:

  <system.serviceModel>
    <extensions>
      <behaviorExtensions>
        <add name="CustomBehaviorExtension" type="MyProj.CustomBehaviorExtensionElement, MyProj, Version=1.0.0.0, Culture=neutral" />
      </behaviorExtensions>
    </extensions>
    <behaviors>
      <endpointBehaviors>
        <behavior>
          <CustomBehaviorExtension />
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="false" />
          <serviceDebug includeExceptionDetailInFaults="false" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <service name="MyProj.MyService">
        <endpoint binding="mexHttpBinding" address="mex" contract="IMetadataExchange"></endpoint>
        <endpoint name="MyServiceEndpoint" binding="basicHttpBinding" contract="MyProjServiceContract"></endpoint>
      </service>
    </services>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>

下面是响应消息中生成的XML:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
   <s:Body>
      <getUserResponse xmlns="urn:example.com:types">
         <userData>
            <myProp xsi:type="ns1:MapType" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns1="urn:example.com:types">
               <item>
                  <key>some key</key>
                  <value>some value</value>
               </item>
               <item>
                  <key>some other key</key>
                  <value>some other value</value>
               </item>
            </myProp >
         </userData>
      </getUserResponse>
   </s:Body>
</s:Envelope>

一些钥匙
一些价值
其他的钥匙
其他价值

我找不到使用任何内置机制(属性、配置等)来实现这一点的方法,因此我最终编写了一个自定义消息检查器,在响应中发送XML之前动态修改XML。代码如下:

自定义Ispector—执行XML重写以添加所需的标记

using System.IO;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Dispatcher;
using System.Xml;

namespace MyProj
{
    public class CustomInspector : IDispatchMessageInspector
    {
        public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
        {
            return null;
        }

        public void BeforeSendReply(ref Message reply, object correlationState)
        {
            if (reply.Headers.Action == "urn:example:wsdl/Adapter/getUserResponse")
            {
                MessageBuffer copy = reply.CreateBufferedCopy(int.MaxValue);
                XmlDictionaryReader xdr = copy.CreateMessage().GetReaderAtBodyContents();
                XmlDocument doc = new XmlDocument();
                doc.Load(xdr);
                xdr.Close();

                doc.InnerXml = doc.InnerXml.Replace(@"<myprop>",
                    @"<myprop xsi:type=""ns1:MapType"" xmlns:ns1=""urn:example.com:types"" xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"">");
                doc.InnerXml = doc.InnerXml.Replace(@"<item>", @"<item xmlns=""urn:example.com:types"">");

                MemoryStream ms = new MemoryStream();
                XmlWriter xw = XmlWriter.Create(ms);
                doc.Save(xw);
                xw.Flush();
                xw.Close();
                ms.Position = 0;
                XmlReader reader = XmlReader.Create(ms);


                Message newMsg = Message.CreateMessage(reply.Version, reply.Headers.Action, reader);
                reply = newMsg;
            }

        }
    }
}
自定义行为扩展元素-定义新行为

using System;
using System.ServiceModel.Configuration;

namespace KeypadIdmAdaptor
{
    public class CustomBehaviorExtensionElement : BehaviorExtensionElement
    {
        protected override object CreateBehavior()
        {
            return new CustomBehavior();
        }

        public override Type BehaviorType
        {
            get { return typeof(CustomBehavior); }
        }
    }
}
将其连接到web.config:

  <system.serviceModel>
    <extensions>
      <behaviorExtensions>
        <add name="CustomBehaviorExtension" type="MyProj.CustomBehaviorExtensionElement, MyProj, Version=1.0.0.0, Culture=neutral" />
      </behaviorExtensions>
    </extensions>
    <behaviors>
      <endpointBehaviors>
        <behavior>
          <CustomBehaviorExtension />
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="false" />
          <serviceDebug includeExceptionDetailInFaults="false" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <service name="MyProj.MyService">
        <endpoint binding="mexHttpBinding" address="mex" contract="IMetadataExchange"></endpoint>
        <endpoint name="MyServiceEndpoint" binding="basicHttpBinding" contract="MyProjServiceContract"></endpoint>
      </service>
    </services>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>

下面是响应消息中生成的XML:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
   <s:Body>
      <getUserResponse xmlns="urn:example.com:types">
         <userData>
            <myProp xsi:type="ns1:MapType" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns1="urn:example.com:types">
               <item>
                  <key>some key</key>
                  <value>some value</value>
               </item>
               <item>
                  <key>some other key</key>
                  <value>some other value</value>
               </item>
            </myProp >
         </userData>
      </getUserResponse>
   </s:Body>
</s:Envelope>

一些钥匙
一些价值
其他的钥匙
其他价值