Posted By

dmilligan on 04/12/13


Tagged

MVC JSONP JsonMediaTypeFormatter WebAPI


Versions (?)

Who likes this?

2 people have marked this snippet as a favorite

danfinrud55
Beppoi


JsonpFormatter for MVC WebAPI


 / Published in: C#
 

A JSONP formatter for MVC 4 WebAPI.

  1. In the Global.ascx file, add formatter.
  2. protected void Application_Start()
  3. {
  4. ...
  5. GlobalConfiguration.Configuration.Formatters.Insert(0, new JsonpFormatter());
  6. }
  7.  
  8. The JsonpFormatter class:
  9.  
  10. public class JsonpFormatter : JsonMediaTypeFormatter
  11. {
  12.  
  13. public JsonpFormatter()
  14. {
  15. SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
  16. SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/javascript"));
  17.  
  18. JsonpParameterName = "callback";
  19. }
  20.  
  21. /// <summary>
  22.  
  23. /// Name of the query string parameter to look for
  24. /// the jsonp function name
  25. /// </summary>
  26. public string JsonpParameterName { get; set; }
  27.  
  28. /// <summary>
  29. /// Captured name of the Jsonp function that the JSON call
  30. /// is wrapped in. Set in GetPerRequestFormatter Instance
  31. /// </summary>
  32. private string JsonpCallbackFunction;
  33.  
  34.  
  35. public override bool CanWriteType(Type type)
  36. {
  37. return true;
  38. }
  39.  
  40. /// <summary>
  41. /// Override this method to capture the Request object
  42. /// </summary>
  43. /// <param name="type"></param>
  44. /// <param name="request"></param>
  45. /// <param name="mediaType"></param>
  46. /// <returns></returns>
  47. public override MediaTypeFormatter GetPerRequestFormatterInstance(Type type, System.Net.Http.HttpRequestMessage request, MediaTypeHeaderValue mediaType)
  48. {
  49. var formatter = new JsonpFormatter()
  50. {
  51. JsonpCallbackFunction = GetJsonCallbackFunction(request)
  52. };
  53.  
  54. // this doesn't work unfortunately
  55. //formatter.SerializerSettings = GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings;
  56.  
  57. // You have to reapply any JSON.NET default serializer Customizations here
  58. formatter.SerializerSettings.Converters.Add(new StringEnumConverter());
  59. formatter.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.Indented;
  60.  
  61. return formatter;
  62. }
  63.  
  64.  
  65. public override Task WriteToStreamAsync(Type type, object value,
  66. Stream stream,
  67. HttpContent content,
  68. TransportContext transportContext)
  69. {
  70. if (string.IsNullOrEmpty(JsonpCallbackFunction))
  71. return base.WriteToStreamAsync(type, value, stream, content, transportContext);
  72.  
  73. StreamWriter writer = null;
  74.  
  75. // write the pre-amble
  76. try
  77. {
  78. writer = new StreamWriter(stream);
  79. writer.Write(JsonpCallbackFunction + "(");
  80. writer.Flush();
  81. }
  82. catch (Exception ex)
  83. {
  84. try
  85. {
  86. if (writer != null)
  87. writer.Dispose();
  88. }
  89. catch { }
  90.  
  91. var tcs = new TaskCompletionSource<object>();
  92. tcs.SetException(ex);
  93. return tcs.Task;
  94. }
  95.  
  96. return base.WriteToStreamAsync(type, value, stream, content, transportContext)
  97. .ContinueWith(innerTask =>
  98. {
  99. if (innerTask.Status == TaskStatus.RanToCompletion)
  100. {
  101. writer.Write(")");
  102. writer.Flush();
  103. }
  104.  
  105. }, TaskContinuationOptions.ExecuteSynchronously)
  106. .ContinueWith(innerTask =>
  107. {
  108. writer.Dispose();
  109. return innerTask;
  110.  
  111. }, TaskContinuationOptions.ExecuteSynchronously)
  112. .Unwrap();
  113. }
  114.  
  115. /// <summary>
  116. /// Retrieves the Jsonp Callback function
  117. /// from the query string
  118. /// </summary>
  119. /// <returns></returns>
  120. private string GetJsonCallbackFunction(HttpRequestMessage request)
  121. {
  122. if (request.Method != HttpMethod.Get)
  123. return null;
  124.  
  125. var query = HttpUtility.ParseQueryString(request.RequestUri.Query);
  126. var queryVal = query[this.JsonpParameterName];
  127.  
  128. if (string.IsNullOrEmpty(queryVal))
  129. return null;
  130.  
  131. return queryVal;
  132. }
  133. }

Report this snippet  

You need to login to post a comment.