/// <summary> /// Returns an <see cref="Encoding"/> based on <paramref name="context"/>'s /// character set. /// </summary> /// <param name="context">The <see cref="InputFormatterContext"/>.</param> /// <returns> /// An <see cref="Encoding"/> based on <paramref name="context"/>'s /// character set. <c>null</c> if no supported encoding was found. /// </returns> protected Encoding SelectCharacterEncoding(InputFormatterContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (SupportedEncodings?.Count == 0) { var message = Resources.FormatTextInputFormatter_SupportedEncodingsMustNotBeEmpty(nameof(SupportedEncodings)); throw new InvalidOperationException(message); } var request = context.HttpContext.Request; var requestEncoding = request.ContentType == null ? null : MediaType.GetEncoding(request.ContentType); if (requestEncoding != null) { for (int i = 0; i < SupportedEncodings.Count; i++) { if (string.Equals( requestEncoding.WebName, SupportedEncodings[i].WebName, StringComparison.OrdinalIgnoreCase)) { return(SupportedEncodings[i]); } } // The client specified an encoding in the content type header of the request // but we don't understand it. In this situation we don't try to pick any other encoding // from the list of supported encodings and read the body with that encoding. // Instead, we return null and that will translate later on into a 415 Unsupported Media Type // response. return(null); } // We want to do our best effort to read the body of the request even in the // cases where the client doesn't send a content type header or sends a content // type header without encoding. For that reason we pick the first encoding of the // list of supported encodings and try to use that to read the body. This encoding // is UTF-8 by default on our formatters, which generally is a safe choice for the // encoding. return(SupportedEncodings[0]); }
/// <summary> /// Gets the content type and encoding that need to be used for the response. /// The priority for selecting the content type is: /// 1. ContentType property set on the action result /// 2. <see cref="HttpResponse.ContentType"/> property set on <see cref="HttpResponse"/> /// 3. Default content type set on the action result /// </summary> /// <remarks> /// The user supplied content type is not modified and is used as is. For example, if user /// sets the content type to be "text/plain" without any encoding, then the default content type's /// encoding is used to write the response and the ContentType header is set to be "text/plain" without any /// "charset" information. /// </remarks> /// <param name="actionResultContentType">ContentType set on the action result</param> /// <param name="httpResponseContentType"><see cref="HttpResponse.ContentType"/> property set /// on <see cref="HttpResponse"/></param> /// <param name="defaultContentType">The default content type of the action result.</param> /// <param name="resolvedContentType">The content type to be used for the response content type header</param> /// <param name="resolvedContentTypeEncoding">Encoding to be used for writing the response</param> public static void ResolveContentTypeAndEncoding( string actionResultContentType, string httpResponseContentType, string defaultContentType, out string resolvedContentType, out Encoding resolvedContentTypeEncoding) { Debug.Assert(defaultContentType != null); var defaultContentTypeEncoding = MediaType.GetEncoding(defaultContentType); Debug.Assert(defaultContentTypeEncoding != null); // 1. User sets the ContentType property on the action result if (actionResultContentType != null) { resolvedContentType = actionResultContentType; var actionResultEncoding = MediaType.GetEncoding(actionResultContentType); resolvedContentTypeEncoding = actionResultEncoding ?? defaultContentTypeEncoding; return; } // 2. User sets the ContentType property on the http response directly if (!string.IsNullOrEmpty(httpResponseContentType)) { var mediaTypeEncoding = MediaType.GetEncoding(httpResponseContentType); if (mediaTypeEncoding != null) { resolvedContentType = httpResponseContentType; resolvedContentTypeEncoding = mediaTypeEncoding; } else { resolvedContentType = httpResponseContentType; resolvedContentTypeEncoding = defaultContentTypeEncoding; } return; } // 3. Fall-back to the default content type resolvedContentType = defaultContentType; resolvedContentTypeEncoding = defaultContentTypeEncoding; }