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