public ResourceLinkModel(ResourceLink link, ResourceDescriptor destinationResourceDescriptor) : this() { Id = link.Id; Relation = link.Relation; DestinationResourceName = link.DestinationResourceName; foreach (var linkParam in link.Parameters) { var param = destinationResourceDescriptor.InputPramameters.FirstOrDefault(p => p.Name == linkParam.Name); if (param != null) { var paramModel = new ResourceLinkParameterModel { Name = linkParam.Name, Value = linkParam.Value, UseFixedValue = linkParam.UseFixedValue, Required = param.Required, ParameterType = param.ParameterType.Name }; if (param.Required) { RequiredParameters.Add(paramModel); } else { OptionalParameters.Add(paramModel); } } } }
public ResourceModel(ResourceDescriptor resource) : this() { ResourceName = resource.ResourceName; ResourceUri = resource.ResourceUri; IsListResource = resource.IsListResource; ImplicitLinkProvider = resource.ImplicitLinkProvider == null ? null : new ImplicitLinkProviderModel(resource.ImplicitLinkProvider); if (resource.InputPramameters != null && resource.InputPramameters.Length > 0) { InputParameters = resource.InputPramameters.Select(p => new HalParameterModel(p)).ToList(); } if (resource.OutputParameters != null && resource.OutputParameters.Length > 0) { OutputParameters = resource.OutputParameters.Select(p => new HalParameterModel(p)).ToList(); } }
public IEnumerable<PropertyResource> GetPropertyResources(ResourceDescriptor descriptor, object entity) { var propResources = new List<PropertyResource>(); Type type = entity.GetType(); var properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance); foreach(var prop in properties) { var isEnumerable = false; Type propType = prop.PropertyType; if (prop.PropertyType.IsGenericType) { var defType = prop.PropertyType.GetGenericTypeDefinition(); if (typeof(IEnumerable).IsAssignableFrom(defType)) { isEnumerable = true; } propType = prop.PropertyType.GetGenericArguments()[0]; } if (prop.PropertyType.IsArray) { propType = prop.PropertyType.GetElementType(); isEnumerable = true; } if (typeof(IItemResource).IsAssignableFrom(propType)) { var resourcePrefix = propType.Name; var propVal = prop.GetValue(entity, null); if (propVal != null) { var propResource = new PropertyResource(); propResource.IsEnumerable = isEnumerable; propResource.Value = propVal; propResource.ResourceNames.Add(ResourceDescriptor.NomalizeResourceName(resourcePrefix, "detail")); propResources.Add(propResource); } } } return propResources; }
/// <summary> /// get resources from type /// </summary> /// <param name="type">resource type</param> /// <returns>resources of this type</returns> private IEnumerable<ResourceDescriptor> GetResources(Type type) { var resources = new List<ResourceDescriptor>(); // get api actions var actions = type.GetMethods() .Where(o => o.IsPublic && !o.IsSpecialName && !o.IsSecurityTransparent && o.GetMethodImplementationFlags() == MethodImplAttributes.IL) .ToArray(); var halParameterProviders = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) .Where(o => o.IsDefined(typeof(HalParameterProviderAttribute), true)) .ToArray(); foreach (var action in actions) { var resAttrs = action.GetCustomAttributes(typeof(ResourceAttribute), true); if (resAttrs != null && resAttrs.Length > 0) { var resAttr = resAttrs[0] as ResourceAttribute; if (resAttr != null) { var resource = new ResourceDescriptor(); var controllerName = type.Name.Replace("Controller", ""); resource.ResourceName = NormalizeResourceName(resAttr.Name, controllerName, action.Name); if (string.IsNullOrEmpty(resAttr.Uri)) { string actionName = action.Name; if (_specialActionNames.Contains(action.Name.ToLower())) actionName = string.Empty; resource.ResourceUri = string.Format("/{{instance}}/{0}/{1}", controllerName.ToLower(), actionName.ToLower()).TrimEnd('/'); } else resource.ResourceUri = resAttr.Uri.Replace("{controller}", controllerName.ToLower()).Replace("{action}", action.Name.ToLower()); resource.IsListResource = resAttr.IsList; if (!string.IsNullOrEmpty(resAttr.ItemName)) { resource.IsListResource = true; resource.ItemResourceName = NormalizeResourceName(resAttr.ItemName, controllerName, null); } // set implicit link provider. implicit links means these links will be implictly added to the resource. if (resAttr.ImplicitLinksProvider != null && typeof(IImplicitLinkProvider).IsAssignableFrom(resAttr.ImplicitLinksProvider)) { var linksProvider = Activator.CreateInstance(resAttr.ImplicitLinksProvider) as IImplicitLinkProvider; resource.ImplicitLinkProvider = linksProvider; } // set property link provider. property links will visit the model type and automatically add reference resources to this resource if (resAttr.PropertyResourceProvider != null && typeof(IPropertyResourceProvider).IsAssignableFrom(resAttr.PropertyResourceProvider)) { var resourcesProvider = Activator.CreateInstance(resAttr.PropertyResourceProvider) as IPropertyResourceProvider; resource.PropertyResourceProvider = resourcesProvider; } List<HalParameter> inputParameters = new List<HalParameter>(); List<HalParameter> outputParameters = new List<HalParameter>(); var paras = action.GetParameters(); if (paras != null && paras.Count() > 0) { var halParas = paras.Where(o => o.GetCustomAttributes(true).OfType<HalParameterAttribute>().Count() > 0); if (halParas.Count() > 0) { foreach (var para in halParas) { var pa = para.GetCustomAttributes(true).OfType<HalParameterAttribute>().First(); if (string.IsNullOrEmpty(pa.Name)) pa.Name = para.Name; if (pa.ParameterType == null) pa.ParameterType = para.ParameterType; if (!pa.Required) pa.Required = !para.IsOptional && IsTypeRequired(pa.ParameterType); inputParameters.Add(new HalParameter(HalParameter.NormailizeParameterName(controllerName, pa.Name), pa.ParameterType, pa.Required)); } } else { foreach (var para in paras) { if (IsSimpleType(para.ParameterType)) { bool required = !para.IsOptional && IsTypeRequired(para.ParameterType); inputParameters.Add(new HalParameter(HalParameter.NormailizeParameterName(controllerName, para.Name), para.ParameterType, required)); } } } if (action.ReturnType != typeof(void)) { var returnPara = action.ReturnParameter; if (IsSimpleType(returnPara.ParameterType)) { outputParameters.Add(new HalParameter(returnPara.Name, returnPara.ParameterType, IsTypeRequired(returnPara.ParameterType))); } else { var ptype = returnPara.ParameterType; if (ptype.IsGenericType && ptype.GetGenericTypeDefinition().Equals(typeof(IListResource<>))) ptype = ptype.GetGenericTypeDefinition().GetGenericArguments()[0]; if (typeof(IItemResource).IsAssignableFrom(ptype)) { var returnParas = ptype.GetProperties(); foreach (var para in returnParas) { if (para.Name == "Links") continue; if (IsSimpleType(para.PropertyType)) { outputParameters.Add(new HalParameter(HalParameter.NormailizeParameterName(ptype.Name, para.Name), para.PropertyType, IsTypeRequired(para.PropertyType))); } } } } } } // add parameters from hal parameter provider string resName = (string.IsNullOrEmpty(resAttr.Name) ? action.Name : resAttr.Name).ToLower(); if (halParameterProviders != null && halParameterProviders.Count() > 0) { foreach (var halParameterProvider in halParameterProviders) { var providerAttr = halParameterProvider.GetCustomAttributes(true).OfType<HalParameterProviderAttribute>().First(); if (providerAttr.ForResources == null || providerAttr.ForResources.Count() <= 0 || providerAttr.ForResources.Contains(resName)) { var pattrs = halParameterProvider.GetCustomAttributes(true).OfType<HalParameterAttribute>(); foreach (var pattr in pattrs) { string pname = HalParameter.NormailizeParameterName(controllerName, pattr.Name); if (inputParameters.Any(o => o.Name == pname)) continue; inputParameters.Add(new HalParameter(pname, pattr.ParameterType, pattr.Required)); } } } } resource.InputPramameters = inputParameters.ToArray(); resource.OutputParameters = outputParameters.ToArray(); resources.Add(resource); } } } return resources; }