/// <summary> /// Constructs a ResourceAssociationEnd instance. /// </summary> /// <param name="resourceSet">Resource set of the association end.</param> /// <param name="resourceType">Resource type of the association end.</param> /// <param name="resourceProperty">Resource property of the association end.</param> public ResourceAssociationSetEnd(ResourceSet resourceSet, ResourceType resourceType, ResourceProperty resourceProperty) { WebUtil.CheckArgumentNull(resourceSet, "resourceSet"); WebUtil.CheckArgumentNull(resourceType, "resourceType"); if (resourceProperty != null && (resourceType.TryResolvePropertyName(resourceProperty.Name) == null || resourceProperty.TypeKind != ResourceTypeKind.EntityType)) { throw new ArgumentException(Strings.ResourceAssociationSetEnd_ResourcePropertyMustBeNavigationPropertyOnResourceType); } if (!resourceSet.ResourceType.IsAssignableFrom(resourceType) && !resourceType.IsAssignableFrom(resourceSet.ResourceType)) { throw new ArgumentException(Strings.ResourceAssociationSetEnd_ResourceTypeMustBeAssignableToResourceSet); } this.resourceSet = resourceSet; this.resourceType = resourceType; // Note that for the TargetEnd, resourceProperty can be null. this.resourceProperty = resourceProperty; }
private OperationWrapper ValidateCanAdvertiseServiceAction(ResourceType resourceType, ServiceAction serviceAction, HashSet <string> existingActionNames) { if (serviceAction == null) { return(null); } if (!existingActionNames.Add(serviceAction.Name)) { throw new DataServiceException(500, System.Data.Services.Strings.DataServiceActionProviderWrapper_DuplicateAction(serviceAction.Name)); } ServiceActionParameter bindingParameter = serviceAction.BindingParameter; if (bindingParameter == null) { throw new DataServiceException(500, System.Data.Services.Strings.DataServiceActionProviderWrapper_ServiceActionBindingParameterNull(serviceAction.Name)); } ResourceType parameterType = bindingParameter.ParameterType; if (!parameterType.IsAssignableFrom(resourceType)) { throw new DataServiceException(500, System.Data.Services.Strings.DataServiceActionProviderWrapper_ResourceTypeMustBeAssignableToBindingParameterResourceType(serviceAction.Name, parameterType.FullName, resourceType.FullName)); } return(this.dataService.Provider.ValidateOperation(serviceAction)); }
/// <summary> /// Gets the type and uri specified in the metadata object in the given json object. /// </summary> /// <param name="jsonObjectTable">jsonObject which contains the metadata information</param> /// <param name="expectedType">expected type that this segment of the uri is targeted to</param> /// <param name="topLevel">whether the segment represents the top level object.</param> /// <param name="uri">uri as specified in the metadata object. If its not specified, this is set to null</param> /// <param name="metadataElementSpecified">returns true if the metadata element was specified</param> /// <returns>typename and uri as specified in the metadata object</returns> private ResourceType GetTypeAndUriFromMetadata( Dictionary<String, Object> jsonObjectTable, ResourceType expectedType, bool topLevel, out string uri, out bool metadataElementSpecified) { metadataElementSpecified = false; // Get the metadata object object metadataObject; ResourceType targetType = expectedType; bool typeNameSpecified = false; uri = null; if (jsonObjectTable.TryGetValue(XmlConstants.JsonMetadataString, out metadataObject)) { metadataElementSpecified = true; JsonReader.JsonObjectRecords metadata = metadataObject as JsonReader.JsonObjectRecords; if (metadata == null) { throw DataServiceException.CreateBadRequestError(Strings.BadRequestStream_InvalidMetadataContent); } // Get the type information from the metadata object. if the type name is not specified, // then return the expectedType as the target type object objectTypeName; if (metadata.Entries.TryGetValue(XmlConstants.JsonTypeString, out objectTypeName)) { string typeName = objectTypeName as string; if (string.IsNullOrEmpty(typeName)) { throw DataServiceException.CreateBadRequestError(Strings.BadRequestStream_InvalidTypeMetadata); } // Resolve resource type name targetType = this.Service.Provider.TryResolveResourceType(typeName); if (targetType == null || targetType.ResourceTypeKind == ResourceTypeKind.Primitive) { throw DataServiceException.CreateBadRequestError(Strings.BadRequest_InvalidTypeName(typeName)); } if (expectedType != null && !expectedType.IsAssignableFrom(targetType)) { throw DataServiceException.CreateBadRequestError(Strings.BadRequest_InvalidTypeSpecified(typeName, expectedType.FullName)); } typeNameSpecified = true; } uri = JsonDeserializer.ReadUri(metadata.Entries); } // Type information is optional for bind operations. // Top level operations cannot be bind operations, since uri need to have $links // for top level bind operations and that's a different code path. // For bind operations, uri must be specified and nothing else should be specified. bool bindOperation = !topLevel && uri != null && jsonObjectTable.Count == 1; // type name must be specified for POST or PUT/MERGE operations. if (!typeNameSpecified) { if (!bindOperation) { if (expectedType == null) { // For open properties, you must specify the type information throw DataServiceException.CreateBadRequestError(Strings.BadRequestStream_MissingTypeInformationForOpenTypeProperties); } else if (this.Service.Provider.HasDerivedTypes(expectedType)) { // For types that take part in inheritance, type information must be specified. throw DataServiceException.CreateBadRequestError(Strings.BadRequest_TypeInformationMustBeSpecifiedForInhertiance); } } else { // If the type name is not specified, we should set the type name to null, since in case of inheritance, // we don't want to guess the type information. targetType = null; } } return targetType; }