Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataWeb / Server / System / Data / Services / ErrorHandler.cs / 1305376 / ErrorHandler.cs
//---------------------------------------------------------------------- //// Copyright (c) Microsoft Corporation. All rights reserved. // //// Provides some utility functions for this project // // // @owner [....] //--------------------------------------------------------------------- namespace System.Data.Services { #region Namespaces. using System; using System.Data.Services.Serializers; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Text; using System.Xml; #endregion Namespaces. ////// Provides support for orchestrating error handling at different points in the processing cycle and for /// serializing structured errors. /// internal class ErrorHandler { #region Private fields. ///Arguments for the exception being handled. private HandleExceptionArgs exceptionArgs; ///Encoding to created over stream; null if a higher-level writer will be provided. private Encoding encoding; #endregion Private fields. #region Constructors. ///Initializes a new /// Arguments for the exception being handled. /// Encoding to created over stream; null if a higher-level writer will be provided. private ErrorHandler(HandleExceptionArgs args, Encoding encoding) { Debug.Assert(args != null, "args != null"); this.exceptionArgs = args; this.encoding = encoding; } #endregion Constructors. #region Internal methods. ///instance. Handles an exception when processing a batch response. /// Data service doing the processing. /// host to which we need to write the exception message /// Exception thrown. /// Output writer for the batch. internal static void HandleBatchProcessException(IDataService service, DataServiceHostWrapper host, Exception exception, StreamWriter writer) { Debug.Assert(service != null, "service != null"); Debug.Assert(host != null, "host != null"); Debug.Assert(exception != null, "exception != null"); Debug.Assert(writer != null, "writer != null"); Debug.Assert(service.Configuration != null, "service.Configuration != null"); Debug.Assert(WebUtil.IsCatchableExceptionType(exception), "WebUtil.IsCatchableExceptionType(exception)"); string contentType; Encoding encoding; TryGetResponseFormatForError(host, out contentType, out encoding); HandleExceptionArgs args = new HandleExceptionArgs(exception, false, contentType, service.Configuration.UseVerboseErrors); service.InternalHandleException(args); host.ResponseVersion = XmlConstants.DataServiceVersion1Dot0 + ";"; host.ProcessException(args); writer.Flush(); ActionerrorWriter = ProcessBenignException(exception, service); if (errorWriter == null) { errorWriter = CreateErrorSerializer(args, encoding); } errorWriter(writer.BaseStream); writer.WriteLine(); } /// Handles an exception when processing a batch request. /// Data service doing the processing. /// Exception thrown. /// Output writer for the batch. internal static void HandleBatchRequestException(IDataService service, Exception exception, StreamWriter writer) { Debug.Assert(service != null, "service != null"); Debug.Assert(exception != null, "exception != null"); Debug.Assert(writer != null, "writer != null"); Debug.Assert(service.Configuration != null, "service.Configuration != null - it should have been initialized by now"); Debug.Assert(WebUtil.IsCatchableExceptionType(exception), "WebUtil.IsCatchableExceptionType(exception) - "); string contentType; Encoding encoding; DataServiceHostWrapper host = service.OperationContext == null ? null : service.OperationContext.Host; TryGetResponseFormatForError(host, out contentType, out encoding); encoding = writer.Encoding; HandleExceptionArgs args = new HandleExceptionArgs(exception, false, contentType, service.Configuration.UseVerboseErrors); service.InternalHandleException(args); writer.Flush(); ActionerrorWriter = CreateErrorSerializer(args, encoding); errorWriter(writer.BaseStream); writer.WriteLine(); } /// Handles an exception before the response has been written out. /// Exception thrown. /// Data service doing the processing. /// 'Accept' header value; possibly null. /// 'Accept-Charset' header; possibly null. ///An action that can serialize the exception into a stream. internal static ActionHandleBeforeWritingException(Exception exception, IDataService service, string accept, string acceptCharset) { Debug.Assert(WebUtil.IsCatchableExceptionType(exception), "WebUtil.IsCatchableExceptionType(exception)"); Debug.Assert(exception != null, "exception != null"); Debug.Assert(service != null, "service != null"); string contentType; Encoding encoding; TryGetResponseFormatForError(accept, acceptCharset, out contentType, out encoding); bool verbose = (service.Configuration != null) ? service.Configuration.UseVerboseErrors : false; HandleExceptionArgs args = new HandleExceptionArgs(exception, false, contentType, verbose); service.InternalHandleException(args); DataServiceHostWrapper host = service.OperationContext.Host; host.ResponseVersion = XmlConstants.DataServiceVersion1Dot0 + ";"; host.ProcessException(args); Action action = ProcessBenignException(exception, service); if (action != null) { return action; } else { return CreateErrorSerializer(args, encoding); } } /// Handles an exception while the response is being written out. /// Exception thrown. /// Data service doing the processing. /// MIME type of output stream. /// Serializer-specific exception writer. internal static void HandleDuringWritingException(Exception exception, IDataService service, string contentType, IExceptionWriter exceptionWriter) { Debug.Assert(service != null, "service != null"); Debug.Assert(exception != null, "exception != null"); Debug.Assert(exceptionWriter != null, "exceptionWriter != null"); Debug.Assert(service.Configuration != null, "service.Configuration != null"); Debug.Assert(WebUtil.IsCatchableExceptionType(exception), "WebUtil.IsCatchableExceptionType(exception)"); HandleExceptionArgs args = new HandleExceptionArgs(exception, true, contentType, service.Configuration.UseVerboseErrors); service.InternalHandleException(args); service.OperationContext.Host.ProcessException(args); exceptionWriter.WriteException(args); } ///Handles the specified /// Exception to handle ///. The caller should re-throw the original exception if this method returns normally. internal static void HandleTargetInvocationException(TargetInvocationException exception) { Debug.Assert(exception != null, "exception != null"); DataServiceException dataException = exception.InnerException as DataServiceException; if (dataException == null) { return; } throw new DataServiceException( dataException.StatusCode, dataException.ErrorCode, dataException.Message, dataException.MessageLanguage, exception); } ///Serializes an error in JSON format. /// Arguments describing the error. /// Writer to which error should be serialized. internal static void SerializeJsonError(HandleExceptionArgs args, JsonWriter writer) { Debug.Assert(args != null, "args != null"); Debug.Assert(writer != null, "writer != null"); ErrorHandler serializer = new ErrorHandler(args, null); serializer.SerializeJsonError(writer); } ///Serializes an error in XML format. /// Arguments describing the error. /// Writer to which error should be serialized. internal static void SerializeXmlError(HandleExceptionArgs args, XmlWriter writer) { Debug.Assert(args != null, "args != null"); Debug.Assert(writer != null, "writer != null"); ErrorHandler serializer = new ErrorHandler(args, null); serializer.SerializeXmlError(writer); } #endregion Internal methods. #region Private methods. ////// Check to see if the given excpetion is a benign one such as statusCode = 304. If yes we return an action that can /// serialize the exception into a stream. Other wise we return null. /// /// Exception to be processed /// Data service instance ///An action that can serialize the exception into a stream. private static ActionProcessBenignException(Exception exception, IDataService service) { DataServiceException dataServiceException = exception as DataServiceException; if (dataServiceException != null) { if (dataServiceException.StatusCode == (int)System.Net.HttpStatusCode.NotModified) { DataServiceHostWrapper host = service.OperationContext.Host; Debug.Assert(host != null, "host != null"); host.ResponseStatusCode = (int)System.Net.HttpStatusCode.NotModified; // For 304, we MUST return an empty message-body. return WebUtil.GetEmptyStreamWriter(); } } return null; } /// Creates a delegate that can serialize an error for the specified arguments. /// Arguments for the exception being handled. /// Encoding to created over stream. ///A delegate that can serialize an error for the specified arguments. private static ActionCreateErrorSerializer(HandleExceptionArgs args, Encoding encoding) { Debug.Assert(args != null, "args != null"); Debug.Assert(encoding != null, "encoding != null"); ErrorHandler handler = new ErrorHandler(args, encoding); if (WebUtil.CompareMimeType(args.ResponseContentType, XmlConstants.MimeApplicationJson)) { return handler.SerializeJsonErrorToStream; } else { return handler.SerializeXmlErrorToStream; } } /// /// Gets values describing the /// Exception to extract value from. /// Error code from theif it's a DataServiceException; /// defaults otherwise. /// ; blank if not available. /// Message from the ; blank if not available. /// Message language from the ; current default if not available. /// The cast DataServiceException; possibly null. private static DataServiceException ExtractErrorValues(Exception exception, out string errorCode, out string message, out string messageLang) { DataServiceException dataException = exception as DataServiceException; if (dataException != null) { errorCode = dataException.ErrorCode ?? ""; message = dataException.Message ?? ""; messageLang = dataException.MessageLanguage ?? CultureInfo.CurrentCulture.Name; return dataException; } else { errorCode = ""; message = Strings.DataServiceException_GeneralError; messageLang = CultureInfo.CurrentCulture.Name; return null; } } ///Serializes an exception in JSON format. /// Writer to which error should be serialized. /// Exception to serialize. private static void SerializeJsonException(JsonWriter writer, Exception exception) { string elementName = XmlConstants.JsonErrorInner; int nestingDepth = 0; while (exception != null) { writer.WriteName(elementName); writer.StartObjectScope(); nestingDepth++; string exceptionMessage = exception.Message ?? String.Empty; writer.WriteName(XmlConstants.JsonErrorMessage); writer.WriteValue(exceptionMessage); string exceptionType = exception.GetType().FullName; writer.WriteName(XmlConstants.JsonErrorType); writer.WriteValue(exceptionType); string exceptionStackTrace = exception.StackTrace ?? String.Empty; writer.WriteName(XmlConstants.JsonErrorStackTrace); writer.WriteValue(exceptionStackTrace); exception = exception.InnerException; elementName = XmlConstants.JsonErrorInternalException; } while (nestingDepth > 0) { writer.EndScope(); // nestingDepth--; } } ///Serializes an exception in XML format. /// Writer to which error should be serialized. /// Exception to serialize. private static void SerializeXmlException(XmlWriter writer, Exception exception) { string elementName = XmlConstants.XmlErrorInnerElementName; int nestingDepth = 0; while (exception != null) { // Inner Error Tag namespace changed to DataWebMetadataNamespace // Maybe DataWebNamespace should be used on all error tags? Up to debate... // NOTE: this is a breaking change from V1 writer.WriteStartElement(elementName, XmlConstants.DataWebMetadataNamespace); nestingDepth++; string exceptionMessage = exception.Message ?? String.Empty; writer.WriteStartElement(XmlConstants.XmlErrorMessageElementName, XmlConstants.DataWebMetadataNamespace); writer.WriteString(exceptionMessage); writer.WriteEndElement(); // string exceptionType = exception.GetType().FullName; writer.WriteStartElement(XmlConstants.XmlErrorTypeElementName, XmlConstants.DataWebMetadataNamespace); writer.WriteString(exceptionType); writer.WriteEndElement(); // string exceptionStackTrace = exception.StackTrace ?? String.Empty; writer.WriteStartElement(XmlConstants.XmlErrorStackTraceElementName, XmlConstants.DataWebMetadataNamespace); writer.WriteString(exceptionStackTrace); writer.WriteEndElement(); // exception = exception.InnerException; elementName = XmlConstants.XmlErrorInternalExceptionElementName; } while (nestingDepth > 0) { writer.WriteEndElement(); // nestingDepth--; } } ///Gets content type and encoding information from the host if possible; defaults otherwise. /// Host to get headers from (possibly null). /// After invocation, content type for the exception. /// After invocation, encoding for the exception. private static void TryGetResponseFormatForError(DataServiceHostWrapper host, out string contentType, out Encoding encoding) { TryGetResponseFormatForError( (host != null) ? host.RequestAccept : null, (host != null) ? host.RequestAcceptCharSet : null, out contentType, out encoding); } ///Gets content type and encoding information from the headers if possible; defaults otherwise. /// A comma-separated list of client-supported MIME Accept types. /// The specification for the character set encoding that the client requested. /// After invocation, content type for the exception. /// After invocation, encoding for the exception. private static void TryGetResponseFormatForError(string accept, string acceptCharset, out string contentType, out Encoding encoding) { contentType = null; encoding = null; if (accept != null) { try { string[] availableTypes = new string[] { XmlConstants.MimeApplicationXml, XmlConstants.MimeApplicationJson }; contentType = HttpProcessUtility.SelectMimeType(accept, availableTypes); } catch (DataServiceException) { // Ignore formatting erros in Accept and rely on text. } } if (acceptCharset != null) { try { encoding = HttpProcessUtility.EncodingFromAcceptCharset(acceptCharset); } catch (DataServiceException) { // Ignore formatting erros in Accept-Charset and rely on text. } } contentType = contentType ?? XmlConstants.MimeApplicationXml; encoding = encoding ?? HttpProcessUtility.FallbackEncoding; } ///Serializes an error in JSON format. /// Writer to which error should be serialized. private void SerializeJsonError(JsonWriter writer) { Debug.Assert(writer != null, "writer != null"); writer.StartObjectScope(); // Wrapper for error. writer.WriteName(XmlConstants.JsonError); string errorCode, message, messageLang; DataServiceException dataException = ExtractErrorValues(this.exceptionArgs.Exception, out errorCode, out message, out messageLang); writer.StartObjectScope(); writer.WriteName(XmlConstants.JsonErrorCode); writer.WriteValue(errorCode); writer.WriteName(XmlConstants.JsonErrorMessage); writer.StartObjectScope(); writer.WriteName(XmlConstants.XmlLangAttributeName); writer.WriteValue(messageLang); writer.WriteName(XmlConstants.JsonErrorValue); writer.WriteValue(message); writer.EndScope(); // if (this.exceptionArgs.UseVerboseErrors) { Exception exception = (dataException == null) ? this.exceptionArgs.Exception : dataException.InnerException; SerializeJsonException(writer, exception); } writer.EndScope(); // writer.EndScope(); // writer.Flush(); } ///Serializes an error in XML format. /// Writer to which error should be serialized. private void SerializeXmlError(XmlWriter writer) { Debug.Assert(writer != null, "writer != null"); writer.WriteStartElement(XmlConstants.XmlErrorElementName, XmlConstants.DataWebMetadataNamespace); string errorCode, message, messageLang; DataServiceException dataException = ExtractErrorValues(this.exceptionArgs.Exception, out errorCode, out message, out messageLang); writer.WriteStartElement(XmlConstants.XmlErrorCodeElementName, XmlConstants.DataWebMetadataNamespace); writer.WriteString(errorCode); writer.WriteEndElement(); // writer.WriteStartElement(XmlConstants.XmlErrorMessageElementName, XmlConstants.DataWebMetadataNamespace); writer.WriteAttributeString( XmlConstants.XmlNamespacePrefix, // prefix XmlConstants.XmlLangAttributeName, // localName null, // ns messageLang); // value writer.WriteString(message); writer.WriteEndElement(); // if (this.exceptionArgs.UseVerboseErrors) { Exception exception = (dataException == null) ? this.exceptionArgs.Exception : dataException.InnerException; SerializeXmlException(writer, exception); } writer.WriteEndElement(); // writer.Flush(); } ///Serializes the current exception description to the specified /// Stream to write to. private void SerializeJsonErrorToStream(Stream stream) { Debug.Assert(stream != null, "stream != null"); JsonWriter jsonWriter = new JsonWriter(new StreamWriter(stream, this.encoding)); try { SerializeJsonError(jsonWriter); } finally { // We should not close the writer, since the stream is owned by the underlying host. jsonWriter.Flush(); } } ///. Serializes the current exception description to the specified /// Stream to write to. private void SerializeXmlErrorToStream(Stream stream) { Debug.Assert(stream != null, "stream != null"); using (XmlWriter writer = XmlUtil.CreateXmlWriterAndWriteProcessingInstruction(stream, this.encoding)) { SerializeXmlError(writer); } } #endregion Private methods. } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //---------------------------------------------------------------------- //. // Copyright (c) Microsoft Corporation. All rights reserved. // //// Provides some utility functions for this project // // // @owner [....] //--------------------------------------------------------------------- namespace System.Data.Services { #region Namespaces. using System; using System.Data.Services.Serializers; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Text; using System.Xml; #endregion Namespaces. ////// Provides support for orchestrating error handling at different points in the processing cycle and for /// serializing structured errors. /// internal class ErrorHandler { #region Private fields. ///Arguments for the exception being handled. private HandleExceptionArgs exceptionArgs; ///Encoding to created over stream; null if a higher-level writer will be provided. private Encoding encoding; #endregion Private fields. #region Constructors. ///Initializes a new /// Arguments for the exception being handled. /// Encoding to created over stream; null if a higher-level writer will be provided. private ErrorHandler(HandleExceptionArgs args, Encoding encoding) { Debug.Assert(args != null, "args != null"); this.exceptionArgs = args; this.encoding = encoding; } #endregion Constructors. #region Internal methods. ///instance. Handles an exception when processing a batch response. /// Data service doing the processing. /// host to which we need to write the exception message /// Exception thrown. /// Output writer for the batch. internal static void HandleBatchProcessException(IDataService service, DataServiceHostWrapper host, Exception exception, StreamWriter writer) { Debug.Assert(service != null, "service != null"); Debug.Assert(host != null, "host != null"); Debug.Assert(exception != null, "exception != null"); Debug.Assert(writer != null, "writer != null"); Debug.Assert(service.Configuration != null, "service.Configuration != null"); Debug.Assert(WebUtil.IsCatchableExceptionType(exception), "WebUtil.IsCatchableExceptionType(exception)"); string contentType; Encoding encoding; TryGetResponseFormatForError(host, out contentType, out encoding); HandleExceptionArgs args = new HandleExceptionArgs(exception, false, contentType, service.Configuration.UseVerboseErrors); service.InternalHandleException(args); host.ResponseVersion = XmlConstants.DataServiceVersion1Dot0 + ";"; host.ProcessException(args); writer.Flush(); ActionerrorWriter = ProcessBenignException(exception, service); if (errorWriter == null) { errorWriter = CreateErrorSerializer(args, encoding); } errorWriter(writer.BaseStream); writer.WriteLine(); } /// Handles an exception when processing a batch request. /// Data service doing the processing. /// Exception thrown. /// Output writer for the batch. internal static void HandleBatchRequestException(IDataService service, Exception exception, StreamWriter writer) { Debug.Assert(service != null, "service != null"); Debug.Assert(exception != null, "exception != null"); Debug.Assert(writer != null, "writer != null"); Debug.Assert(service.Configuration != null, "service.Configuration != null - it should have been initialized by now"); Debug.Assert(WebUtil.IsCatchableExceptionType(exception), "WebUtil.IsCatchableExceptionType(exception) - "); string contentType; Encoding encoding; DataServiceHostWrapper host = service.OperationContext == null ? null : service.OperationContext.Host; TryGetResponseFormatForError(host, out contentType, out encoding); encoding = writer.Encoding; HandleExceptionArgs args = new HandleExceptionArgs(exception, false, contentType, service.Configuration.UseVerboseErrors); service.InternalHandleException(args); writer.Flush(); ActionerrorWriter = CreateErrorSerializer(args, encoding); errorWriter(writer.BaseStream); writer.WriteLine(); } /// Handles an exception before the response has been written out. /// Exception thrown. /// Data service doing the processing. /// 'Accept' header value; possibly null. /// 'Accept-Charset' header; possibly null. ///An action that can serialize the exception into a stream. internal static ActionHandleBeforeWritingException(Exception exception, IDataService service, string accept, string acceptCharset) { Debug.Assert(WebUtil.IsCatchableExceptionType(exception), "WebUtil.IsCatchableExceptionType(exception)"); Debug.Assert(exception != null, "exception != null"); Debug.Assert(service != null, "service != null"); string contentType; Encoding encoding; TryGetResponseFormatForError(accept, acceptCharset, out contentType, out encoding); bool verbose = (service.Configuration != null) ? service.Configuration.UseVerboseErrors : false; HandleExceptionArgs args = new HandleExceptionArgs(exception, false, contentType, verbose); service.InternalHandleException(args); DataServiceHostWrapper host = service.OperationContext.Host; host.ResponseVersion = XmlConstants.DataServiceVersion1Dot0 + ";"; host.ProcessException(args); Action action = ProcessBenignException(exception, service); if (action != null) { return action; } else { return CreateErrorSerializer(args, encoding); } } /// Handles an exception while the response is being written out. /// Exception thrown. /// Data service doing the processing. /// MIME type of output stream. /// Serializer-specific exception writer. internal static void HandleDuringWritingException(Exception exception, IDataService service, string contentType, IExceptionWriter exceptionWriter) { Debug.Assert(service != null, "service != null"); Debug.Assert(exception != null, "exception != null"); Debug.Assert(exceptionWriter != null, "exceptionWriter != null"); Debug.Assert(service.Configuration != null, "service.Configuration != null"); Debug.Assert(WebUtil.IsCatchableExceptionType(exception), "WebUtil.IsCatchableExceptionType(exception)"); HandleExceptionArgs args = new HandleExceptionArgs(exception, true, contentType, service.Configuration.UseVerboseErrors); service.InternalHandleException(args); service.OperationContext.Host.ProcessException(args); exceptionWriter.WriteException(args); } ///Handles the specified /// Exception to handle ///. The caller should re-throw the original exception if this method returns normally. internal static void HandleTargetInvocationException(TargetInvocationException exception) { Debug.Assert(exception != null, "exception != null"); DataServiceException dataException = exception.InnerException as DataServiceException; if (dataException == null) { return; } throw new DataServiceException( dataException.StatusCode, dataException.ErrorCode, dataException.Message, dataException.MessageLanguage, exception); } ///Serializes an error in JSON format. /// Arguments describing the error. /// Writer to which error should be serialized. internal static void SerializeJsonError(HandleExceptionArgs args, JsonWriter writer) { Debug.Assert(args != null, "args != null"); Debug.Assert(writer != null, "writer != null"); ErrorHandler serializer = new ErrorHandler(args, null); serializer.SerializeJsonError(writer); } ///Serializes an error in XML format. /// Arguments describing the error. /// Writer to which error should be serialized. internal static void SerializeXmlError(HandleExceptionArgs args, XmlWriter writer) { Debug.Assert(args != null, "args != null"); Debug.Assert(writer != null, "writer != null"); ErrorHandler serializer = new ErrorHandler(args, null); serializer.SerializeXmlError(writer); } #endregion Internal methods. #region Private methods. ////// Check to see if the given excpetion is a benign one such as statusCode = 304. If yes we return an action that can /// serialize the exception into a stream. Other wise we return null. /// /// Exception to be processed /// Data service instance ///An action that can serialize the exception into a stream. private static ActionProcessBenignException(Exception exception, IDataService service) { DataServiceException dataServiceException = exception as DataServiceException; if (dataServiceException != null) { if (dataServiceException.StatusCode == (int)System.Net.HttpStatusCode.NotModified) { DataServiceHostWrapper host = service.OperationContext.Host; Debug.Assert(host != null, "host != null"); host.ResponseStatusCode = (int)System.Net.HttpStatusCode.NotModified; // For 304, we MUST return an empty message-body. return WebUtil.GetEmptyStreamWriter(); } } return null; } /// Creates a delegate that can serialize an error for the specified arguments. /// Arguments for the exception being handled. /// Encoding to created over stream. ///A delegate that can serialize an error for the specified arguments. private static ActionCreateErrorSerializer(HandleExceptionArgs args, Encoding encoding) { Debug.Assert(args != null, "args != null"); Debug.Assert(encoding != null, "encoding != null"); ErrorHandler handler = new ErrorHandler(args, encoding); if (WebUtil.CompareMimeType(args.ResponseContentType, XmlConstants.MimeApplicationJson)) { return handler.SerializeJsonErrorToStream; } else { return handler.SerializeXmlErrorToStream; } } /// /// Gets values describing the /// Exception to extract value from. /// Error code from theif it's a DataServiceException; /// defaults otherwise. /// ; blank if not available. /// Message from the ; blank if not available. /// Message language from the ; current default if not available. /// The cast DataServiceException; possibly null. private static DataServiceException ExtractErrorValues(Exception exception, out string errorCode, out string message, out string messageLang) { DataServiceException dataException = exception as DataServiceException; if (dataException != null) { errorCode = dataException.ErrorCode ?? ""; message = dataException.Message ?? ""; messageLang = dataException.MessageLanguage ?? CultureInfo.CurrentCulture.Name; return dataException; } else { errorCode = ""; message = Strings.DataServiceException_GeneralError; messageLang = CultureInfo.CurrentCulture.Name; return null; } } ///Serializes an exception in JSON format. /// Writer to which error should be serialized. /// Exception to serialize. private static void SerializeJsonException(JsonWriter writer, Exception exception) { string elementName = XmlConstants.JsonErrorInner; int nestingDepth = 0; while (exception != null) { writer.WriteName(elementName); writer.StartObjectScope(); nestingDepth++; string exceptionMessage = exception.Message ?? String.Empty; writer.WriteName(XmlConstants.JsonErrorMessage); writer.WriteValue(exceptionMessage); string exceptionType = exception.GetType().FullName; writer.WriteName(XmlConstants.JsonErrorType); writer.WriteValue(exceptionType); string exceptionStackTrace = exception.StackTrace ?? String.Empty; writer.WriteName(XmlConstants.JsonErrorStackTrace); writer.WriteValue(exceptionStackTrace); exception = exception.InnerException; elementName = XmlConstants.JsonErrorInternalException; } while (nestingDepth > 0) { writer.EndScope(); // nestingDepth--; } } ///Serializes an exception in XML format. /// Writer to which error should be serialized. /// Exception to serialize. private static void SerializeXmlException(XmlWriter writer, Exception exception) { string elementName = XmlConstants.XmlErrorInnerElementName; int nestingDepth = 0; while (exception != null) { // Inner Error Tag namespace changed to DataWebMetadataNamespace // Maybe DataWebNamespace should be used on all error tags? Up to debate... // NOTE: this is a breaking change from V1 writer.WriteStartElement(elementName, XmlConstants.DataWebMetadataNamespace); nestingDepth++; string exceptionMessage = exception.Message ?? String.Empty; writer.WriteStartElement(XmlConstants.XmlErrorMessageElementName, XmlConstants.DataWebMetadataNamespace); writer.WriteString(exceptionMessage); writer.WriteEndElement(); // string exceptionType = exception.GetType().FullName; writer.WriteStartElement(XmlConstants.XmlErrorTypeElementName, XmlConstants.DataWebMetadataNamespace); writer.WriteString(exceptionType); writer.WriteEndElement(); // string exceptionStackTrace = exception.StackTrace ?? String.Empty; writer.WriteStartElement(XmlConstants.XmlErrorStackTraceElementName, XmlConstants.DataWebMetadataNamespace); writer.WriteString(exceptionStackTrace); writer.WriteEndElement(); // exception = exception.InnerException; elementName = XmlConstants.XmlErrorInternalExceptionElementName; } while (nestingDepth > 0) { writer.WriteEndElement(); // nestingDepth--; } } ///Gets content type and encoding information from the host if possible; defaults otherwise. /// Host to get headers from (possibly null). /// After invocation, content type for the exception. /// After invocation, encoding for the exception. private static void TryGetResponseFormatForError(DataServiceHostWrapper host, out string contentType, out Encoding encoding) { TryGetResponseFormatForError( (host != null) ? host.RequestAccept : null, (host != null) ? host.RequestAcceptCharSet : null, out contentType, out encoding); } ///Gets content type and encoding information from the headers if possible; defaults otherwise. /// A comma-separated list of client-supported MIME Accept types. /// The specification for the character set encoding that the client requested. /// After invocation, content type for the exception. /// After invocation, encoding for the exception. private static void TryGetResponseFormatForError(string accept, string acceptCharset, out string contentType, out Encoding encoding) { contentType = null; encoding = null; if (accept != null) { try { string[] availableTypes = new string[] { XmlConstants.MimeApplicationXml, XmlConstants.MimeApplicationJson }; contentType = HttpProcessUtility.SelectMimeType(accept, availableTypes); } catch (DataServiceException) { // Ignore formatting erros in Accept and rely on text. } } if (acceptCharset != null) { try { encoding = HttpProcessUtility.EncodingFromAcceptCharset(acceptCharset); } catch (DataServiceException) { // Ignore formatting erros in Accept-Charset and rely on text. } } contentType = contentType ?? XmlConstants.MimeApplicationXml; encoding = encoding ?? HttpProcessUtility.FallbackEncoding; } ///Serializes an error in JSON format. /// Writer to which error should be serialized. private void SerializeJsonError(JsonWriter writer) { Debug.Assert(writer != null, "writer != null"); writer.StartObjectScope(); // Wrapper for error. writer.WriteName(XmlConstants.JsonError); string errorCode, message, messageLang; DataServiceException dataException = ExtractErrorValues(this.exceptionArgs.Exception, out errorCode, out message, out messageLang); writer.StartObjectScope(); writer.WriteName(XmlConstants.JsonErrorCode); writer.WriteValue(errorCode); writer.WriteName(XmlConstants.JsonErrorMessage); writer.StartObjectScope(); writer.WriteName(XmlConstants.XmlLangAttributeName); writer.WriteValue(messageLang); writer.WriteName(XmlConstants.JsonErrorValue); writer.WriteValue(message); writer.EndScope(); // if (this.exceptionArgs.UseVerboseErrors) { Exception exception = (dataException == null) ? this.exceptionArgs.Exception : dataException.InnerException; SerializeJsonException(writer, exception); } writer.EndScope(); // writer.EndScope(); // writer.Flush(); } ///Serializes an error in XML format. /// Writer to which error should be serialized. private void SerializeXmlError(XmlWriter writer) { Debug.Assert(writer != null, "writer != null"); writer.WriteStartElement(XmlConstants.XmlErrorElementName, XmlConstants.DataWebMetadataNamespace); string errorCode, message, messageLang; DataServiceException dataException = ExtractErrorValues(this.exceptionArgs.Exception, out errorCode, out message, out messageLang); writer.WriteStartElement(XmlConstants.XmlErrorCodeElementName, XmlConstants.DataWebMetadataNamespace); writer.WriteString(errorCode); writer.WriteEndElement(); // writer.WriteStartElement(XmlConstants.XmlErrorMessageElementName, XmlConstants.DataWebMetadataNamespace); writer.WriteAttributeString( XmlConstants.XmlNamespacePrefix, // prefix XmlConstants.XmlLangAttributeName, // localName null, // ns messageLang); // value writer.WriteString(message); writer.WriteEndElement(); // if (this.exceptionArgs.UseVerboseErrors) { Exception exception = (dataException == null) ? this.exceptionArgs.Exception : dataException.InnerException; SerializeXmlException(writer, exception); } writer.WriteEndElement(); // writer.Flush(); } ///Serializes the current exception description to the specified /// Stream to write to. private void SerializeJsonErrorToStream(Stream stream) { Debug.Assert(stream != null, "stream != null"); JsonWriter jsonWriter = new JsonWriter(new StreamWriter(stream, this.encoding)); try { SerializeJsonError(jsonWriter); } finally { // We should not close the writer, since the stream is owned by the underlying host. jsonWriter.Flush(); } } ///. Serializes the current exception description to the specified /// Stream to write to. private void SerializeXmlErrorToStream(Stream stream) { Debug.Assert(stream != null, "stream != null"); using (XmlWriter writer = XmlUtil.CreateXmlWriterAndWriteProcessingInstruction(stream, this.encoding)) { SerializeXmlError(writer); } } #endregion Private methods. } } // 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
- X509CertificateCollection.cs
- XmlSchemaDatatype.cs
- IntSecurity.cs
- ClientProxyGenerator.cs
- MultiByteCodec.cs
- EncoderReplacementFallback.cs
- DomNameTable.cs
- ButtonChrome.cs
- RuleAction.cs
- RegexParser.cs
- GB18030Encoding.cs
- TemplateControlCodeDomTreeGenerator.cs
- EncryptedReference.cs
- HandleRef.cs
- EventListener.cs
- ImageUrlEditor.cs
- ReaderWriterLock.cs
- ParseHttpDate.cs
- ReverseComparer.cs
- HandledEventArgs.cs
- SimpleWebHandlerParser.cs
- CreateUserWizard.cs
- Vector3DValueSerializer.cs
- CodeMemberEvent.cs
- QuerySettings.cs
- XmlParserContext.cs
- ErasingStroke.cs
- RelatedCurrencyManager.cs
- WebPartConnectionsCloseVerb.cs
- Propagator.JoinPropagator.cs
- SqlProcedureAttribute.cs
- WindowsBrush.cs
- TaskHelper.cs
- DataSetFieldSchema.cs
- SafeArrayTypeMismatchException.cs
- AnnotationHighlightLayer.cs
- Range.cs
- CodeGeneratorOptions.cs
- UnlockInstanceAsyncResult.cs
- WSSecurityJan2004.cs
- ProcessThreadCollection.cs
- MetaTableHelper.cs
- MatrixAnimationBase.cs
- NameValueCollection.cs
- DependentTransaction.cs
- _Rfc2616CacheValidators.cs
- Context.cs
- UDPClient.cs
- ConfigurationManagerInternalFactory.cs
- InsufficientExecutionStackException.cs
- GridViewColumnCollection.cs
- DataTableNameHandler.cs
- StylusButtonCollection.cs
- FormsAuthenticationCredentials.cs
- LinkedDataMemberFieldEditor.cs
- documentsequencetextview.cs
- Int32Converter.cs
- ProtocolsConfiguration.cs
- BinaryReader.cs
- DiscoveryUtility.cs
- SafeNativeMethods.cs
- PrintingPermission.cs
- XmlNamespaceDeclarationsAttribute.cs
- GreenMethods.cs
- CompletedAsyncResult.cs
- BitmapEffectDrawing.cs
- HtmlLinkAdapter.cs
- TreeNodeBinding.cs
- _ScatterGatherBuffers.cs
- ContextDataSourceView.cs
- MessageContractImporter.cs
- TimeEnumHelper.cs
- DesigntimeLicenseContext.cs
- WorkflowEventArgs.cs
- WmpBitmapDecoder.cs
- ToolStripItemCollection.cs
- WebPartsPersonalizationAuthorization.cs
- ConvertersCollection.cs
- InvalidAsynchronousStateException.cs
- OuterGlowBitmapEffect.cs
- AggregatePushdown.cs
- remotingproxy.cs
- MimeReflector.cs
- CodeCompileUnit.cs
- ObjectAnimationUsingKeyFrames.cs
- SpeechSynthesizer.cs
- DataKey.cs
- TreeNodeStyleCollectionEditor.cs
- DataGridItemEventArgs.cs
- SizeAnimation.cs
- XmlQuerySequence.cs
- AQNBuilder.cs
- LinqDataSourceEditData.cs
- ConnectionPoint.cs
- WriterOutput.cs
- CFStream.cs
- odbcmetadatacollectionnames.cs
- ColorTranslator.cs
- sapiproxy.cs
- HostingEnvironmentWrapper.cs