1 //------------------------------------------------------------ 2 // Copyright (c) Microsoft Corporation. All rights reserved. 3 //------------------------------------------------------------ 4 namespace System.ServiceModel.Channels 5 { 6 using System.Collections.Generic; 7 using System.ServiceModel.Description; 8 using System.Runtime.Serialization; 9 using System.ServiceModel.Channels; 10 using System.ServiceModel; 11 using System.Text; 12 using System.Xml; 13 using System.ComponentModel; 14 15 public sealed class MtomMessageEncodingBindingElement : MessageEncodingBindingElement, IWsdlExportExtension, IPolicyExportExtension 16 { 17 int maxReadPoolSize; 18 int maxWritePoolSize; 19 XmlDictionaryReaderQuotas readerQuotas; 20 int maxBufferSize; 21 Encoding writeEncoding; 22 MessageVersion messageVersion; 23 MtomMessageEncodingBindingElement()24 public MtomMessageEncodingBindingElement() 25 : this(MessageVersion.Default, TextEncoderDefaults.Encoding) 26 { 27 } 28 MtomMessageEncodingBindingElement(MessageVersion messageVersion, Encoding writeEncoding)29 public MtomMessageEncodingBindingElement(MessageVersion messageVersion, Encoding writeEncoding) 30 { 31 if (messageVersion == null) 32 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("messageVersion"); 33 34 if (messageVersion == MessageVersion.None) 35 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.MtomEncoderBadMessageVersion, messageVersion.ToString()), "messageVersion")); 36 37 if (writeEncoding == null) 38 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("writeEncoding"); 39 40 TextEncoderDefaults.ValidateEncoding(writeEncoding); 41 this.maxReadPoolSize = EncoderDefaults.MaxReadPoolSize; 42 this.maxWritePoolSize = EncoderDefaults.MaxWritePoolSize; 43 this.readerQuotas = new XmlDictionaryReaderQuotas(); 44 EncoderDefaults.ReaderQuotas.CopyTo(this.readerQuotas); 45 this.maxBufferSize = MtomEncoderDefaults.MaxBufferSize; 46 this.messageVersion = messageVersion; 47 this.writeEncoding = writeEncoding; 48 } 49 MtomMessageEncodingBindingElement(MtomMessageEncodingBindingElement elementToBeCloned)50 MtomMessageEncodingBindingElement(MtomMessageEncodingBindingElement elementToBeCloned) 51 : base(elementToBeCloned) 52 { 53 this.maxReadPoolSize = elementToBeCloned.maxReadPoolSize; 54 this.maxWritePoolSize = elementToBeCloned.maxWritePoolSize; 55 this.readerQuotas = new XmlDictionaryReaderQuotas(); 56 elementToBeCloned.readerQuotas.CopyTo(this.readerQuotas); 57 this.maxBufferSize = elementToBeCloned.maxBufferSize; 58 this.writeEncoding = elementToBeCloned.writeEncoding; 59 this.messageVersion = elementToBeCloned.messageVersion; 60 } 61 62 [DefaultValue(EncoderDefaults.MaxReadPoolSize)] 63 public int MaxReadPoolSize 64 { 65 get 66 { 67 return this.maxReadPoolSize; 68 } 69 set 70 { 71 if (value <= 0) 72 { 73 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value", value, 74 SR.GetString(SR.ValueMustBePositive))); 75 } 76 this.maxReadPoolSize = value; 77 } 78 } 79 80 [DefaultValue(EncoderDefaults.MaxWritePoolSize)] 81 public int MaxWritePoolSize 82 { 83 get 84 { 85 return this.maxWritePoolSize; 86 } 87 set 88 { 89 if (value <= 0) 90 { 91 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value", value, 92 SR.GetString(SR.ValueMustBePositive))); 93 } 94 this.maxWritePoolSize = value; 95 } 96 } 97 98 public XmlDictionaryReaderQuotas ReaderQuotas 99 { 100 get 101 { 102 return this.readerQuotas; 103 } 104 } 105 106 [DefaultValue(MtomEncoderDefaults.MaxBufferSize)] 107 public int MaxBufferSize 108 { 109 get 110 { 111 return this.maxBufferSize; 112 } 113 set 114 { 115 if (value <= 0) 116 { 117 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value", value, 118 SR.GetString(SR.ValueMustBePositive))); 119 } 120 this.maxBufferSize = value; 121 } 122 } 123 124 [TypeConverter(typeof(System.ServiceModel.Configuration.EncodingConverter))] 125 public Encoding WriteEncoding 126 { 127 get 128 { 129 return this.writeEncoding; 130 } 131 set 132 { 133 if (value == null) 134 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("value"); 135 136 TextEncoderDefaults.ValidateEncoding(value); 137 this.writeEncoding = value; 138 } 139 } 140 141 public override MessageVersion MessageVersion 142 { 143 get 144 { 145 return this.messageVersion; 146 } 147 set 148 { 149 if (value == null) 150 { 151 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("value"); 152 } 153 if (value == MessageVersion.None) 154 { 155 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.MtomEncoderBadMessageVersion, value.ToString()), "value")); 156 } 157 158 this.messageVersion = value; 159 } 160 } 161 BuildChannelFactory(BindingContext context)162 public override IChannelFactory<TChannel> BuildChannelFactory<TChannel>(BindingContext context) 163 { 164 return InternalBuildChannelFactory<TChannel>(context); 165 } 166 CanBuildChannelFactory(BindingContext context)167 public override bool CanBuildChannelFactory<TChannel>(BindingContext context) 168 { 169 return InternalCanBuildChannelFactory<TChannel>(context); 170 } 171 BuildChannelListener(BindingContext context)172 public override IChannelListener<TChannel> BuildChannelListener<TChannel>(BindingContext context) 173 { 174 return InternalBuildChannelListener<TChannel>(context); 175 } 176 CanBuildChannelListener(BindingContext context)177 public override bool CanBuildChannelListener<TChannel>(BindingContext context) 178 { 179 return InternalCanBuildChannelListener<TChannel>(context); 180 } 181 Clone()182 public override BindingElement Clone() 183 { 184 return new MtomMessageEncodingBindingElement(this); 185 } 186 CreateMessageEncoderFactory()187 public override MessageEncoderFactory CreateMessageEncoderFactory() 188 { 189 return new MtomMessageEncoderFactory(MessageVersion, WriteEncoding, this.MaxReadPoolSize, this.MaxWritePoolSize, this.MaxBufferSize, this.ReaderQuotas); 190 } 191 GetProperty(BindingContext context)192 public override T GetProperty<T>(BindingContext context) 193 { 194 if (context == null) 195 { 196 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context"); 197 } 198 if (typeof(T) == typeof(XmlDictionaryReaderQuotas)) 199 { 200 return (T)(object)this.readerQuotas; 201 } 202 else 203 { 204 return base.GetProperty<T>(context); 205 } 206 } 207 IPolicyExportExtension.ExportPolicy(MetadataExporter exporter, PolicyConversionContext policyContext)208 void IPolicyExportExtension.ExportPolicy(MetadataExporter exporter, PolicyConversionContext policyContext) 209 { 210 if (policyContext == null) 211 { 212 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("policyContext"); 213 } 214 XmlDocument document = new XmlDocument(); 215 216 policyContext.GetBindingAssertions().Add(document.CreateElement( 217 MessageEncodingPolicyConstants.OptimizedMimeSerializationPrefix, 218 MessageEncodingPolicyConstants.MtomEncodingName, 219 MessageEncodingPolicyConstants.OptimizedMimeSerializationNamespace)); 220 } 221 IWsdlExportExtension.ExportContract(WsdlExporter exporter, WsdlContractConversionContext context)222 void IWsdlExportExtension.ExportContract(WsdlExporter exporter, WsdlContractConversionContext context) { } IWsdlExportExtension.ExportEndpoint(WsdlExporter exporter, WsdlEndpointConversionContext context)223 void IWsdlExportExtension.ExportEndpoint(WsdlExporter exporter, WsdlEndpointConversionContext context) 224 { 225 if (context == null) 226 { 227 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context"); 228 } 229 230 SoapHelper.SetSoapVersion(context, exporter, this.messageVersion.Envelope); 231 } 232 CheckEncodingVersion(EnvelopeVersion version)233 internal override bool CheckEncodingVersion(EnvelopeVersion version) 234 { 235 return messageVersion.Envelope == version; 236 } 237 IsMatch(BindingElement b)238 internal override bool IsMatch(BindingElement b) 239 { 240 if (!base.IsMatch(b)) 241 return false; 242 MtomMessageEncodingBindingElement mtom = b as MtomMessageEncodingBindingElement; 243 if (mtom == null) 244 return false; 245 if (this.maxReadPoolSize != mtom.MaxReadPoolSize) 246 return false; 247 if (this.maxWritePoolSize != mtom.MaxWritePoolSize) 248 return false; 249 250 // compare XmlDictionaryReaderQuotas 251 if (this.readerQuotas.MaxStringContentLength != mtom.ReaderQuotas.MaxStringContentLength) 252 return false; 253 if (this.readerQuotas.MaxArrayLength != mtom.ReaderQuotas.MaxArrayLength) 254 return false; 255 if (this.readerQuotas.MaxBytesPerRead != mtom.ReaderQuotas.MaxBytesPerRead) 256 return false; 257 if (this.readerQuotas.MaxDepth != mtom.ReaderQuotas.MaxDepth) 258 return false; 259 if (this.readerQuotas.MaxNameTableCharCount != mtom.ReaderQuotas.MaxNameTableCharCount) 260 return false; 261 262 if (this.maxBufferSize != mtom.MaxBufferSize) 263 return false; 264 265 if (this.WriteEncoding.EncodingName != mtom.WriteEncoding.EncodingName) 266 return false; 267 if (!this.MessageVersion.IsMatch(mtom.MessageVersion)) 268 return false; 269 270 return true; 271 } 272 273 [EditorBrowsable(EditorBrowsableState.Never)] ShouldSerializeMessageVersion()274 public bool ShouldSerializeMessageVersion() 275 { 276 return (!this.messageVersion.IsMatch(MessageVersion.Default)); 277 } 278 279 [EditorBrowsable(EditorBrowsableState.Never)] ShouldSerializeReaderQuotas()280 public bool ShouldSerializeReaderQuotas() 281 { 282 return (!EncoderDefaults.IsDefaultReaderQuotas(this.ReaderQuotas)); 283 } 284 285 [EditorBrowsable(EditorBrowsableState.Never)] ShouldSerializeWriteEncoding()286 public bool ShouldSerializeWriteEncoding() 287 { 288 return (this.WriteEncoding != TextEncoderDefaults.Encoding); 289 } 290 } 291 } 292