<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Customize WCF Envelope and Namespace Prefix

      轉自:http://vanacosmin.ro/Articles/Read/WCFEnvelopeNamespacePrefix

      Introduction

      WCF allows you to customize the response using DataContract, MessageContract or XmlSerializer. With DataContract you have access only to the body of the message while MessageContract will let you control the headers of the message too. However, you don't have any control over namespace prefixes or on the soap envelope tag from the response message.

      When generating the response, WCF uses some default namespaces prefixes and we cannot control this from configuration. For example, <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">. Normally, the prefix should not be a problem according to SOAP standards. However, there are times when we need to support old clients who manually parse the response and they expect fixed format or look for specific prefixes.

      Real world example

      Recently, I was asked to rewrite an old service using .NET and WCF, keeping compatibility with existing clients. The response from WCF looked like this:

      <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
        <s:Body>
          <GetCardInfoResponse xmlns="https://vanacosmin.ro/WebService/soap/" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
            <control_area>
              <source>OVF</source>
              <ns1:source_send_date>2014-01-06T14:15:37.1505943+01:00</ns1:source_send_date>
              <api_key/>
              <message_id>27970411614463393270</message_id>
              <correlation_id>1</correlation_id>
            </control_area>
            <chip_uid>1111</chip_uid>
            <tls_engraved_id>************1111</tls_engraved_id>
            <reference_id/>
            <is_blocked>false</is_blocked>
            <is_useable>false</is_useable>
            <registration_date>2013-12-13T13:06:39.75</registration_date>
            <last_modification>2013-12-20T15:48:52.307</last_modification>
          </GetCardInfoResponse>
        </s:Body>
      </s:Envelope>

      The expected response for existing clients was:

      <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"xmlns:ns1="https://vanacosmin.ro/WebService/soap/">
        <SOAP-ENV:Body>
          <ns1:GetCardInfoResponse xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
            <ns1:control_area>
              <ns1:source>OVF</ns1:source>
              <ns1:source_send_date>2014-01-06T14:15:37.1505943+01:00</ns1:source_send_date>
              <ns1:api_key/>
              <ns1:message_id>27970411614463393270</ns1:message_id>
              <ns1:correlation_id>1</ns1:correlation_id>
            </ns1:control_area>
            <ns1:chip_uid>1111</ns1:chip_uid>
            <ns1:tls_engraved_id>************1111</ns1:tls_engraved_id>
            <ns1:reference_id/>
            <ns1:is_blocked>false</ns1:is_blocked>
            <ns1:is_useable>false</ns1:is_useable>
            <ns1:registration_date>2013-12-13T13:06:39.75</ns1:registration_date>
            <ns1:last_modification>2013-12-20T15:48:52.307</ns1:last_modification>
          </ns1:GetCardInfoResponse>
        </SOAP-ENV:Body>
      </SOAP-ENV:Envelope>

      The two messages are equivalent from SOAP or XML perspective. What I needed to do in order to obtain the expected result was:

      • Change the namespace prefix for SOAP envelope
      • Add another namespace with the prefix ns1 in the SOAP envelope
      • Remove the namespace from s:body (because it was moved on a top level)

      Possible solutions

      There are multiple extension points where the message can be altered

      Custom MessageEncoder

      You can alter the xml output using a MessageEncoder. A good example about this can be found here.

      This approach has several disadvantages, as the author also pointed out in the end of the article:

      • The message encoder is activated late in the WCF pipeline. If you have message security, a hash is already included in the message. Changing the message will invalidate the hash.
      • You can build a custom channel so that the changing of the message takes place before the hash is calculated. This is complicated, and the next drawback applies.
      • If you are using a message inspector (e.g. for logging), you will log the message in its initial state, and not in the form sent to the customer.
      • If you make big changes to the message, your wsdl contract will not work, so you need to do additional work for metadata exchange, if you want your service to be consumed by new clients without manually parsing your message.

      Custom MessageFormatter and a derived Message class

      The MessageFormatter is used to transform the result of your method into an instance of Message class. This instance is then passed in the WCF pipeline (message inspectors, channels, encoders). This is the right place to transform your message because all the other extension points will work with the exact same message that you are sending to your clients

      The following diagram shows how the message is sent accross different layers in WCF pipeline. You can see that the MessageFormatter is just before the MessageInspector when you send a message from server to client, while the MessageEncoder is a side component which is activated right before the transport layer.

      Additional information about the diagram can be found here

      Creating a custom MessageFormatter

      First, you need to create a IDispatchMessageFormatter class. This is the message formatter. The SerializeReply method will return an instance of your custom Message class.

          public class MyCustomMessageFormatter : IDispatchMessageFormatter     {
              private readonly IDispatchMessageFormatter formatter;
       
              public MyCustomMessageFormatter(IDispatchMessageFormatter formatter)
              {
                  this.formatter= formatter;
              }
       
              public void DeserializeRequest(Message message, object[]parameters)
              {
                  this.formatter.DeserializeRequest(message,parameters);
              }
       
              public Message SerializeReply(MessageVersion messageVersion, object[]parameters, object result)
              {
                  var message = this.formatter.SerializeReply(messageVersion, parameters, result);
                  return new MyCustomMessage(message);
              }
          }

      Inherit from Message class

      Custom message class

      This is the class that will allow you to alter the output of your service.

      public class MyCustomMessage : Message
      {
          private readonly Message message;
       
          public MyCustomMessage(Message message)
          {
              this.message= message;
          }
          public override MessageHeaders Headers
          {
              get { return this.message.Headers;}
          }
          public override MessageProperties Properties
          {
              get { return this.message.Properties;}
          }
          public override MessageVersion Version
          {
             get { return this.message.Version;}
          }
          protected override void OnWriteStartBody(XmlDictionaryWriter writer)
          {
              writer.WriteStartElement("Body", "http://schemas.xmlsoap.org/soap/envelope/");
          }
          protected override void OnWriteBodyContents(XmlDictionaryWriter writer)
          {
              this.message.WriteBodyContents(writer);
          }
          protected override void OnWriteStartEnvelope(XmlDictionaryWriter writer)
          {
              writer.WriteStartElement("SOAP-ENV", "Envelope", "http://schemas.xmlsoap.org/soap/envelope/");
              writer.WriteAttributeString("xmlns", "ns1", null,"https://vanacosmin.ro/WebService/soap/");
          }
      }

      Custom message class explained

      The derived Message class has several overrides that you can use to obtain the required XML:

      • All the methods will use the same XmlDictionaryWriter. This means that if you add a namespace with a prefix, that prefix will be used for the next elements that you add in the same namespace.
      • OnWriteStartEnvelope Method is called first. By default this method will write the s prefix and will add namespaces according to the soap version. I use this method to change the prefix to "SOAP-ENV" and also to add the ns1 namespace.
      • OnWriteStartBody is called second. By default, this method will still use the prefix s for body. This is why I had to override it and write the Body element using the XmlDictionaryWriter.
      • OnWriteBodyContents is called last in this sequence. By calling WriteBodyContents on the original message, I will get the expected result because I have declared the namespace ns1 at the top level
      • There are other methods that you can override if you need more flexibility.

      Activate the MessageFormatter

      To activate the MessageFormatter we will create an OperationBehavior attribute that must be applied to the methods (on the interface) that we want to use this MessageFormatter.

      [AttributeUsage(AttributeTargets.Method)]
      public class MobilityProviderFormatMessageAttribute : Attribute, IOperationBehavior
      {
          public void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters) { }
       
          public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation) { }
       
          public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
          {
              var serializerBehavior =operationDescription.Behaviors.Find<DataContractSerializerOperationBehavior>();
       

      posted @ 2014-12-04 12:04  tyb1222  閱讀(1107)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 中文字幕成人精品久久不卡| 日韩精品一区二区三区视频| 亚洲一区二区三区久久受| 97人妻中文字幕总站| 国产视频 视频一区二区| 久久精品国产6699国产精| 热久久这里只有精品国产| 国产在线无码不卡播放| 亚洲精品自拍在线视频| 亚洲人成色7777在线观看不卡| 国产麻豆精品一区一区三区| 亚洲成人av在线资源| 成人午夜av在线播放| 人妻精品动漫H无码中字| 国产美女被遭强高潮免费一视频| 国内免费视频成人精品| 亚洲av无码精品色午夜| 国产99在线 | 免费| 国产免费播放一区二区三区| 国产精品亚洲五月天高清| 国产精品一区二区中文| 中文字幕在线视频不卡一区二区 | 国产成人综合欧美精品久久| 日韩V欧美V中文在线| 日韩亚洲精品中文字幕| 少妇办公室好紧好爽再浪一点 | 无遮挡午夜男女xx00动态| 尹人香蕉久久99天天拍| 国产片AV国语在线观看手机版| 免费看的一级黄色片永久| 国产精品黄色片| 日韩乱码人妻无码系列中文字幕| 亚洲性日韩精品一区二区| 麻豆精品传媒一二三区| 亚洲精品一区二区区别| 农村乱色一区二区高清视频| 综合无码一区二区三区| 精品一区二区无码免费| 亚洲精品一区二区麻豆| 丰满少妇被猛烈进出69影院| 加勒比无码人妻东京热|