Skip to content

Instantly share code, notes, and snippets.

@madagaga
Last active June 23, 2016 09:12
Show Gist options
  • Save madagaga/6c13fdb14a3c71f883a3618be2e19a31 to your computer and use it in GitHub Desktop.
Save madagaga/6c13fdb14a3c71f883a3618be2e19a31 to your computer and use it in GitHub Desktop.
Workaround to get object from body with mono 4.2.x
// workaround class
public static class StreamExtension
{
private static MediaTypeFormatterCollection _defaultMediaTypeFormatterCollection = null;
// Using the JsonMediaTypeFormatter for the first time is rather expensive (due to reflection cost
// when creating the default contract resolver). Hence we new up a static collection, such
// that the second call is much faster.
private static MediaTypeFormatterCollection DefaultMediaTypeFormatterCollection
{
get
{
if (_defaultMediaTypeFormatterCollection == null)
{
_defaultMediaTypeFormatterCollection = new MediaTypeFormatterCollection();
}
return _defaultMediaTypeFormatterCollection;
}
}
public static T ReadAs<T>(this System.Web.HttpRequest request)
{
return request.ReadAs<T>(DefaultMediaTypeFormatterCollection);
}
public static T ReadAs<T>(this System.Web.HttpRequest request, IEnumerable<MediaTypeFormatter> formatters)
{
return ReadAs<T>(request, typeof(T), formatters, null);
}
private static T ReadAs<T>(System.Web.HttpRequest request , Type type, IEnumerable<MediaTypeFormatter> formatters,
IFormatterLogger formatterLogger)
{
if (request.InputStream == null)
{
throw new ArgumentNullException("content");
}
if (type == null)
{
throw new ArgumentNullException("type");
}
if (formatters == null)
{
throw new ArgumentNullException("formatters");
}
// Default to "application/octet-stream" if there is no content-type in accordance with section 7.2.1 of the HTTP spec
MediaTypeHeaderValue mediaType = null;
try {
mediaType = new MediaTypeHeaderValue(request.ContentType);
}
catch {
mediaType = new MediaTypeHeaderValue ("application/octet-stream");
}
// ObjectContent objectContent = new ObjectContent(typeof T,"test",null
// if (objectContent != null && objectContent.Value != null && type.IsAssignableFrom(objectContent.Value.GetType()))
// {
// return Task.FromResult((T)objectContent.Value);
// }
MediaTypeFormatter formatter = new MediaTypeFormatterCollection(formatters).FindReader(type, mediaType);
if (formatter == null)
{
if (request.ContentLength == 0)
return default(T);
throw new UnsupportedMediaTypeException(
string.Format("NoReadSerializerAvailable {0} {1}", type.Name, mediaType.MediaType),
mediaType);
}
return ReadAsCore<T>(request, type, formatterLogger, formatter);
}
private static T ReadAsCore<T>(System.Web.HttpRequest request , Type type, IFormatterLogger formatterLogger,
MediaTypeFormatter formatter)
{
Stream stream = request.InputStream;
object result = formatter.ReadFromStreamAsync(type, stream, null, formatterLogger).Result;
return (T)result;
}
}
@madagaga
Copy link
Author

Usage:

Original line looks like
public virtual IHttpActionResult Post([FromBody] T value) { ... }

with the workaround
public virtual IHttpActionResult Post() { T value = HttpContext.Current.Request.ReadAs<T> (); ... }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment