public static MetadataPlainObjects.Fields Generate(MappingRule mappingRule, ApiDescription apiDescription, object originalObject) { var fromBodyParameterType = (from param in mappingRule.MethodExpression.Method.GetParameters() let fromBodyAttr = param.GetCustomAttribute<FromBodyAttribute>() where fromBodyAttr != null select param.ParameterType).FirstOrDefault(); if (fromBodyParameterType == null) return GenerateFromGet(mappingRule, apiDescription, originalObject); var result = new MetadataPlainObjects.Fields(); result.AddRange(from property in fromBodyParameterType.GetProperties() let fieldName = GetFieldName(property) let propVal = property.GetValue(originalObject) let jsonIgnore = property.GetCustomAttribute<JsonIgnoreAttribute>() where jsonIgnore == null select new MetadataPlainObjects.Field { FieldName = fieldName, FieldType = GetFieldType(property), FieldValue = propVal == null ? null : propVal.ToString() }); return result; }
public List<string> Build(MappingRule mappingRule, string method) { if (mappingRule.Names.Any()) return mappingRule.Names; return _defaultRouteNameBuilder.Value.Build(mappingRule, method); }
public void TestSubstitution() { var sub = new DefaultRouteValueSubstitution(); Expression<Func<ControllerSample, ModelSample, ModelSample>> lambda = (c, m) => c.ControllerMethod(m.Id, m.Name, QueryParameter.Is<string>(), QueryParameter.Is<int>()); var methodCallExpression = (MethodCallExpression)lambda.Body; var apiExplorerMoq = new Mock<IApiExplorer>(); apiExplorerMoq.Setup(_ => _.ApiDescriptions).Returns(new Collection<ApiDescription>() { new ApiDescription() { } }); var mr = new MappingRule(methodCallExpression, apiExplorerMoq.Object); var payload = new ModelSample() { Id = 1, Name = "test &?{}<>", Price = 3.2 }; var result = sub.Substitute("/Product/{id}/Details?query={query}&skip={skip}&displayname={name}", mr, payload); Assume.That(result, Is.EqualTo("/Product/1/Details?query=:query&skip=:skip&displayname=test+%26%3f%7b%7d%3c%3e")); }
public void TestFromBody() { var sub = new DefaultRouteValueSubstitution(); Expression<Func<ControllerSample, ModelSample, ModelSample>> lambda = (c, m) => c.ControllerMethodPut(m.Id, m); var methodCallExpression = (MethodCallExpression)lambda.Body; var apiExplorerMoq = new Mock<IApiExplorer>(); apiExplorerMoq.Setup(_ => _.ApiDescriptions).Returns(new Collection<ApiDescription>() { new ApiDescription() { HttpMethod = HttpMethod.Get } }); var mr = new MappingRule(methodCallExpression, apiExplorerMoq.Object); var payload = _fixture.CreateAnonymous<ModelSample>(); var fields = ActionFieldsGenerator.Generate(mr, apiExplorerMoq.Object.ApiDescriptions[0], payload); Assume.That(fields, Is.Not.Null); var names = fields.ConvertAll(f => f.FieldName); Assume.That(names, Is.EquivalentTo(new[] { "Id", "Name", "Price", "email_address" })); var types = fields.ConvertAll(f => f.FieldType); Assume.That(types, Is.EqualTo(new object[]{null, null, null, "email"})); var values = fields.ConvertAll(f => f.FieldValue); Assume.That(values, Is.EqualTo(new object[] { payload.Id.ToString(), payload.Name, payload.Price.ToString(), payload.EMailAddress })); }
public void AddNewRule(Expression expression) { var methodExpression = (MethodCallExpression)expression; var rule = new MappingRule(methodExpression, _httpConfiguration.Services.GetApiExplorer()); ActionConfiguration.AddMappingRule(rule); }
private static string[] GetClassArray(MappingRule mappingRule) { var returnType = mappingRule.MethodExpression.Method.ReturnType; if (returnType.IsGenericType && typeof(IEnumerable<>).IsAssignableFrom(returnType.GetGenericTypeDefinition())) { return new[] { SirenMetadataProvider.QueryClassName }; } return null; }
public static List<string> GetRelList(MappingRule mapping, ApiDescription apiDescription, List<string> rels) { var result = new List<string>(rels); var returnType = mapping.MethodExpression.Method.ReturnType; if (returnType.IsGenericType && typeof(IEnumerable<>).IsAssignableFrom(returnType.GetGenericTypeDefinition())) result.Add(SirenMetadataProvider.QueryClassName); return result; }
public void ReturnHttpresponseAttributedParam() { Expression<Func<ControllerSample, ModelSample, HttpResponseMessage>> lambda = (c, m) => c.ControllerHttpResponseMessageMethodWithTypeParam(m.Price); var methodCallExpression = (MethodCallExpression)lambda.Body; var mappingRule = new MappingRule(methodCallExpression, null); var result = _routeNameBuilder.Build(mappingRule, "get"); Assume.That(result, Is.EquivalentTo(new[] { "get_string_by_price" })); }
public void ReturnHttpresponse() { Expression<Func<ControllerSample, HttpResponseMessage>> lambda = (c) => c.ControllerHttpResponseMessageMethod(); var methodCallExpression = (MethodCallExpression)lambda.Body; var mappingRule = new MappingRule(methodCallExpression, null); var result = _routeNameBuilder.Build(mappingRule, "get"); Assume.That(result, Is.EquivalentTo(new[] { "get" })); }
public void ReturnEnumerable() { Expression<Func<ControllerSample, ModelSample, IEnumerable<ModelSample>>> lambda = (c, m) => c.ControllerQueryMethod(m.Id, m.Name, m.Name, m.Id); var methodCallExpression = (MethodCallExpression)lambda.Body; var mappingRule = new MappingRule(methodCallExpression, null); var result = _routeNameBuilder.Build(mappingRule, "get"); Assume.That(result, Is.EquivalentTo(new[] { "query_modelsample_by_id_name_query_skip" })); }
private static string DeduceContentType(MappingRule mappingRule, ApiDescription apiDescription, object originalObject) { if (mappingRule.ContentType != null) return mappingRule.ContentType.MediaType; if (apiDescription.HttpMethod != HttpMethod.Post) return null; //if (IsOrContains(typeof(System.Web.HttpPostedFileBase), originalObject.GetType())) // return "multipart/form-data"; return "application/x-www-form-urlencoded"; }
public string Substitute(string templateUrl, MappingRule mapping, Object data) { var methodParameters = mapping.MethodExpression.Method.GetParameters(); var expressionArguments = mapping.MethodExpression.Arguments.GetEnumerator(); var result = new StringBuilder(templateUrl); foreach (var methodParameter in methodParameters) { expressionArguments.MoveNext(); var parameterTemplateName = string.Format("{{{0}}}", methodParameter.Name); if (!templateUrl.Contains(parameterTemplateName)) continue; if (!mapping.ParameterDelegates.ContainsKey(methodParameter.Name)) { Debug.Write(string.Format("Unable to obtain delegate for parameter {0}, URL: {1}", methodParameter.Name, templateUrl)); continue; } var paramDelegate = mapping.ParameterDelegates[methodParameter.Name]; var paramResult = paramDelegate.DynamicInvoke(data); if (paramResult == null) { Debug.Write(string.Format("Unable to get result for parameter {0}, URL: {1}", methodParameter.Name, templateUrl)); continue; } var stringResult = paramResult.ToString(); var expressionArgunemt = (expressionArguments.Current as MethodCallExpression); if (expressionArgunemt != null && expressionArgunemt.Method.DeclaringType == typeof (QueryParameter)) { result.Replace(parameterTemplateName, stringResult); } else { result.Replace(parameterTemplateName, HttpUtility.UrlEncode(stringResult)); } } return result.ToString(); }
public void Complex() { Expression<Func<ControllerSample, ModelSample, ModelSample>> lambda = (test, model) => test.ControllerMethod(model.Id, model.Name, QueryParameter.Is<string>(), QueryParameter.Is<int>()); var methodCallExpression = (MethodCallExpression)lambda.Body; var httpControllerDescriptor = _fixture.CreateAnonymous<HttpControllerDescriptor>(); var apiExplorerMoq = new Mock<IApiExplorer>(); apiExplorerMoq.Setup(_ => _.ApiDescriptions).Returns(new Collection<ApiDescription>() { new ApiDescription() { ActionDescriptor = new ReflectedHttpActionDescriptor(httpControllerDescriptor, methodCallExpression.Method), HttpMethod = HttpMethod.Get, RelativePath = "/api" } }); var mappingRule = new MappingRule(methodCallExpression, apiExplorerMoq.Object); _actionConfiguration.AddMappingRule(mappingRule); _actionConfiguration.Configure(); var originalType = typeof(ModelSample); var strategy = _defaultStrategyFactory.Build(_actionConfiguration, originalType); Assume.That(strategy.ClassKey(originalType), Is.StringContaining("_NHateoas.Tests.ModelSample_SP_SR")); var typeBuilder = new TypeBuilder(originalType, strategy); var type = typeBuilder.BuildType(); Assume.That(type.Name, Is.EqualTo(originalType.Name)); Assume.That(type.FullName, Is.StringContaining("_NHateoas.Tests.ModelSample_SP_SR")); var props = type.GetProperties(); Assume.That(props, Is.Not.Empty); var propNames = props.ToList().ConvertAll(p => p.Name); Assume.That(propNames, Is.EquivalentTo(new[] { "Id", "Name", "Price", "EMailAddress", "get_modelsample_by_id_name_query_skip" })); var propTypes = props.ToList().ConvertAll(p => p.PropertyType.Name); Assume.That(propTypes, Is.EquivalentTo(new[] { "Int32", "String", "Double", "String", "String" })); var instance = Activator.CreateInstance(type); var original = _fixture.CreateAnonymous<ModelSample>(); strategy.ActivateInstance(instance, original, _actionConfiguration); var propValues = props.ToList().ConvertAll(p => p.GetValue(instance).ToString()); Assume.That(propValues, Is.EquivalentTo(new[] { original.Id.ToString(), original.Name, original.Price.ToString(), original.EMailAddress, "/api" })); }
public List<string> Build(MappingRule mappingRule, string method) { var methodName = method.ToLower(); var name = new StringBuilder(); var actionMethodInfo = mappingRule.MethodExpression.Method; var returnType = actionMethodInfo.ReturnType; if (typeof (HttpResponseMessage).IsAssignableFrom(returnType)) { var attributes = actionMethodInfo.GetCustomAttributes<ResponseTypeAttribute>().ToList(); if (attributes.Any()) { returnType = attributes.First().ResponseType; } } if (returnType.IsGenericType && typeof (IEnumerable<>).IsAssignableFrom(returnType.GetGenericTypeDefinition())) { returnType = returnType.GetGenericArguments()[0]; methodName = "query"; } name.Append(methodName); if (returnType != typeof(void) && !returnType.IsAssignableFrom(typeof(HttpResponseMessage))) name.AppendFormat("_{0}", returnType.Name.ToLower()); var parameters = actionMethodInfo.GetParameters(); if (parameters.Any()) name.AppendFormat("_by"); foreach (var parameterInfo in parameters) { if (parameterInfo.GetType() == returnType) continue; name.AppendFormat("_{0}", parameterInfo.Name.ToLower()); } return new List<string> {name.ToString()}; }
public void DefaultCtor() { Expression<Func<ControllerSample, int>> lambda = (test) => test.FakeMethod(); var methodCallExpression = (MethodCallExpression) lambda.Body; var apiExplorerMoq = new Mock<IApiExplorer>(); apiExplorerMoq.Setup(_ => _.ApiDescriptions).Returns(new Collection<ApiDescription>() { new ApiDescription() { } }); var mappingRule = new MappingRule(methodCallExpression, apiExplorerMoq.Object); Assume.That(mappingRule.MethodExpression, Is.EqualTo(methodCallExpression)); Assume.That(mappingRule.ApiDescriptions, Is.Empty); Assume.That(mappingRule.ParameterDelegates, Is.Empty); Assume.That(mappingRule.Names, Is.Empty); Assume.That(mappingRule.Type, Is.EqualTo(MappingRule.RuleType.Default)); }
private static MetadataPlainObjects.Fields GenerateFromGet(MappingRule mappingRule, ApiDescription apiDescription, object originalObject) { if (apiDescription.HttpMethod != HttpMethod.Get) return null; var result = new MetadataPlainObjects.Fields(); int argumentCounter = 0; result.AddRange( from parameter in mappingRule.MethodExpression.Method.GetParameters() let isMemberExpression = mappingRule.MethodExpression.Arguments[argumentCounter++] is MemberExpression where mappingRule.ParameterDelegates.ContainsKey(parameter.Name) let paramDelegate = mappingRule.ParameterDelegates.ContainsKey(parameter.Name) ? mappingRule.ParameterDelegates[parameter.Name] : null select new MetadataPlainObjects.Field { FieldName = parameter.Name, FieldValue = (isMemberExpression && paramDelegate != null) ? paramDelegate.DynamicInvoke(originalObject).ToString() : null }); return result; }
public void ReturnModel() { Expression<Func<ControllerSample, ModelSample, ModelSample>> lambda = (c, m) => c.ControllerMethod(m.Id, m.Name, QueryParameter.Is<string>(), QueryParameter.Is<int>()); var methodCallExpression = (MethodCallExpression)lambda.Body; var mappingRule = new MappingRule(methodCallExpression, null); var result = _routeNameBuilder.Build(mappingRule, "get"); Assume.That(result, Is.EquivalentTo(new[] { "get_modelsample_by_id_name_query_skip" })); }
public void MapApiDescription() { Expression<Func<ControllerSample, int>> lambda = (test) => test.FakeMethod(); var methodCallExpression = (MethodCallExpression) lambda.Body; var actionDescriptor = new ReflectedHttpActionDescriptor(_fixture.CreateAnonymous<HttpControllerDescriptor>(), methodCallExpression.Method); var apiExplorerMoq = new Mock<IApiExplorer>(); apiExplorerMoq.Setup(_ => _.ApiDescriptions).Returns(new Collection<ApiDescription>() { new ApiDescription() { ActionDescriptor = actionDescriptor } }); var mappingRule = new MappingRule(methodCallExpression, apiExplorerMoq.Object); Assume.That(mappingRule.MethodExpression, Is.EqualTo(methodCallExpression)); Assume.That(mappingRule.ApiDescriptions, Is.Not.Empty); Assume.That(mappingRule.ParameterDelegates, Is.Empty); Assume.That(mappingRule.Names, Is.Empty); Assume.That(mappingRule.Type, Is.EqualTo(MappingRule.RuleType.Default)); }
public void TestNotFromBodyNotGet() { var sub = new DefaultRouteValueSubstitution(); Expression<Func<ControllerSample, ModelSample, ModelSample>> lambda = (c, m) => c.ControllerMethod(m.Id, m.Name, QueryParameter.Is<string>(), QueryParameter.Is<int>()); var methodCallExpression = (MethodCallExpression)lambda.Body; var apiExplorerMoq = new Mock<IApiExplorer>(); apiExplorerMoq.Setup(_ => _.ApiDescriptions).Returns(new Collection<ApiDescription>() { new ApiDescription() { } }); var mr = new MappingRule(methodCallExpression, apiExplorerMoq.Object); var payload = _fixture.CreateAnonymous<ModelSample>(); var fields = ActionFieldsGenerator.Generate(mr, apiExplorerMoq.Object.ApiDescriptions[0], payload); Assume.That(fields, Is.Null); }
public void AddMappingRule(MappingRule rule) { _mappingRules.Add(rule); }
public void Complex() { Expression<Func<ControllerSample, ModelSample, ModelSample>> lambda = (test, model) => test.ControllerMethod(model.Id, model.Name, QueryParameter.Is<string>(), QueryParameter.Is<int>()); var methodCallExpression = (MethodCallExpression)lambda.Body; var httpControllerDescriptor = _fixture.CreateAnonymous<HttpControllerDescriptor>(); Expression<Func<ControllerSample, int>> lambda2 = (test) => test.FakeMethodWithAttribute(); var apiExplorerMoq = new Mock<IApiExplorer>(); apiExplorerMoq.Setup(_ => _.ApiDescriptions).Returns(new Collection<ApiDescription>() { new ApiDescription() { ActionDescriptor = new ReflectedHttpActionDescriptor(httpControllerDescriptor, methodCallExpression.Method), HttpMethod = HttpMethod.Get, RelativePath = "/api" }, new ApiDescription() { ActionDescriptor = new ReflectedHttpActionDescriptor(httpControllerDescriptor, ((MethodCallExpression)lambda2.Body).Method), HttpMethod = HttpMethod.Post, RelativePath = "/api/test" } }); _actionConfiguration.AddMappingRule(new MappingRule(methodCallExpression, apiExplorerMoq.Object)); var rule = new MappingRule((MethodCallExpression)lambda2.Body, apiExplorerMoq.Object) { Type = MappingRule.RuleType.ActionRule }; rule.Names.Add("action-name"); _actionConfiguration.AddMappingRule(rule); _actionConfiguration.UseSirenSpecification(); _actionConfiguration.Configure(); var originalType = typeof(ModelSample); var strategy = _defaultStrategyFactory.Build(_actionConfiguration, originalType); Assume.That(strategy.ClassKey(originalType), Is.StringContaining("_NHateoas.Tests.ModelSample_PP")); var typeBuilder = new TypeBuilder(originalType, strategy); var type = typeBuilder.BuildType(); Assume.That(type.Name, Is.EqualTo(originalType.Name)); Assume.That(type.FullName, Is.StringContaining("_NHateoas.Tests.ModelSample_PP")); var props = type.GetProperties(); Assume.That(props, Is.Not.Empty); var propNames = new List<string>(); props.ToList().ForEach(p => { propNames.Add(p.Name); if (p.PropertyType == typeof(string)) return; if (p.PropertyType.IsArray && p.PropertyType.GetElementType() == typeof(string)) return; var pt = (p.PropertyType.BaseType != null && p.PropertyType.BaseType.IsGenericType) ? p.PropertyType.BaseType.GetGenericArguments()[0] : p.PropertyType; pt.GetProperties().ToList().ForEach(sp => propNames.Add(sp.Name)); }); Assume.That(propNames, Is.EquivalentTo(new[] { "properties", "Id", "Name", "Price", "EMailAddress", "class", "href","rel", "links", "RelList", "Href", "actions", "ActionName", "Class", "Title", "Method", "Href", "ContentType", "ActionFields" })); var propTypes = props.Where(p => !p.PropertyType.IsArray && p.PropertyType != typeof(string)).ToList().ConvertAll(p => p.PropertyType.Name); Assume.That(propTypes, Is.EquivalentTo(new[] { "ModelSample", "Links", "Actions"})); var instance = Activator.CreateInstance(type); var original = new ModelSample() { Id = 1, Name = "test", Price = 3.0, EMailAddress = "aa.bb@ccc" }; strategy.ActivateInstance(instance, original, _actionConfiguration); var result = JsonConvert.SerializeObject(instance); Assume.That(result, Is.EqualTo("{\"properties\":{\"Id\":1,\"Name\":\"test\",\"Price\":3.0,\"EMailAddress\":\"aa.bb@ccc\"},\"links\":[{\"rel\":[\"get_modelsample_by_id_name_query_skip\"],\"href\":\"http://localhost/api\"}],\"actions\":[{\"name\":\"rel-name\",\"method\":\"POST\",\"href\":\"http://localhost/api/test\",\"type\":\"application/x-www-form-urlencoded\"}]}")); }