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