Last active
September 11, 2020 13:31
-
-
Save cobysy/578302d0f4f5b895f459 to your computer and use it in GitHub Desktop.
Fix of JsonMediaTypeFormatter (ASP.net WebAPI) that does not convert JSON to object when Request is in Chunked Transfer Encoding.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <summary> | |
/// Fix of JsonMediaTypeFormatter that does not convert JSON to object when Request is in Chunked Transfer Encoding. | |
/// </summary> | |
public class XJsonMediaTypeFormatter : JsonMediaTypeFormatter | |
{ | |
/// <summary> | |
/// Replaces web api default JsonMediaTypeFormatter with this instance. | |
/// Usage: | |
/// protected void Application_Start() | |
/// { | |
/// ... | |
/// XJsonMediaTypeFormatter.FixConfiguration(GlobalConfiguration.Configuration); | |
/// ... | |
/// </summary> | |
/// <param name="configuration"></param> | |
public static void FixConfiguration(HttpConfiguration configuration) | |
{ | |
var formatter = new XJsonMediaTypeFormatter | |
{ | |
SerializerSettings = | |
{ | |
NullValueHandling = NullValueHandling.Ignore | |
} | |
}; | |
configuration.Formatters.Remove(configuration.Formatters.JsonFormatter); | |
configuration.Formatters.Add(formatter); | |
} | |
// From BaseJsonMediaTypeFormatter in Microsoft.AspNet.WebApi.Client.5.1.2\lib\net45\System.Net.Http.Formatting.dll | |
public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger) | |
{ | |
if (content.Headers.ContentLength.HasValue && content.Headers.ContentLength == 0) | |
// "Messages MUST NOT include both a Content-Length header field and a non-identity transfer-coding. | |
// If the message does include a non-identity transfer-coding, the Content-Length MUST be ignored." | |
// (RFC 2616, Section 4.4) | |
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html | |
// Fix for that the base-implementation defaults to 'default' value if Content-Length is 0. | |
content.Headers.ContentLength = new long?(); | |
return base.ReadFromStreamAsync(type, readStream, content, formatterLogger); | |
} | |
} | |
/* | |
* "Long" version | |
* | |
/// <summary> | |
/// Fix of JsonMediaTypeFormatter that does not convert JSON to object when Request is in Chunked Transfer Encoding. | |
/// </summary> | |
public class XJsonMediaTypeFormatter : JsonMediaTypeFormatter | |
{ | |
/// <summary> | |
/// Replaces web api default JsonMediaTypeFormatter with this instance. | |
/// Usage: | |
/// protected void Application_Start() | |
/// { | |
/// ... | |
/// XJsonMediaTypeFormatter.FixConfiguration(GlobalConfiguration.Configuration); | |
/// ... | |
/// </summary> | |
/// <param name="configuration"></param> | |
public static void FixConfiguration(HttpConfiguration configuration) | |
{ | |
var formatter = new XJsonMediaTypeFormatter | |
{ | |
SerializerSettings = | |
{ | |
NullValueHandling = NullValueHandling.Ignore | |
} | |
}; | |
configuration.Formatters.Remove(configuration.Formatters.JsonFormatter); | |
configuration.Formatters.Add(formatter); | |
} | |
// From BaseJsonMediaTypeFormatter in Microsoft.AspNet.WebApi.Client.5.1.2\lib\net45\System.Net.Http.Formatting.dll | |
public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger) | |
{ | |
try | |
{ | |
return Task.FromResult(ReadFromStream(type, readStream, content, formatterLogger)); | |
} | |
catch (Exception ex) | |
{ | |
//return TaskHelpers.FromError<object>(ex); | |
return FromError<object>(ex); | |
} | |
} | |
// From System.Threading.Tasks.TaskHelpers in Microsoft.AspNet.WebApi.Client.5.1.2\lib\net45\System.Net.Http.Formatting.dll | |
private static Task<TResult> FromError<TResult>(Exception exception) | |
{ | |
TaskCompletionSource<TResult> completionSource = new TaskCompletionSource<TResult>(); | |
completionSource.SetException(exception); | |
return completionSource.Task; | |
} | |
// From BaseJsonMediaTypeFormatter in Microsoft.AspNet.WebApi.Client.5.1.2\lib\net45\System.Net.Http.Formatting.dll | |
private object ReadFromStream(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger) | |
{ | |
var contentHeaders = content == null ? null : content.Headers; | |
var effectiveEncoding = SelectCharacterEncoding(contentHeaders); | |
try | |
{ | |
var res = ReadFromStream(type, readStream, effectiveEncoding, formatterLogger); | |
return res; | |
} | |
catch (Exception ex) | |
{ | |
if (formatterLogger == null) | |
throw; | |
formatterLogger.LogError(string.Empty, ex); | |
return GetDefaultValueForType(type); | |
} | |
} | |
/* | |
* BaseJsonMediaTypeFormatter.ReadFromStream implementation here only for reference | |
* | |
private object ReadFromStream(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger) | |
{ | |
HttpContentHeaders contentHeaders = content == null ? (HttpContentHeaders)null : content.Headers; | |
if (contentHeaders != null) | |
{ | |
long? contentLength = contentHeaders.ContentLength; | |
if ((contentLength.GetValueOrDefault() != 0L ? 0 : (contentLength.HasValue ? 1 : 0)) != 0) | |
return MediaTypeFormatter.GetDefaultValueForType(type); | |
} | |
Encoding effectiveEncoding = this.SelectCharacterEncoding(contentHeaders); | |
try | |
{ | |
return this.ReadFromStream(type, readStream, effectiveEncoding, formatterLogger); | |
} | |
catch (Exception ex) | |
{ | |
if (formatterLogger == null) | |
{ | |
throw; | |
} | |
else | |
{ | |
formatterLogger.LogError(string.Empty, ex); | |
return MediaTypeFormatter.GetDefaultValueForType(type); | |
} | |
} | |
} | |
*/ | |
} | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This saved me!! Thanks for sharing this! Two days hunting down the issue, and it turned out to be this problem.