public void Ctor() { var mt = new MimeTypeAttribute("member", "type"); Assert.AreEqual("member", mt.MemberName); Assert.AreEqual("type", mt.MimeType); }
private static void BuildTypeProperties(ResourceType parentResourceType, IDictionary <Type, ResourceType> knownTypes, IDictionary <ResourceType, List <ResourceType> > childTypes, Queue <ResourceType> unvisitedTypes, IEnumerable <ResourceSet> entitySets) { BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance; if (parentResourceType.BaseType != null) { bindingFlags |= BindingFlags.DeclaredOnly; } HashSet <string> set = new HashSet <string>(IgnorePropertiesAttribute.GetProperties(parentResourceType.InstanceType, false, bindingFlags), StringComparer.Ordinal); HashSet <string> source = new HashSet <string>(LoadETagProperties(parentResourceType), StringComparer.Ordinal); ResourceKeyKind kind = (ResourceKeyKind)0x7fffffff; PropertyInfo[] properties = parentResourceType.InstanceType.GetProperties(bindingFlags); if (!properties.Any <PropertyInfo>() && (parentResourceType.BaseType == null)) { throw new NotSupportedException(System.Data.Services.Strings.ReflectionProvider_ResourceTypeHasNoPublicallyVisibleProperties(parentResourceType.FullName)); } foreach (PropertyInfo info in properties) { if (!set.Contains(info.Name)) { ResourceType collectionResourceType; if (!info.CanRead || (info.GetIndexParameters().Length != 0)) { throw new InvalidOperationException(System.Data.Services.Strings.ReflectionProvider_InvalidProperty(info.Name, parentResourceType.FullName)); } ResourcePropertyKind collection = (ResourcePropertyKind)(-1); Type propertyType = info.PropertyType; bool flag = false; if (!BaseServiceProvider.TryGetType(knownTypes, propertyType, out collectionResourceType)) { Type iEnumerableElement = BaseServiceProvider.GetIEnumerableElement(info.PropertyType); if (iEnumerableElement != null) { BaseServiceProvider.TryGetType(knownTypes, iEnumerableElement, out collectionResourceType); flag = true; propertyType = iEnumerableElement; } } if (collectionResourceType != null) { if (collectionResourceType.ResourceTypeKind == ResourceTypeKind.Primitive) { if (flag) { collection = ResourcePropertyKind.Collection; } else { ResourceKeyKind kind3; if (((parentResourceType.BaseType == null) && (parentResourceType.ResourceTypeKind == ResourceTypeKind.EntityType)) && IsPropertyKeyProperty(info, out kind3)) { if (kind3 < kind) { if (parentResourceType.KeyProperties.Count != 0) { parentResourceType.RemoveKeyProperties(); } kind = kind3; collection = ResourcePropertyKind.Key | ResourcePropertyKind.Primitive; } else if (kind3 == kind) { collection = ResourcePropertyKind.Key | ResourcePropertyKind.Primitive; } else { collection = ResourcePropertyKind.Primitive; } } else { collection = ResourcePropertyKind.Primitive; } } } else if (collectionResourceType.ResourceTypeKind == ResourceTypeKind.ComplexType) { collection = flag ? ResourcePropertyKind.Collection : ResourcePropertyKind.ComplexType; } else if (collectionResourceType.ResourceTypeKind == ResourceTypeKind.EntityType) { collection = flag ? ResourcePropertyKind.ResourceSetReference : ResourcePropertyKind.ResourceReference; } } else { collectionResourceType = IsEntityOrComplexType(propertyType, knownTypes, childTypes, unvisitedTypes); if (collectionResourceType != null) { if (collectionResourceType.ResourceTypeKind == ResourceTypeKind.ComplexType) { if (flag) { if (BaseServiceProvider.GetIEnumerableElement(propertyType) != null) { throw new InvalidOperationException(System.Data.Services.Strings.ReflectionProvider_CollectionOfCollectionProperty(info.Name, parentResourceType.FullName)); } collection = ResourcePropertyKind.Collection; } else { collection = ResourcePropertyKind.ComplexType; } } else { collection = flag ? ResourcePropertyKind.ResourceSetReference : ResourcePropertyKind.ResourceReference; } } } if ((collectionResourceType == null) || ((collectionResourceType.ResourceTypeKind == ResourceTypeKind.EntityType) && (parentResourceType.ResourceTypeKind == ResourceTypeKind.ComplexType))) { if (collectionResourceType != null) { throw new InvalidOperationException(System.Data.Services.Strings.ReflectionProvider_ComplexTypeWithNavigationProperty(info.Name, parentResourceType.FullName)); } if (flag && (BaseServiceProvider.GetIEnumerableElement(propertyType) != null)) { throw new InvalidOperationException(System.Data.Services.Strings.ReflectionProvider_CollectionOfCollectionProperty(info.Name, parentResourceType.FullName)); } if (flag) { throw new InvalidOperationException(System.Data.Services.Strings.ReflectionProvider_CollectionOfUnsupportedTypeProperty(info.Name, parentResourceType.FullName, propertyType)); } if (CommonUtil.IsUnsupportedType(propertyType)) { throw new InvalidOperationException(System.Data.Services.Strings.BadProvider_UnsupportedPropertyType(info.Name, parentResourceType.FullName)); } throw new InvalidOperationException(System.Data.Services.Strings.ReflectionProvider_InvalidProperty(info.Name, parentResourceType.FullName)); } if ((collectionResourceType.ResourceTypeKind == ResourceTypeKind.EntityType) && (InternalGetContainerForResourceType(propertyType, entitySets) == null)) { throw new InvalidOperationException(System.Data.Services.Strings.ReflectionProvider_EntityPropertyWithNoEntitySet(parentResourceType.FullName, info.Name)); } if (collection == ResourcePropertyKind.Collection) { collectionResourceType = ResourceType.GetCollectionResourceType(collectionResourceType); } if (source.Remove(info.Name)) { collection |= ResourcePropertyKind.ETag; } ResourceProperty property = new ResourceProperty(info.Name, collection, collectionResourceType); MimeTypeAttribute mimeTypeAttribute = MimeTypeAttribute.GetMimeTypeAttribute(info); if (mimeTypeAttribute != null) { property.MimeType = mimeTypeAttribute.MimeType; } parentResourceType.AddProperty(property); } } if ((parentResourceType.ResourceTypeKind == ResourceTypeKind.EntityType) && ((parentResourceType.KeyProperties == null) || (parentResourceType.KeyProperties.Count == 0))) { throw new InvalidOperationException(System.Data.Services.Strings.ReflectionProvider_KeyPropertiesCannotBeIgnored(parentResourceType.FullName)); } if (source.Count != 0) { throw new InvalidOperationException(System.Data.Services.Strings.ReflectionProvider_ETagPropertyNameNotValid(source.ElementAt <string>(0), parentResourceType.FullName)); } }
public void Ctor() { var mt = new MimeTypeAttribute ("member", "type"); Assert.AreEqual ("member", mt.MemberName); Assert.AreEqual ("type", mt.MimeType); }
/// <summary> /// Adds a new <see cref="ServiceOperation"/> based on the specified <paramref name="method"/> /// instance. /// </summary> /// <param name="method">Method to expose as a service operation.</param> /// <param name="protocolMethod">Protocol (for example HTTP) method the service operation responds to.</param> private void AddServiceOperation(MethodInfo method, string protocolMethod) { Debug.Assert(method != null, "method != null"); Debug.Assert(!method.IsAbstract, "!method.IsAbstract - if method is abstract, the type is abstract - already checked"); // This method is only called for V1 providers, since in case of custom providers, // they are suppose to load the metadata themselves. if (this.metadata.ServiceOperations.ContainsKey(method.Name)) { throw new InvalidOperationException(Strings.BaseServiceProvider_OverloadingNotSupported(this.Type, method)); } bool hasSingleResult = SingleResultAttribute.MethodHasSingleResult(method); ServiceOperationResultKind resultKind; ResourceType resourceType = null; if (method.ReturnType == typeof(void)) { resultKind = ServiceOperationResultKind.Void; this.UpdateEdmSchemaVersion(MetadataEdmSchemaVersion.Version1Dot1); } else { // Load the metadata of the resource type on the fly. // For Edm provider, it might not mean anything, but for reflection service provider, we need to // load the metadata of the type if its used only in service operation case Type resultType = null; if (WebUtil.IsPrimitiveType(method.ReturnType)) { resultKind = ServiceOperationResultKind.DirectValue; resultType = method.ReturnType; resourceType = ResourceType.GetPrimitiveResourceType(resultType); } else { Type queryableElement = GetGenericInterfaceElementType(method.ReturnType, IQueryableTypeFilter); if (queryableElement != null) { resultKind = hasSingleResult ? ServiceOperationResultKind.QueryWithSingleResult : ServiceOperationResultKind.QueryWithMultipleResults; resultType = queryableElement; } else { Type enumerableElement = GetIEnumerableElement(method.ReturnType); if (enumerableElement != null) { resultKind = ServiceOperationResultKind.Enumeration; resultType = enumerableElement; } else { resultType = method.ReturnType; resultKind = ServiceOperationResultKind.DirectValue; this.UpdateEdmSchemaVersion(MetadataEdmSchemaVersion.Version1Dot1); } } Debug.Assert(resultType != null, "resultType != null"); resourceType = ResourceType.GetPrimitiveResourceType(resultType); if (resourceType == null) { resourceType = this.PopulateMetadataForType(resultType, this.TypeCache, this.ChildTypesCache, this.EntitySets.Values); } } if (resourceType == null) { throw new InvalidOperationException(Strings.BaseServiceProvider_UnsupportedReturnType(method, method.ReturnType)); } if (resultKind == ServiceOperationResultKind.Enumeration && hasSingleResult) { throw new InvalidOperationException(Strings.BaseServiceProvider_IEnumerableAlwaysMultiple(this.Type, method)); } if (hasSingleResult || (!hasSingleResult && (resourceType.ResourceTypeKind == ResourceTypeKind.ComplexType || resourceType.ResourceTypeKind == ResourceTypeKind.Primitive))) { this.UpdateEdmSchemaVersion(MetadataEdmSchemaVersion.Version1Dot1); } } ParameterInfo[] parametersInfo = method.GetParameters(); ServiceOperationParameter[] parameters = new ServiceOperationParameter[parametersInfo.Length]; for (int i = 0; i < parameters.Length; i++) { ParameterInfo parameterInfo = parametersInfo[i]; if (parameterInfo.IsOut || parameterInfo.IsRetval) { throw new InvalidOperationException(Strings.BaseServiceProvider_ParameterNotIn(method, parameterInfo)); } ResourceType parameterType = ResourceType.GetPrimitiveResourceType(parameterInfo.ParameterType); if (parameterType == null) { throw new InvalidOperationException( Strings.BaseServiceProvider_ParameterTypeNotSupported(method, parameterInfo, parameterInfo.ParameterType)); } string parameterName = parameterInfo.Name ?? "p" + i.ToString(CultureInfo.InvariantCulture); parameters[i] = new ServiceOperationParameter(parameterName, parameterType); } ResourceSet container = null; if (resourceType != null && resourceType.ResourceTypeKind == ResourceTypeKind.EntityType) { if (!this.TryFindAnyContainerForType(resourceType, out container)) { throw new InvalidOperationException( Strings.BaseServiceProvider_ServiceOperationMissingSingleEntitySet(method, resourceType.FullName)); } } ServiceOperation operation = new ServiceOperation(method.Name, resultKind, resourceType, container, protocolMethod, parameters); operation.CustomState = method; MimeTypeAttribute attribute = MimeTypeAttribute.GetMimeTypeAttribute(method); if (attribute != null) { operation.MimeType = attribute.MimeType; } this.metadata.ServiceOperations.Add(method.Name, operation); }
private void AddServiceOperation(MethodInfo method, string protocolMethod) { ServiceOperationResultKind @void; if (this.metadata.ServiceOperations.ContainsKey(method.Name)) { throw new InvalidOperationException(System.Data.Services.Strings.BaseServiceProvider_OverloadingNotSupported(this.Type, method)); } bool flag = SingleResultAttribute.MethodHasSingleResult(method); ResourceType primitive = null; if (method.ReturnType == typeof(void)) { @void = ServiceOperationResultKind.Void; } else { System.Type returnType; if (WebUtil.IsPrimitiveType(method.ReturnType)) { @void = ServiceOperationResultKind.DirectValue; returnType = method.ReturnType; primitive = ResourceType.PrimitiveResourceTypeMap.GetPrimitive(returnType); } else { System.Type genericInterfaceElementType = GetGenericInterfaceElementType(method.ReturnType, new TypeFilter(BaseServiceProvider.IQueryableTypeFilter)); if (genericInterfaceElementType != null) { @void = flag ? ServiceOperationResultKind.QueryWithSingleResult : ServiceOperationResultKind.QueryWithMultipleResults; returnType = genericInterfaceElementType; } else { System.Type iEnumerableElement = GetIEnumerableElement(method.ReturnType); if (iEnumerableElement != null) { @void = ServiceOperationResultKind.Enumeration; returnType = iEnumerableElement; } else { returnType = method.ReturnType; @void = ServiceOperationResultKind.DirectValue; } } primitive = ResourceType.PrimitiveResourceTypeMap.GetPrimitive(returnType); if (primitive == null) { primitive = this.PopulateMetadataForType(returnType, this.TypeCache, this.ChildTypesCache, this.EntitySets.Values); } } if (primitive == null) { throw new InvalidOperationException(System.Data.Services.Strings.BaseServiceProvider_UnsupportedReturnType(method, method.ReturnType)); } if ((@void == ServiceOperationResultKind.Enumeration) && flag) { throw new InvalidOperationException(System.Data.Services.Strings.BaseServiceProvider_IEnumerableAlwaysMultiple(this.Type, method)); } } ParameterInfo[] parameters = method.GetParameters(); ServiceOperationParameter[] parameterArray = new ServiceOperationParameter[parameters.Length]; for (int i = 0; i < parameterArray.Length; i++) { ParameterInfo info = parameters[i]; if (info.IsOut || info.IsRetval) { throw new InvalidOperationException(System.Data.Services.Strings.BaseServiceProvider_ParameterNotIn(method, info)); } ResourceType parameterType = ResourceType.PrimitiveResourceTypeMap.GetPrimitive(info.ParameterType); if (parameterType == null) { throw new InvalidOperationException(System.Data.Services.Strings.BaseServiceProvider_ParameterTypeNotSupported(method, info, info.ParameterType)); } string name = info.Name ?? ("p" + i.ToString(CultureInfo.InvariantCulture)); parameterArray[i] = new ServiceOperationParameter(name, parameterType); } ResourceSet container = null; if (((primitive != null) && (primitive.ResourceTypeKind == ResourceTypeKind.EntityType)) && !this.TryFindAnyContainerForType(primitive, out container)) { throw new InvalidOperationException(System.Data.Services.Strings.BaseServiceProvider_ServiceOperationMissingSingleEntitySet(method, primitive.FullName)); } ServiceOperation operation = new ServiceOperation(method.Name, @void, primitive, container, protocolMethod, parameterArray) { CustomState = method }; MimeTypeAttribute mimeTypeAttribute = MimeTypeAttribute.GetMimeTypeAttribute(method); if (mimeTypeAttribute != null) { operation.MimeType = mimeTypeAttribute.MimeType; } this.metadata.ServiceOperations.Add(method.Name, operation); }
/// <summary> /// Returns a new <see cref="ServiceOperation"/> based on the specified <paramref name="method"/> /// instance. /// </summary> /// <param name="method">Method to expose as a service operation.</param> /// <param name="protocolMethod">Protocol (for example HTTP) method the service operation responds to.</param> /// <returns>Service operation corresponding to give <paramref name="method"/>.</returns> private ServiceOperation GetServiceOperationForMethod(MethodInfo method, string protocolMethod) { Debug.Assert(method != null, "method != null"); Debug.Assert(!method.IsAbstract, "!method.IsAbstract - if method is abstract, the type is abstract - already checked"); bool hasSingleResult = BaseServiceProvider.MethodHasSingleResult(method); ServiceOperationResultKind resultKind; ResourceType resourceType = null; if (method.ReturnType == typeof(void)) { resultKind = ServiceOperationResultKind.Void; } else { // Load the metadata of the resource type on the fly. // For Edm provider, it might not mean anything, but for reflection service provider, we need to // load the metadata of the type if its used only in service operation case Type resultType; if (WebUtil.IsPrimitiveType(method.ReturnType)) { resultKind = ServiceOperationResultKind.DirectValue; resultType = method.ReturnType; resourceType = PrimitiveResourceTypeMap.TypeMap.GetPrimitive(resultType); } else { Type queryableElement = BaseServiceProvider.GetIQueryableElement(method.ReturnType); if (queryableElement != null) { resultKind = hasSingleResult ? ServiceOperationResultKind.QueryWithSingleResult : ServiceOperationResultKind.QueryWithMultipleResults; resultType = queryableElement; } else { Type enumerableElement = BaseServiceProvider.GetIEnumerableElement(method.ReturnType); if (enumerableElement != null) { resultKind = ServiceOperationResultKind.Enumeration; resultType = enumerableElement; } else { resultType = method.ReturnType; resultKind = ServiceOperationResultKind.DirectValue; } } Debug.Assert(resultType != null, "resultType != null"); resourceType = PrimitiveResourceTypeMap.TypeMap.GetPrimitive(resultType); if (resourceType == null) { resourceType = this.ResolveResourceType(resultType); } } if (resourceType == null) { throw new InvalidOperationException(Strings.BaseServiceProvider_UnsupportedReturnType(method, method.ReturnType)); } if (resultKind == ServiceOperationResultKind.Enumeration && hasSingleResult) { throw new InvalidOperationException(Strings.BaseServiceProvider_IEnumerableAlwaysMultiple(type, method)); } } ParameterInfo[] parametersInfo = method.GetParameters(); ServiceOperationParameter[] parameters = new ServiceOperationParameter[parametersInfo.Length]; for (int i = 0; i < parameters.Length; i++) { ParameterInfo parameterInfo = parametersInfo[i]; if (parameterInfo.IsOut || parameterInfo.IsRetval) { throw new InvalidOperationException(Strings.BaseServiceProvider_ParameterNotIn(method, parameterInfo)); } ResourceType parameterType = PrimitiveResourceTypeMap.TypeMap.GetPrimitive(parameterInfo.ParameterType); if (parameterType == null) { throw new InvalidOperationException( Strings.BaseServiceProvider_ParameterTypeNotSupported(method, parameterInfo, parameterInfo.ParameterType)); } string parameterName = parameterInfo.Name ?? "p" + i.ToString(CultureInfo.InvariantCulture); parameters[i] = new ServiceOperationParameter(parameterName, parameterType); } ResourceSet resourceSet = null; if (resourceType != null && resourceType.ResourceTypeKind == ResourceTypeKind.EntityType) { resourceSet = this.ResolveResourceSet(resourceType, method); if (resourceSet == null) { throw new InvalidOperationException( Strings.BaseServiceProvider_ServiceOperationMissingSingleEntitySet(method, resourceType.FullName)); } } ServiceOperation operation = new ServiceOperation(method.Name, resultKind, resourceType, resourceSet, protocolMethod, parameters); operation.CustomState = method; MimeTypeAttribute attribute = BaseServiceProvider.GetMimeTypeAttribute(method); if (attribute != null) { operation.MimeType = attribute.MimeType; } return(operation); }