private static string CreateArgumentStyle(string value, LinkArgumentStyle linkArgumentStyle) { switch (linkArgumentStyle) { case LinkArgumentStyle.Normal: return(string.Format("{{{0}}}", value)); break; case LinkArgumentStyle.Angular: return(string.Format(":{0}", value)); break; default: throw new ArgumentOutOfRangeException("linkArgumentStyle"); } }
private void PopulateList(Type type, dynamic model, LinkArgumentStyle linkArgumentStyle) { if (model == null) { return; } if (type.BaseType != null && IsListOrArray(type.BaseType)) { type = type.BaseType; } Type listType = type.IsArray ? type.GetElementType() : type.GetGenericArguments()[0]; foreach (object item in model) { Populate(listType, item, linkArgumentStyle); } }
public void Populate(Type modelType, object model, LinkArgumentStyle linkArgumentStyle) { if (IsListOrArray(modelType)) { PopulateList(modelType, model, linkArgumentStyle); } else { if (!modelType.IsSealed && model != null) { modelType.GetProperties().ForEach(propertyInfo => Populate(propertyInfo.PropertyType, propertyInfo.GetValue(model, null), linkArgumentStyle)); } var linkAttributes = modelType.GetCustomAttributes(typeof(LinksToAttribute), true).Cast <LinksToAttribute>(); foreach (var linkAttribute in linkAttributes) { IGenerateLinksFor linkGenerator = null; if (linkAttribute.ResponseType != null) { var linkGeneratorType = typeof(IGenerateLinksFor <,>).MakeGenericType(linkAttribute.ResponseType, modelType); linkGenerator = _linkGenerators.SingleOrDefault(linkGeneratorType.IsInstanceOfType); } if (linkGenerator != null) { var route = _linkGenerator.FindHttpRoute(linkAttribute.ResponseType); linkGenerator.GetType().GetMethod("Generate").Invoke(linkGenerator, new object[] { linkAttribute, model, route, linkArgumentStyle }); } else { MethodInfo generic = _linkGenerator.GetType().GetMethod("Generate").MakeGenericMethod(modelType); if (linkAttribute.LinkType == LinkTo.Resource) { generic.Invoke(_linkGenerator, new object[] { linkAttribute.ResponseType, linkAttribute.Name, model, linkArgumentStyle }); } else { generic.Invoke(_linkGenerator, new object[] { modelType, linkAttribute.LinkType.ToString(), model, linkArgumentStyle }); } } } } }
private string ConstructUrl <T>(T onModel, IHttpRoute route, LinkArgumentStyle linkArgumentStyle) { return("/" + RouteHelpers.Link(route.RouteTemplate, onModel, linkArgumentStyle)); }
public void Generate <T>(Type linkResourceType, string resourceName, T onModel, LinkArgumentStyle linkArgumentStyle) where T : BaseApiResponse { var route = FindHttpRoute(linkResourceType); onModel.AddLink(resourceName, ConstructUrl(onModel, route, linkArgumentStyle)); }
public Link GetLink(IHttpRoute linkRoute, object o, LinkArgumentStyle linkArgumentStyle) { return(new Link(Name, RouteHelpers.Link(linkRoute.RouteTemplate, o, linkArgumentStyle))); }
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) { HttpMethod httpMethod = actionExecutedContext.Request.Method; IEnumerable <string> linkStyle; var linkStyleHeader = actionExecutedContext.Request.Headers.TryGetValues("X-Api-Linkstyle", out linkStyle); LinkArgumentStyle linkArgumentStyle = LinkArgumentStyle.Normal; if (linkStyle != null) { linkArgumentStyle = linkStyle.First().Equals("angular", StringComparison.InvariantCultureIgnoreCase) ? LinkArgumentStyle.Angular : LinkArgumentStyle.Normal; } if (httpMethod == HttpMethod.Put || httpMethod == HttpMethod.Post || httpMethod == HttpMethod.Delete) { var arguments = actionExecutedContext.ActionContext.ActionArguments; object requestObject = FindObjects(arguments, false).SingleOrDefault().Value; var extraArguments = FindObjects(arguments, true); var returnType = actionExecutedContext.ActionContext.ActionDescriptor.ReturnType; var innerType = returnType.GetGenericArguments().First(); var commandMap = GetMapThatMapsFrom(requestObject.GetType()); var commandType = commandMap.DestinationType; var command = Activator.CreateInstance(commandType); AutoMapper.Mapper.Map(requestObject, command, requestObject.GetType(), commandType); command.TryToSetPropertiesFromDictionary(extraArguments); var result = _commandExecutor.ExecuteCommand(command); if (result.Status == CommandStatus.Executed) { if (httpMethod == HttpMethod.Post || httpMethod == HttpMethod.Put) { var destinationMap = AutoMapper.Mapper.GetAllTypeMaps().SingleOrDefault(map => map.DestinationType == innerType); var returnObject = Activator.CreateInstance(innerType); AutoMapper.Mapper.Map(result.Data, returnObject, destinationMap.SourceType, destinationMap.DestinationType); _linkPopulator.Populate(innerType, returnObject, linkArgumentStyle); actionExecutedContext.Response.StatusCode = httpMethod == HttpMethod.Post ? HttpStatusCode.Created : HttpStatusCode.OK; actionExecutedContext.Response.Content = new ObjectContent(typeof(BaseApiResponse), returnObject as BaseApiResponse, _configuration.Formatters .JsonFormatter); } else { actionExecutedContext.Response.StatusCode = HttpStatusCode.NoContent; actionExecutedContext.Response.Content = new StringContent(string.Empty); } } if (result.Status != CommandStatus.Executed) { actionExecutedContext.Response = new HttpResponseMessage(HttpStatusCode.InternalServerError) { Content = new StringContent(result.Message) }; } } if (httpMethod == HttpMethod.Get) { var returnType = actionExecutedContext.ActionContext.ActionDescriptor.ReturnType; var innerType = returnType.GetGenericArguments().First(); var destinationMap = AutoMapper.Mapper.GetAllTypeMaps().SingleOrDefault(map => map.DestinationType == innerType); if (destinationMap == null) { if (!Configuration.RequiresContractMapping) { AutoMapper.Mapper.CreateMap(innerType, innerType); destinationMap = AutoMapper.Mapper.GetAllTypeMaps().SingleOrDefault(map => map.DestinationType == innerType); } else { throw new ResponseMapNotFoundException( string.Format("No map was found to map a contract to {0}", innerType), innerType); } } var contract = _contractConstructors.ConstructContractFromRouteData(destinationMap.SourceType, actionExecutedContext.ActionContext); _dataProviders.FillModelFromProviders(contract.GetType(), contract); var response = _mapper.Map(contract, contract.GetType(), innerType); _linkPopulator.Populate(response.GetType(), response, linkArgumentStyle); response = Explode(response); actionExecutedContext.Response.Content = new ObjectContent(response.GetType(), response, _configuration.Formatters.JsonFormatter); } }
public static string Link(string relativeUrl, object routeValues, LinkArgumentStyle linkArgumentStyle) { relativeUrl = PopulateRelativeUrl(relativeUrl.ToLower(), routeValues, linkArgumentStyle); return(relativeUrl); }
private static string PopulateRelativeUrl(string relativeUrl, object routeValues, LinkArgumentStyle linkArgumentStyle) { string regexPattern = "{{{0}.*?}}"; foreach (var property in routeValues.GetType().GetProperties()) { var propertyValue = property.GetValue(routeValues, null); if (propertyValue != null) { relativeUrl = Regex.Replace(relativeUrl, string.Format(regexPattern, property.Name), propertyValue.ToString(), RegexOptions.IgnoreCase); } } foreach (Match match in Regex.Matches(relativeUrl, @"\{(?<name>(.+))\}")) { string argument = CreateArgumentStyle(match.Groups["name"].Value, linkArgumentStyle); relativeUrl = relativeUrl.Replace(match.Value, argument); } return(relativeUrl); }