Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / NetFx35 / System.ServiceModel.Web / System / ServiceModel / Channels / JsonMessageEncoderFactory.cs / 1305376 / JsonMessageEncoderFactory.cs
//------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------- namespace System.ServiceModel.Channels { using System.Globalization; using System.IO; using System.Runtime; using System.Runtime.Serialization.Json; using System.ServiceModel.Diagnostics; using System.Text; using System.Xml; using System.ServiceModel.Web; using System.Net; class JsonMessageEncoderFactory : MessageEncoderFactory { static readonly TextMessageEncoderFactory.ContentEncoding[] ApplicationJsonContentEncoding = GetContentEncodingMap(JsonGlobals.applicationJsonMediaType); JsonMessageEncoder messageEncoder; public JsonMessageEncoderFactory(Encoding writeEncoding, int maxReadPoolSize, int maxWritePoolSize, XmlDictionaryReaderQuotas quotas, bool crossDomainScriptAccessEnabled) { messageEncoder = new JsonMessageEncoder(writeEncoding, maxReadPoolSize, maxWritePoolSize, quotas, crossDomainScriptAccessEnabled); } public override MessageEncoder Encoder { get { return messageEncoder; } } public override MessageVersion MessageVersion { get { return messageEncoder.MessageVersion; } } internal static string GetContentType(WebMessageEncodingBindingElement encodingElement) { if (encodingElement == null) { return WebMessageEncoderFactory.GetContentType(JsonGlobals.applicationJsonMediaType, TextEncoderDefaults.Encoding); } else { return WebMessageEncoderFactory.GetContentType(JsonGlobals.applicationJsonMediaType, encodingElement.WriteEncoding); } } static TextMessageEncoderFactory.ContentEncoding[] GetContentEncodingMap(string mediaType) { Encoding[] readEncodings = TextMessageEncoderFactory.GetSupportedEncodings(); TextMessageEncoderFactory.ContentEncoding[] map = new TextMessageEncoderFactory.ContentEncoding[readEncodings.Length]; for (int i = 0; i < readEncodings.Length; i++) { TextMessageEncoderFactory.ContentEncoding contentEncoding = new TextMessageEncoderFactory.ContentEncoding(); contentEncoding.contentType = WebMessageEncoderFactory.GetContentType(mediaType, readEncodings[i]); contentEncoding.encoding = readEncodings[i]; map[i] = contentEncoding; } return map; } class JsonMessageEncoder : MessageEncoder { const int maxPooledXmlReadersPerMessage = 2; SynchronizedPoolbufferedReaderPool; SynchronizedPool bufferedWriterPool; string contentType; int maxReadPoolSize; int maxWritePoolSize; OnXmlDictionaryReaderClose onStreamedReaderClose; XmlDictionaryReaderQuotas readerQuotas; SynchronizedPool recycledStatePool; SynchronizedPool streamedReaderPool; SynchronizedPool streamedWriterPool; object thisLock; Encoding writeEncoding; bool crossDomainScriptAccessEnabled; byte[] encodedClosingFunctionCall; public JsonMessageEncoder(Encoding writeEncoding, int maxReadPoolSize, int maxWritePoolSize, XmlDictionaryReaderQuotas quotas, bool crossDomainScriptAccessEnabled) { if (writeEncoding == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("writeEncoding"); } thisLock = new object(); TextEncoderDefaults.ValidateEncoding(writeEncoding); this.writeEncoding = writeEncoding; this.maxReadPoolSize = maxReadPoolSize; this.maxWritePoolSize = maxWritePoolSize; this.readerQuotas = new XmlDictionaryReaderQuotas(); this.onStreamedReaderClose = new OnXmlDictionaryReaderClose(ReturnStreamedReader); quotas.CopyTo(this.readerQuotas); this.contentType = WebMessageEncoderFactory.GetContentType(JsonGlobals.applicationJsonMediaType, writeEncoding); this.crossDomainScriptAccessEnabled = crossDomainScriptAccessEnabled; this.encodedClosingFunctionCall = this.writeEncoding.GetBytes(");"); } public override string ContentType { get { return contentType; } } public override string MediaType { get { return JsonGlobals.applicationJsonMediaType; } } public override MessageVersion MessageVersion { get { return MessageVersion.None; } } SynchronizedPool RecycledStatePool { get { if (recycledStatePool == null) { lock (ThisLock) { if (recycledStatePool == null) { recycledStatePool = new SynchronizedPool (maxReadPoolSize); } } } return recycledStatePool; } } object ThisLock { get { return thisLock; } } public override bool IsContentTypeSupported(string contentType) { if (contentType == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("contentType"); } return IsJsonContentType(contentType); } public override Message ReadMessage(ArraySegment buffer, BufferManager bufferManager, string contentType) { if (bufferManager == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("bufferManager")); } Message message; JsonBufferedMessageData messageData = TakeBufferedReader(); messageData.Encoding = TextMessageEncoderFactory.GetEncodingFromContentType(contentType, JsonMessageEncoderFactory.ApplicationJsonContentEncoding); messageData.Open(buffer, bufferManager); RecycledMessageState messageState = messageData.TakeMessageState(); if (messageState == null) { messageState = new RecycledMessageState(); } message = new BufferedMessage(messageData, messageState); message.Properties.Encoder = this; if (MessageLogger.LogMessagesAtTransportLevel) { MessageLogger.LogMessage(ref message, MessageLoggingSource.TransportReceive); } return message; } public override Message ReadMessage(Stream stream, int maxSizeOfHeaders, string contentType) { if (stream == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("stream")); } XmlReader reader = TakeStreamedReader(stream, TextMessageEncoderFactory.GetEncodingFromContentType(contentType, JsonMessageEncoderFactory.ApplicationJsonContentEncoding)); Message message = Message.CreateMessage(reader, maxSizeOfHeaders, MessageVersion.None); message.Properties.Encoder = this; if (MessageLogger.LogMessagesAtTransportLevel) { MessageLogger.LogMessage(ref message, MessageLoggingSource.TransportReceive); } return message; } public override ArraySegment WriteMessage(Message message, int maxMessageSize, BufferManager bufferManager, int messageOffset) { if (message == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("message")); } if (bufferManager == null) { throw TraceUtility.ThrowHelperError(new ArgumentNullException("bufferManager"), message); } if (maxMessageSize < 0) { throw TraceUtility.ThrowHelperError(new ArgumentOutOfRangeException("maxMessageSize", maxMessageSize, SR2.GetString(SR2.ValueMustBeNonNegative)), message); } if (messageOffset < 0 || messageOffset > maxMessageSize) { throw TraceUtility.ThrowHelperError(new ArgumentOutOfRangeException("messageOffset", messageOffset, SR2.GetString(SR2.JsonValueMustBeInRange, 0, maxMessageSize)), message); } ThrowIfMismatchedMessageVersion(message); message.Properties.Encoder = this; JsonBufferedMessageWriter messageWriter = TakeBufferedWriter(); JavascriptCallbackResponseMessageProperty javascriptResponseMessageProperty; if (message.Properties.TryGetValue (JavascriptCallbackResponseMessageProperty.Name, out javascriptResponseMessageProperty) && javascriptResponseMessageProperty != null) { if (this.crossDomainScriptAccessEnabled) { messageWriter.SetJavascriptCallbackProperty(javascriptResponseMessageProperty); } else { throw TraceUtility.ThrowHelperError(new InvalidOperationException(SR2.JavascriptCallbackNotEnabled), message); } } ArraySegment messageData = messageWriter.WriteMessage(message, bufferManager, messageOffset, maxMessageSize); ReturnMessageWriter(messageWriter); if (MessageLogger.LogMessagesAtTransportLevel) { XmlDictionaryReader xmlDictionaryReader = JsonReaderWriterFactory.CreateJsonReader( messageData.Array, messageData.Offset, messageData.Count, null, XmlDictionaryReaderQuotas.Max, null); MessageLogger.LogMessage(ref message, xmlDictionaryReader, MessageLoggingSource.TransportSend); } return messageData; } public override void WriteMessage(Message message, Stream stream) { if (message == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("message")); } if (stream == null) { throw TraceUtility.ThrowHelperError(new ArgumentNullException("stream"), message); } ThrowIfMismatchedMessageVersion(message); message.Properties.Encoder = this; XmlDictionaryWriter xmlWriter = TakeStreamedWriter(stream); JavascriptCallbackResponseMessageProperty javascriptResponseMessageProperty; if (message.Properties.TryGetValue (JavascriptCallbackResponseMessageProperty.Name, out javascriptResponseMessageProperty) && javascriptResponseMessageProperty != null && !String.IsNullOrEmpty(javascriptResponseMessageProperty.CallbackFunctionName)) { if (!this.crossDomainScriptAccessEnabled) { throw TraceUtility.ThrowHelperError(new InvalidOperationException(SR2.JavascriptCallbackNotEnabled), message); } byte[] buffer = this.writeEncoding.GetBytes(String.Format(CultureInfo.InvariantCulture, "{0}(", javascriptResponseMessageProperty.CallbackFunctionName)); stream.Write(buffer, 0, buffer.Length); } xmlWriter.WriteStartDocument(); message.WriteMessage(xmlWriter); xmlWriter.WriteEndDocument(); xmlWriter.Flush(); ReturnStreamedWriter(xmlWriter); if (javascriptResponseMessageProperty != null && !String.IsNullOrEmpty(javascriptResponseMessageProperty.CallbackFunctionName)) { if (javascriptResponseMessageProperty.StatusCode != null && (int)javascriptResponseMessageProperty.StatusCode != 200) { byte[] buffer = this.writeEncoding.GetBytes(String.Format(CultureInfo.InvariantCulture, ",{0}", (int)javascriptResponseMessageProperty.StatusCode)); stream.Write(buffer, 0, buffer.Length); } stream.Write(this.encodedClosingFunctionCall, 0, this.encodedClosingFunctionCall.Length); } if (MessageLogger.LogMessagesAtTransportLevel) { MessageLogger.LogMessage(ref message, MessageLoggingSource.TransportSend); } } internal override bool IsCharSetSupported(string charSet) { Encoding tmp; return TextEncoderDefaults.TryGetEncoding(charSet, out tmp); } bool IsJsonContentType(string contentType) { return IsContentTypeSupported(contentType, JsonGlobals.applicationJsonMediaType, JsonGlobals.applicationJsonMediaType) || IsContentTypeSupported(contentType, JsonGlobals.textJsonMediaType, JsonGlobals.textJsonMediaType); } void ReturnBufferedData(JsonBufferedMessageData messageData) { bufferedReaderPool.Return(messageData); } void ReturnMessageWriter(JsonBufferedMessageWriter messageWriter) { bufferedWriterPool.Return(messageWriter); } void ReturnStreamedReader(XmlDictionaryReader xmlReader) { streamedReaderPool.Return(xmlReader); } void ReturnStreamedWriter(XmlWriter xmlWriter) { xmlWriter.Close(); streamedWriterPool.Return((XmlDictionaryWriter) xmlWriter); } JsonBufferedMessageData TakeBufferedReader() { if (bufferedReaderPool == null) { lock (ThisLock) { if (bufferedReaderPool == null) { bufferedReaderPool = new SynchronizedPool (maxReadPoolSize); } } } JsonBufferedMessageData messageData = bufferedReaderPool.Take(); if (messageData == null) { messageData = new JsonBufferedMessageData(this, maxPooledXmlReadersPerMessage); } return messageData; } JsonBufferedMessageWriter TakeBufferedWriter() { if (bufferedWriterPool == null) { lock (ThisLock) { if (bufferedWriterPool == null) { bufferedWriterPool = new SynchronizedPool (maxWritePoolSize); } } } JsonBufferedMessageWriter messageWriter = bufferedWriterPool.Take(); if (messageWriter == null) { messageWriter = new JsonBufferedMessageWriter(this); } return messageWriter; } XmlDictionaryReader TakeStreamedReader(Stream stream, Encoding enc) { if (streamedReaderPool == null) { lock (ThisLock) { if (streamedReaderPool == null) { streamedReaderPool = new SynchronizedPool (maxReadPoolSize); } } } XmlDictionaryReader xmlReader = streamedReaderPool.Take(); if (xmlReader == null) { xmlReader = JsonReaderWriterFactory.CreateJsonReader(stream, enc, this.readerQuotas, this.onStreamedReaderClose); } else { ((IXmlJsonReaderInitializer) xmlReader).SetInput(stream, enc, this.readerQuotas, this.onStreamedReaderClose); } return xmlReader; } XmlDictionaryWriter TakeStreamedWriter(Stream stream) { if (streamedWriterPool == null) { lock (ThisLock) { if (streamedWriterPool == null) { streamedWriterPool = new SynchronizedPool (maxWritePoolSize); } } } XmlDictionaryWriter xmlWriter = streamedWriterPool.Take(); if (xmlWriter == null) { xmlWriter = JsonReaderWriterFactory.CreateJsonWriter(stream, this.writeEncoding, false); } else { ((IXmlJsonWriterInitializer) xmlWriter).SetOutput(stream, this.writeEncoding, false); } return xmlWriter; } class JsonBufferedMessageData : BufferedMessageData { Encoding encoding; JsonMessageEncoder messageEncoder; OnXmlDictionaryReaderClose onClose; Pool readerPool; public JsonBufferedMessageData(JsonMessageEncoder messageEncoder, int maxReaderPoolSize) : base(messageEncoder.RecycledStatePool) { this.messageEncoder = messageEncoder; readerPool = new Pool (maxReaderPoolSize); onClose = new OnXmlDictionaryReaderClose(OnXmlReaderClosed); } public override MessageEncoder MessageEncoder { get { return messageEncoder; } } public override XmlDictionaryReaderQuotas Quotas { get { return messageEncoder.readerQuotas; } } internal Encoding Encoding { set { this.encoding = value; } } protected override void OnClosed() { messageEncoder.ReturnBufferedData(this); } protected override void ReturnXmlReader(XmlDictionaryReader xmlReader) { if (xmlReader != null) { readerPool.Return(xmlReader); } } protected override XmlDictionaryReader TakeXmlReader() { ArraySegment buffer = this.Buffer; XmlDictionaryReader xmlReader = readerPool.Take(); if (xmlReader == null) { xmlReader = JsonReaderWriterFactory.CreateJsonReader(buffer.Array, buffer.Offset, buffer.Count, this.encoding, messageEncoder.readerQuotas, onClose); } else { ((IXmlJsonReaderInitializer) xmlReader).SetInput(buffer.Array, buffer.Offset, buffer.Count, this.encoding, messageEncoder.readerQuotas, onClose); } return xmlReader; } } class JsonBufferedMessageWriter : BufferedMessageWriter { JsonMessageEncoder messageEncoder; XmlDictionaryWriter returnedWriter; JavascriptXmlWriterWrapper javascriptWrapper; public JsonBufferedMessageWriter(JsonMessageEncoder messageEncoder) { this.messageEncoder = messageEncoder; } public void SetJavascriptCallbackProperty(JavascriptCallbackResponseMessageProperty javascriptResponseMessageProperty) { if (this.javascriptWrapper == null) { this.javascriptWrapper = new JavascriptXmlWriterWrapper(this.messageEncoder.writeEncoding) { JavascriptResponseMessageProperty = javascriptResponseMessageProperty }; } else { this.javascriptWrapper.JavascriptResponseMessageProperty = javascriptResponseMessageProperty; } } protected override void OnWriteEndMessage(XmlDictionaryWriter writer) { writer.WriteEndDocument(); } protected override void OnWriteStartMessage(XmlDictionaryWriter writer) { writer.WriteStartDocument(); } protected override void ReturnXmlWriter(XmlDictionaryWriter writer) { writer.Close(); if (writer is JavascriptXmlWriterWrapper) { if (this.javascriptWrapper == null) { this.javascriptWrapper = (JavascriptXmlWriterWrapper)writer; this.javascriptWrapper.JavascriptResponseMessageProperty = null; writer = this.javascriptWrapper.XmlJsonWriter; } } if (this.returnedWriter == null) { this.returnedWriter = writer; } } protected override XmlDictionaryWriter TakeXmlWriter(Stream stream) { XmlDictionaryWriter writer = null; if (this.returnedWriter == null) { writer = JsonReaderWriterFactory.CreateJsonWriter(stream, messageEncoder.writeEncoding, false); } else { writer = this.returnedWriter; ((IXmlJsonWriterInitializer)writer).SetOutput(stream, messageEncoder.writeEncoding, false); this.returnedWriter = null; } if (this.javascriptWrapper != null && this.javascriptWrapper.JavascriptResponseMessageProperty != null) { this.javascriptWrapper.SetOutput(stream, writer); writer = this.javascriptWrapper; this.javascriptWrapper = null; } return writer; } } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- FragmentQuery.cs
- StringDictionaryCodeDomSerializer.cs
- HttpServerVarsCollection.cs
- ImportCatalogPart.cs
- DataErrorValidationRule.cs
- ProfileEventArgs.cs
- ListBindableAttribute.cs
- StrokeCollectionConverter.cs
- LinkGrep.cs
- BooleanFunctions.cs
- IImplicitResourceProvider.cs
- AttachedPropertyMethodSelector.cs
- DateTimeConverter.cs
- DiscoveryExceptionDictionary.cs
- List.cs
- SchemaObjectWriter.cs
- AnnotationResourceChangedEventArgs.cs
- HostingEnvironmentWrapper.cs
- BackgroundFormatInfo.cs
- ElapsedEventArgs.cs
- PolyQuadraticBezierSegment.cs
- CompiledRegexRunnerFactory.cs
- ZipIORawDataFileBlock.cs
- HtmlTableCellCollection.cs
- SystemFonts.cs
- EntityDataSourceMemberPath.cs
- SqlStream.cs
- CrossContextChannel.cs
- DtdParser.cs
- ImpersonateTokenRef.cs
- Substitution.cs
- ExtenderProvidedPropertyAttribute.cs
- SolidColorBrush.cs
- FileUpload.cs
- XmlAttributeProperties.cs
- XmlChoiceIdentifierAttribute.cs
- Base64WriteStateInfo.cs
- TextRangeBase.cs
- Validator.cs
- DelegatingConfigHost.cs
- SupportingTokenAuthenticatorSpecification.cs
- TemplateLookupAction.cs
- BevelBitmapEffect.cs
- ValidationUtility.cs
- XPathNavigatorKeyComparer.cs
- SafeRightsManagementQueryHandle.cs
- UInt16Storage.cs
- HtmlLinkAdapter.cs
- SiteMapPathDesigner.cs
- Asn1IntegerConverter.cs
- AsyncPostBackErrorEventArgs.cs
- PeerCollaboration.cs
- ProfileSection.cs
- QilInvokeEarlyBound.cs
- ProcessInputEventArgs.cs
- FontUnitConverter.cs
- RewritingPass.cs
- XmlIlVisitor.cs
- WhitespaceRule.cs
- GeometryCollection.cs
- Triangle.cs
- Tokenizer.cs
- DatatypeImplementation.cs
- ToggleButton.cs
- ColorConverter.cs
- SetterBase.cs
- HttpModuleAction.cs
- RelationshipManager.cs
- ServiceOperation.cs
- DBConnection.cs
- UserControlParser.cs
- PerformanceCountersElement.cs
- CrossSiteScriptingValidation.cs
- MobileControlPersister.cs
- GcHandle.cs
- VectorAnimationUsingKeyFrames.cs
- TopClause.cs
- Properties.cs
- DiscardableAttribute.cs
- OletxEnlistment.cs
- MatrixCamera.cs
- QilLoop.cs
- PackageDigitalSignatureManager.cs
- PrinterUnitConvert.cs
- RequestBringIntoViewEventArgs.cs
- TemplateInstanceAttribute.cs
- BrowserDefinition.cs
- TimeIntervalCollection.cs
- SchemeSettingElement.cs
- CodeSubDirectoriesCollection.cs
- VirtualPath.cs
- WebBrowserProgressChangedEventHandler.cs
- TrackingServices.cs
- WeakReference.cs
- PackageStore.cs
- DBBindings.cs
- PolicyFactory.cs
- BrowserTree.cs
- URLString.cs
- SqlAliaser.cs