/// <summary> /// Injects route to app pipeline. /// </summary> /// <param name="app">The instance of <see cref="IAppBuilder"/>.</param> /// <param name="configureRoute">Action for configure the route.</param> public static IAppBuilder Route(this IAppBuilder app, Action <MapRouteBuilder> configureRoute) { var route = new MapRouteBuilder(app); configureRoute(route); return(app.UseRoute(route)); }
private static IAppBuilder UseRoute(this IAppBuilder app, MapRouteBuilder mapRouteBuilder) { app.Use(async(ctx, next) => { var handler = mapRouteBuilder.GetHandler(ctx); if (handler != null) { await handler(ctx); } else { await next(); } }); return(app); }
/// <summary> /// Registers methods annotated with <see cref="RouteAttribute"/> into routing pipeline. /// </summary> /// <typeparam name="T">Type to reflect.</typeparam> /// <param name="mapRouteBuilder">The fluent API to register http method handlers.</param> /// <param name="getInstance">Function to get instance of T.</param> /// <returns></returns> public static MapRouteBuilder UseApi <T>(this MapRouteBuilder mapRouteBuilder, Func <IOwinContext, T> getInstance) { if (getInstance == null) { throw new ArgumentNullException("getInstance"); } var type = typeof(T); var prefixAttr = type.GetAttribute <RoutePrefixAttribute>(); var prefix = prefixAttr != null ? prefixAttr.Prefix : string.Empty; var serializerSettings = type.GetProperties(BindingFlags.Static | BindingFlags.FlattenHierarchy | BindingFlags.Public) .Where(p => p.HasAttribute <ResponseSerializerSettingsAttribute>() && p.PropertyType == typeof(JsonSerializerSettings)) .Select(p => p.GetValue(null) as JsonSerializerSettings) .FirstOrDefault(); var errorHandler = type.GetMethods(BindingFlags.Static | BindingFlags.FlattenHierarchy | BindingFlags.Public) .Where(m => m.HasAttribute <ErrorHandlerAttribute>()) .Select(m => DynamicMethods.CompileMethod(type, m)) .FirstOrDefault(); const BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static; var actions = (from m in type.GetMethods(bindingFlags) let route = m.GetAttribute <RouteAttribute>() where route != null select new { Method = m, Route = route }).ToList(); actions.ForEach(a => { var invoke = DynamicMethods.CompileMethod(type, a.Method); var mapper = ParameterMapper.Build(a.Method); var returnType = a.Method.ReturnType; var verb = GetHttpMethod(a.Method); var pattern = AddPrefix(prefix, a.Route.Template); mapRouteBuilder.Register(pattern, verb, async ctx => { Exception error; var args = MapParameters(ctx, mapper, out error); if (error != null) { if (null != errorHandler) { var errorResponse = errorHandler(null, new object[] { ctx, error }); if (null != errorResponse) { await ctx.WriteJson(errorResponse); } } else { ctx.Response.StatusCode = (int)HttpStatusCode.BadRequest; await ctx.WriteJson(new { error = error.Message }); } return; } var instance = a.Method.IsStatic ? (object)null : getInstance(ctx); var result = invoke(instance, args); var task = result as Task; if (null != task) { result = await HandleAsyncResult(task, returnType); } if (result != null) { await ctx.WriteJson(result, serializerSettings); } }); }); return(mapRouteBuilder); }
/// <summary> /// Registers methods annotated with <see cref="RouteAttribute"/> into routing pipeline. /// </summary> /// <typeparam name="T">Type to reflect.</typeparam> /// <param name="routeBuilder">The fluent API to register http method handlers.</param> public static MapRouteBuilder UseApi <T>(this MapRouteBuilder routeBuilder) { var init = DependencyInjection.CompileInitializer <T>(); return(routeBuilder.UseApi(init)); }