moved owin config to its own file,
removed predefined route definition in favour of mapping attributes on ApiController classes. Added JsonpFormatter to ensure cross-domain api web requests will work to this API. added formatter to HTTPConfiguration for owin config.
This commit is contained in:
parent
10027d7f22
commit
bc3c7a5e31
@ -0,0 +1,171 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Net.Http.Formatting;
|
||||||
|
using System.Net.Http.Headers;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Web;
|
||||||
|
using Newtonsoft.Json.Converters;
|
||||||
|
|
||||||
|
namespace WindowsDataCenter
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Handles JsonP requests when requests are fired with text/javascript
|
||||||
|
/// </summary>
|
||||||
|
public class JsonpFormatter : JsonMediaTypeFormatter
|
||||||
|
{
|
||||||
|
|
||||||
|
public JsonpFormatter()
|
||||||
|
{
|
||||||
|
SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
|
||||||
|
SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/javascript"));
|
||||||
|
|
||||||
|
JsonpParameterName = "callback";
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Name of the query string parameter to look for
|
||||||
|
/// the jsonp function name
|
||||||
|
/// </summary>
|
||||||
|
public string JsonpParameterName { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Captured name of the Jsonp function that the JSON call
|
||||||
|
/// is wrapped in. Set in GetPerRequestFormatter Instance
|
||||||
|
/// </summary>
|
||||||
|
private string JsonpCallbackFunction;
|
||||||
|
|
||||||
|
|
||||||
|
public override bool CanWriteType(Type type)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Override this method to capture the Request object
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="type"></param>
|
||||||
|
/// <param name="request"></param>
|
||||||
|
/// <param name="mediaType"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public override MediaTypeFormatter GetPerRequestFormatterInstance(Type type, System.Net.Http.HttpRequestMessage request, MediaTypeHeaderValue mediaType)
|
||||||
|
{
|
||||||
|
var formatter = new JsonpFormatter()
|
||||||
|
{
|
||||||
|
JsonpCallbackFunction = GetJsonCallbackFunction(request)
|
||||||
|
};
|
||||||
|
|
||||||
|
// this doesn't work unfortunately
|
||||||
|
//formatter.SerializerSettings = GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings;
|
||||||
|
|
||||||
|
// You have to reapply any JSON.NET default serializer Customizations here
|
||||||
|
formatter.SerializerSettings.Converters.Add(new StringEnumConverter());
|
||||||
|
formatter.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.Indented;
|
||||||
|
|
||||||
|
return formatter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Task WriteToStreamAsync(
|
||||||
|
Type type,
|
||||||
|
object value,
|
||||||
|
Stream stream,
|
||||||
|
HttpContent content,
|
||||||
|
TransportContext transportContext
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(JsonpCallbackFunction))
|
||||||
|
{
|
||||||
|
return base.WriteToStreamAsync(type, value, stream, content, transportContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
// write the JSONP pre-amble
|
||||||
|
var preamble = Encoding.ASCII.GetBytes(JsonpCallbackFunction + "(");
|
||||||
|
stream.Write(preamble, 0, preamble.Length);
|
||||||
|
|
||||||
|
return base.WriteToStreamAsync(type, value, stream, content, transportContext).ContinueWith((innerTask, state) =>
|
||||||
|
{
|
||||||
|
if (innerTask.Status == TaskStatus.RanToCompletion)
|
||||||
|
{
|
||||||
|
// write the JSONP suffix
|
||||||
|
var responseStream = (Stream)state;
|
||||||
|
var suffix = Encoding.ASCII.GetBytes(")");
|
||||||
|
responseStream.Write(suffix, 0, suffix.Length);
|
||||||
|
}
|
||||||
|
}, stream, TaskContinuationOptions.ExecuteSynchronously);
|
||||||
|
}
|
||||||
|
//public override Task WriteToStreamAsync(
|
||||||
|
// Type type,
|
||||||
|
// object value,
|
||||||
|
// Stream stream,
|
||||||
|
// HttpContent content,
|
||||||
|
// TransportContext transportContext)
|
||||||
|
//{
|
||||||
|
// if (string.IsNullOrEmpty(JsonpCallbackFunction))
|
||||||
|
// return base.WriteToStreamAsync(type, value, stream, content, transportContext);
|
||||||
|
|
||||||
|
// StreamWriter writer = null;
|
||||||
|
|
||||||
|
// // write the pre-amble
|
||||||
|
// try
|
||||||
|
// {
|
||||||
|
// writer = new StreamWriter(stream);
|
||||||
|
// writer.Write(JsonpCallbackFunction + "(");
|
||||||
|
// writer.Flush();
|
||||||
|
// }
|
||||||
|
// catch (Exception ex)
|
||||||
|
// {
|
||||||
|
// try
|
||||||
|
// {
|
||||||
|
// if (writer != null)
|
||||||
|
// writer.Dispose();
|
||||||
|
// }
|
||||||
|
// catch { }
|
||||||
|
|
||||||
|
// var tcs = new TaskCompletionSource<object>();
|
||||||
|
// tcs.SetException(ex);
|
||||||
|
// return tcs.Task;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return base.WriteToStreamAsync(type, value, stream, content, transportContext)
|
||||||
|
// .ContinueWith(innerTask =>
|
||||||
|
// {
|
||||||
|
// if (innerTask.Status == TaskStatus.RanToCompletion)
|
||||||
|
// {
|
||||||
|
// writer.Write(")");
|
||||||
|
// writer.Flush();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// }, TaskContinuationOptions.ExecuteSynchronously)
|
||||||
|
// .ContinueWith(innerTask =>
|
||||||
|
// {
|
||||||
|
// writer.Dispose();
|
||||||
|
// return innerTask;
|
||||||
|
|
||||||
|
// }, TaskContinuationOptions.ExecuteSynchronously)
|
||||||
|
// .Unwrap();
|
||||||
|
//}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves the Jsonp Callback function
|
||||||
|
/// from the query string
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
private string GetJsonCallbackFunction(HttpRequestMessage request)
|
||||||
|
{
|
||||||
|
if (request.Method != HttpMethod.Get)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var query = HttpUtility.ParseQueryString(request.RequestUri.Query);
|
||||||
|
var queryVal = query[this.JsonpParameterName];
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(queryVal))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return queryVal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -69,18 +69,9 @@ namespace WindowsDataCenter
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public class StartOwin
|
|
||||||
{
|
{
|
||||||
public void Configuration(IAppBuilder appBuilder)
|
|
||||||
{
|
{
|
||||||
var config = new HttpConfiguration();
|
|
||||||
config.Routes.MapHttpRoute(
|
|
||||||
name: "DefaultApi",
|
|
||||||
routeTemplate: "api/{controller}/{id}",
|
|
||||||
defaults: new { id = RouteParameter.Optional }
|
|
||||||
);
|
|
||||||
|
|
||||||
appBuilder.UseWebApi(config);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,24 @@
|
|||||||
|
using System.Web.Http;
|
||||||
|
using Owin;
|
||||||
|
|
||||||
|
namespace WindowsDataCenter
|
||||||
|
{
|
||||||
|
public class StartOwin
|
||||||
|
{
|
||||||
|
public void Configuration(IAppBuilder appBuilder)
|
||||||
|
{
|
||||||
|
var config = new HttpConfiguration();
|
||||||
|
//config.Routes.MapHttpRoute(
|
||||||
|
// name: "DefaultApi",
|
||||||
|
// routeTemplate: "api/{controller}/{id}",
|
||||||
|
// defaults: new { id = RouteParameter.Optional }
|
||||||
|
//);
|
||||||
|
config.MapHttpAttributeRoutes();
|
||||||
|
|
||||||
|
config.Formatters.Insert(0, new JsonpFormatter());
|
||||||
|
|
||||||
|
|
||||||
|
appBuilder.UseWebApi(config);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user