示例#1
0
        /// <summary>
        /// Validates a type name to ensure that it's not an empty string and resolves it against the provided <paramref name="model"/>.
        /// </summary>
        /// <param name="model">The model to use.</param>
        /// <param name="typeName">The type name to validate.</param>
        /// <param name="expectedTypeKind">The expected type kind for the given type name.</param>
        /// <param name="writerValidator">The writer validator to use for validation.</param>
        /// <returns>The type with the given name and kind if a user model was available, otherwise null.</returns>
        internal static IEdmType ResolveAndValidateTypeName(IEdmModel model, string typeName, EdmTypeKind expectedTypeKind, IWriterValidator writerValidator)
        {
            Debug.Assert(model != null, "model != null");

            if (typeName == null)
            {
                // if we have metadata, the type name of an entry must not be null
                if (model.IsUserModel())
                {
                    throw new ODataException(Strings.WriterValidationUtils_MissingTypeNameWithMetadata);
                }

                return null;
            }

            if (typeName.Length == 0)
            {
                throw new ODataException(Strings.ValidationUtils_TypeNameMustNotBeEmpty);
            }

            if (!model.IsUserModel())
            {
                return null;
            }

            // If we do have metadata, lookup the type and translate it to a type.
            IEdmType resolvedType = MetadataUtils.ResolveTypeNameForWrite(model, typeName);
            if (resolvedType == null)
            {
                throw new ODataException(Strings.ValidationUtils_UnrecognizedTypeName(typeName));
            }

            writerValidator.ValidateTypeKind(resolvedType.TypeKind, expectedTypeKind, resolvedType);
            return resolvedType;
        }
示例#2
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="outputContext">The output context to write to.</param>
        protected ODataSerializer(ODataOutputContext outputContext)
        {
            Debug.Assert(outputContext != null, "outputContext != null");

            this.outputContext   = outputContext;
            this.WriterValidator = outputContext.WriterValidator;
        }
 /// <summary>
 /// Constructs a <see cref="JsonLightInstanceAnnotationWriter"/> that can write a collection of <see cref="ODataInstanceAnnotation"/>.
 /// </summary>
 /// <param name="valueSerializer">The <see cref="IODataJsonLightValueSerializer"/> to use for writing values of instance annotations.
 /// The <see cref="IJsonWriter"/> that is also used internally will be acquired from the this instance.</param>
 /// <param name="typeNameOracle">The oracle to use to determine the type name to write for entries and values.</param>
 internal JsonLightInstanceAnnotationWriter(IODataJsonLightValueSerializer valueSerializer, JsonLightTypeNameOracle typeNameOracle)
 {
     Debug.Assert(valueSerializer != null, "valueSerializer should not be null");
     this.valueSerializer = valueSerializer;
     this.typeNameOracle = typeNameOracle;
     this.jsonWriter = this.valueSerializer.JsonWriter;
     this.odataAnnotationWriter = new JsonLightODataAnnotationWriter(this.jsonWriter, valueSerializer.Settings.ODataSimplified);
     this.writerValidator =
         ValidatorFactory.CreateWriterValidator(this.valueSerializer.Settings.EnableFullValidation);
 }
 /// <summary>
 /// Constructs a <see cref="JsonLightInstanceAnnotationWriter"/> that can write a collection of <see cref="ODataInstanceAnnotation"/>.
 /// </summary>
 /// <param name="valueSerializer">The <see cref="ODataJsonLightValueSerializer"/> to use for writing values of instance annotations.
 /// The <see cref="IJsonWriter"/> that is also used internally will be acquired from the this instance.</param>
 /// <param name="typeNameOracle">The oracle to use to determine the type name to write for entries and values.</param>
 internal JsonLightInstanceAnnotationWriter(ODataJsonLightValueSerializer valueSerializer, JsonLightTypeNameOracle typeNameOracle)
 {
     Debug.Assert(valueSerializer != null, "valueSerializer should not be null");
     this.valueSerializer       = valueSerializer;
     this.typeNameOracle        = typeNameOracle;
     this.jsonWriter            = this.valueSerializer.JsonWriter;
     this.odataAnnotationWriter = new JsonLightODataAnnotationWriter(this.jsonWriter,
                                                                     valueSerializer.JsonLightOutputContext.ODataSimplifiedOptions.EnableWritingODataAnnotationWithoutPrefix, this.valueSerializer.MessageWriterSettings.Version);
     this.writerValidator = this.valueSerializer.MessageWriterSettings.Validator;
 }
 /// <summary>
 /// Constructs a <see cref="JsonLightInstanceAnnotationWriter"/> that can write a collection of <see cref="ODataInstanceAnnotation"/>.
 /// </summary>
 /// <param name="valueSerializer">The <see cref="IODataJsonLightValueSerializer"/> to use for writing values of instance annotations.
 /// The <see cref="IJsonWriter"/> that is also used internally will be acquired from the this instance.</param>
 /// <param name="typeNameOracle">The oracle to use to determine the type name to write for entries and values.</param>
 internal JsonLightInstanceAnnotationWriter(IODataJsonLightValueSerializer valueSerializer, JsonLightTypeNameOracle typeNameOracle)
 {
     Debug.Assert(valueSerializer != null, "valueSerializer should not be null");
     this.valueSerializer       = valueSerializer;
     this.typeNameOracle        = typeNameOracle;
     this.jsonWriter            = this.valueSerializer.JsonWriter;
     this.odataAnnotationWriter = new JsonLightODataAnnotationWriter(this.jsonWriter, valueSerializer.Settings.ODataSimplified);
     this.writerValidator       =
         ValidatorFactory.CreateWriterValidator(this.valueSerializer.Settings.EnableFullValidation);
 }
示例#6
0
 public static IWriterValidator CreateWriterValidator(bool enableFullValidation)
 {
     if (enableFullValidation)
     {
         return fullWriterValidator ?? (fullWriterValidator = new WriterValidatorFullValidation());
     }
     else
     {
         return minimalWriterValidator ?? (minimalWriterValidator = new WriterValidatorMinimalValidation());
     }
 }
示例#7
0
 public static IWriterValidator CreateWriterValidator(bool enableFullValidation)
 {
     if (enableFullValidation)
     {
         return(fullWriterValidator ?? (fullWriterValidator = new WriterValidatorFullValidation()));
     }
     else
     {
         return(minimalWriterValidator ?? (minimalWriterValidator = new WriterValidatorMinimalValidation()));
     }
 }
示例#8
0
 /// <summary>
 /// Constructs a <see cref="JsonLightInstanceAnnotationWriter"/> that can write a collection of <see cref="ODataInstanceAnnotation"/>.
 /// </summary>
 /// <param name="valueSerializer">The <see cref="ODataJsonLightValueSerializer"/> to use for writing values of instance annotations.
 /// The <see cref="IJsonWriter"/> that is also used internally will be acquired from the this instance.</param>
 /// <param name="typeNameOracle">The oracle to use to determine the type name to write for entries and values.</param>
 internal JsonLightInstanceAnnotationWriter(ODataJsonLightValueSerializer valueSerializer, JsonLightTypeNameOracle typeNameOracle)
 {
     Debug.Assert(valueSerializer != null, "valueSerializer should not be null");
     this.valueSerializer                   = valueSerializer;
     this.typeNameOracle                    = typeNameOracle;
     this.jsonWriter                        = this.valueSerializer.JsonWriter;
     this.odataAnnotationWriter             = this.valueSerializer.ODataAnnotationWriter;
     this.asynchronousJsonWriter            = this.valueSerializer.AsynchronousJsonWriter;
     this.asynchronousODataAnnotationWriter = this.valueSerializer.AsynchronousODataAnnotationWriter;
     this.writerValidator                   = this.valueSerializer.MessageWriterSettings.Validator;
 }
示例#9
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="format">The format for this output context.</param>
        /// <param name="messageInfo">The context information for the message.</param>
        /// <param name="messageWriterSettings">Configuration settings of the OData writer.</param>
        protected ODataOutputContext(
            ODataFormat format,
            ODataMessageInfo messageInfo,
            ODataMessageWriterSettings messageWriterSettings)
        {
            ExceptionUtils.CheckArgumentNotNull(format, "format");
            ExceptionUtils.CheckArgumentNotNull(messageWriterSettings, "messageWriterSettings");

            this.format = format;
            this.messageWriterSettings = messageWriterSettings;
            this.writingResponse       = messageInfo.IsResponse;
            this.synchronous           = !messageInfo.IsAsync;
            this.model = messageInfo.Model ?? EdmCoreModel.Instance;
            this.payloadUriConverter    = messageInfo.PayloadUriConverter;
            this.container              = messageInfo.Container;
            this.edmTypeResolver        = EdmTypeWriterResolver.Instance;
            this.payloadValueConverter  = ODataPayloadValueConverter.GetPayloadValueConverter(this.container);
            this.writerValidator        = messageWriterSettings.Validator;
            this.odataSimplifiedOptions = ODataSimplifiedOptions.GetODataSimplifiedOptions(this.container, messageWriterSettings.Version);
        }
示例#10
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="format">The format for this output context.</param>
        /// <param name="messageWriterSettings">Configuration settings of the OData writer.</param>
        /// <param name="writingResponse">true if writing a response message; otherwise false.</param>
        /// <param name="synchronous">true if the output should be written synchronously; false if it should be written asynchronously.</param>
        /// <param name="model">The model to use.</param>
        /// <param name="urlResolver">The optional URL resolver to perform custom URL resolution for URLs written to the payload.</param>
        protected ODataOutputContext(
            ODataFormat format,
            ODataMessageWriterSettings messageWriterSettings,
            bool writingResponse,
            bool synchronous,
            IEdmModel model,
            IODataUrlResolver urlResolver)
        {
            ExceptionUtils.CheckArgumentNotNull(format, "format");
            ExceptionUtils.CheckArgumentNotNull(messageWriterSettings, "messageWriterSettings");

            this.format = format;
            this.messageWriterSettings = messageWriterSettings;
            this.writingResponse       = writingResponse;
            this.synchronous           = synchronous;
            this.model                 = model ?? EdmCoreModel.Instance;
            this.urlResolver           = urlResolver;
            this.edmTypeResolver       = EdmTypeWriterResolver.Instance;
            this.payloadValueConverter = this.model.GetPayloadValueConverter();
            this.writerValidator       = ValidatorFactory.CreateWriterValidator(messageWriterSettings.EnableFullValidation);
        }
示例#11
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="format">The format for this output context.</param>
        /// <param name="messageWriterSettings">Configuration settings of the OData writer.</param>
        /// <param name="writingResponse">true if writing a response message; otherwise false.</param>
        /// <param name="synchronous">true if the output should be written synchronously; false if it should be written asynchronously.</param>
        /// <param name="model">The model to use.</param>
        /// <param name="urlResolver">The optional URL resolver to perform custom URL resolution for URLs written to the payload.</param>
        protected ODataOutputContext(
            ODataFormat format,
            ODataMessageWriterSettings messageWriterSettings,
            bool writingResponse,
            bool synchronous,
            IEdmModel model,
            IODataUrlResolver urlResolver)
        {
            ExceptionUtils.CheckArgumentNotNull(format, "format");
            ExceptionUtils.CheckArgumentNotNull(messageWriterSettings, "messageWriterSettings");

            this.format = format;
            this.messageWriterSettings = messageWriterSettings;
            this.writingResponse = writingResponse;
            this.synchronous = synchronous;
            this.model = model ?? EdmCoreModel.Instance;
            this.urlResolver = urlResolver;
            this.edmTypeResolver = EdmTypeWriterResolver.Instance;
            this.payloadValueConverter = this.model.GetPayloadValueConverter();
            this.writerValidator = ValidatorFactory.CreateWriterValidator(messageWriterSettings.EnableFullValidation);
        }
示例#12
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="outputContext">The output context to write to.</param>
        /// <param name="navigationSource">The navigation source we are going to write entities for.</param>
        /// <param name="entityType">The entity type for the entries in the feed to be written (or null if the entity set base type should be used).</param>
        /// <param name="writingFeed">True if the writer is created for writing a feed; false when it is created for writing an entry.</param>
        /// <param name="writingDelta">True if the writer is created for writing a delta response; false otherwise.</param>
        /// <param name="listener">If not null, the writer will notify the implementer of the interface of relevant state changes in the writer.</param>
        protected ODataWriterCore(
            ODataOutputContext outputContext,
            IEdmNavigationSource navigationSource,
            IEdmEntityType entityType,
            bool writingFeed,
            bool writingDelta = false,
            IODataReaderWriterListener listener = null)
        {
            Debug.Assert(outputContext != null, "outputContext != null");
            Debug.Assert(!writingDelta || outputContext.WritingResponse, "writingResponse must be true when writingDelta is true");

            this.outputContext = outputContext;
            this.writingFeed = writingFeed;
            this.writingDelta = writingDelta;
            this.WriterValidator = outputContext.WriterValidator;

            // create a collection validator when writing a top-level feed and a user model is present
            if (this.writingFeed && this.outputContext.Model.IsUserModel())
            {
                this.feedValidator = new FeedWithoutExpectedTypeValidator();
            }

            if (navigationSource != null && entityType == null)
            {
                entityType = this.outputContext.EdmTypeResolver.GetElementType(navigationSource);
            }

            ODataUri odataUri = outputContext.MessageWriterSettings.ODataUri.Clone();

            // Remove key for top level entry
            if (!writingFeed && odataUri != null && odataUri.Path != null)
            {
                odataUri.Path = odataUri.Path.TrimEndingKeySegment();
            }

            this.listener = listener;

            this.scopes.Push(new Scope(WriterState.Start, /*item*/null, navigationSource, entityType, /*skipWriting*/false, outputContext.MessageWriterSettings.SelectedProperties, odataUri));
        }
示例#13
0
        /// <summary>
        /// Resolve a type name against the provided <paramref name="model"/>. If not payload type name is specified,
        /// derive the type from the model type (if available).
        /// </summary>
        /// <param name="model">The model to use.</param>
        /// <param name="typeReferenceFromMetadata">The type inferred from the model or null if the model is not a user model.</param>
        /// <param name="complexValue">The value in question to resolve the type for.</param>
        /// <param name="isOpenPropertyType">True if the type name belongs to an open property.</param>
        /// <param name="writerValidator">The writer validator to use for validation.</param>
        /// <returns>A type for the <paramref name="complexValue"/> or null if no type name is specified and no metadata is available.</returns>
        internal static IEdmTypeReference ResolveAndValidateTypeForComplexValue(IEdmModel model, IEdmTypeReference typeReferenceFromMetadata, ODataComplexValue complexValue, bool isOpenPropertyType, IWriterValidator writerValidator)
        {
            Debug.Assert(model != null, "model != null");

            var typeName = complexValue.TypeName;

            ValidateIfTypeNameMissing(typeName, model, isOpenPropertyType);

            IEdmType typeFromValue = typeName == null ? null : ResolveAndValidateTypeName(model, typeName, EdmTypeKind.Complex, writerValidator);

            if (typeReferenceFromMetadata != null)
            {
                writerValidator.ValidateTypeKind(EdmTypeKind.Complex, typeReferenceFromMetadata.TypeKind(), typeFromValue);
            }

            IEdmTypeReference typeReferenceFromValue = ResolveTypeFromMetadataAndValue(typeReferenceFromMetadata, typeFromValue == null ? null : typeFromValue.ToTypeReference(), writerValidator);

            return(typeReferenceFromValue);
        }
示例#14
0
        /// <summary>
        /// Resolve a resource type name
        /// </summary>
        /// <param name="model">The model to use.</param>
        /// <param name="expectedType">The type inferred from the model or null if the model is not a user model.</param>
        /// <param name="typeName">Name of the type to resolve.</param>
        /// <param name="writerValidator">The writer validator to use for validation.</param>
        /// <returns>A type for primitive value</returns>
        internal static IEdmStructuredType ResolveAndValidateTypeFromTypeName(IEdmModel model, IEdmStructuredType expectedType, string typeName, IWriterValidator writerValidator)
        {
            if (typeName == null && expectedType != null)
            {
                return(expectedType);
            }

            // TODO: Clean up handling of expected types/sets during writing
            IEdmType          typeFromResource       = ResolveAndValidateTypeName(model, typeName, EdmTypeKind.None, /* expectStructuredType */ true, writerValidator);
            IEdmTypeReference typeReferenceFromValue = ResolveTypeFromMetadataAndValue(
                expectedType.ToTypeReference(),
                typeFromResource == null ? null : typeFromResource.ToTypeReference(),
                writerValidator);

            if (typeReferenceFromValue != null && typeReferenceFromValue.IsUntyped())
            {
                return(new EdmUntypedStructuredType());
            }

            return(typeReferenceFromValue == null ? null : typeReferenceFromValue.ToStructuredType());
        }
示例#15
0
        /// <summary>
        /// Validates that the (optional) <paramref name="typeReferenceFromMetadata"/> is the same as the (optional) <paramref name="typeReferenceFromValue"/>.
        /// </summary>
        /// <param name="typeReferenceFromMetadata">The (optional) type from the metadata definition (the expected type).</param>
        /// <param name="typeReferenceFromValue">The (optional) type from the value (the actual type).</param>
        /// <param name="writerValidator">The writer validator to use for validation.</param>
        /// <returns>The type as derived from the <paramref name="typeReferenceFromMetadata"/> and/or <paramref name="typeReferenceFromValue"/>.</returns>
        private static IEdmTypeReference ResolveTypeFromMetadataAndValue(IEdmTypeReference typeReferenceFromMetadata, IEdmTypeReference typeReferenceFromValue, IWriterValidator writerValidator)
        {
            if (typeReferenceFromMetadata == null)
            {
                // if we have no metadata information there is nothing to validate
                return(typeReferenceFromValue);
            }

            if (typeReferenceFromValue == null)
            {
                // derive the property type from the metadata
                return(typeReferenceFromMetadata);
            }

            Debug.Assert(typeReferenceFromValue.TypeKind() == typeReferenceFromMetadata.TypeKind(), "typeReferenceFromValue.TypeKind() == typeReferenceFromMetadata.TypeKind()");

            writerValidator.ValidateTypeReference(typeReferenceFromMetadata, typeReferenceFromValue);

            return(typeReferenceFromValue);
        }
示例#16
0
        /// <summary>
        /// Validates a type name to ensure that it's not an empty string and resolves it against the provided <paramref name="model"/>.
        /// </summary>
        /// <param name="model">The model to use.</param>
        /// <param name="typeName">The type name to validate.</param>
        /// <param name="expectedTypeKind">The expected type kind for the given type name.</param>
        /// <param name="expectStructuredType">This value indicates if a structured type is expected to be return.
        /// True for structured type, false for non-structured type, null for indetermination.</param>
        /// <param name="writerValidator">The writer validator to use for validation.</param>
        /// <returns>The type with the given name and kind if a user model was available, otherwise null.</returns>
        internal static IEdmType ResolveAndValidateTypeName(IEdmModel model, string typeName, EdmTypeKind expectedTypeKind, bool?expectStructuredType, IWriterValidator writerValidator)
        {
            Debug.Assert(model != null, "model != null");
            Debug.Assert(
                !expectStructuredType.HasValue ||
                !expectStructuredType.Value && !expectedTypeKind.IsStructured() ||
                expectStructuredType.Value && (expectedTypeKind.IsStructured() || expectedTypeKind == EdmTypeKind.None),
                "!expectStructuredType.HasValue || !expectStructuredType.Value && !expectedTypeKind.IsStructured() || expectStructuredType.Value && (expectedTypeKind.IsStructured() || expectedTypeKind == EdmTypeKind.None)");

            if (typeName == null)
            {
                // if we have metadata, the type name of a resource must not be null
                if (model.IsUserModel())
                {
                    throw new ODataException(Strings.WriterValidationUtils_MissingTypeNameWithMetadata);
                }

                return(null);
            }

            if (typeName.Length == 0)
            {
                throw new ODataException(Strings.ValidationUtils_TypeNameMustNotBeEmpty);
            }

            if (!model.IsUserModel())
            {
                return(null);
            }

            // If we do have metadata, lookup the type and translate it to a type.
            IEdmType resolvedType = MetadataUtils.ResolveTypeNameForWrite(model, typeName);

            if (resolvedType == null)
            {
                throw new ODataException(Strings.ValidationUtils_UnrecognizedTypeName(typeName));
            }

            if (resolvedType.TypeKind != EdmTypeKind.Untyped)
            {
                writerValidator.ValidateTypeKind(resolvedType.TypeKind, expectedTypeKind, expectStructuredType, resolvedType);
            }

            return(resolvedType);
        }
示例#17
0
        /// <summary>
        /// Resolve a type name against the provided <paramref name="model"/>. If not payload type name is specified,
        /// derive the type from the model type (if available).
        /// </summary>
        /// <param name="model">The model to use.</param>
        /// <param name="typeReferenceFromMetadata">The type inferred from the model or null if the model is not a user model.</param>
        /// <param name="collectionValue">The value in question to resolve the type for.</param>
        /// <param name="isOpenPropertyType">True if the type name belongs to an open property.</param>
        /// <param name="writerValidator">The writer validator to use for validation.</param>
        /// <returns>A type for the <paramref name="collectionValue"/> or null if no type name is specified and no metadata is available.</returns>
        internal static IEdmTypeReference ResolveAndValidateTypeForCollectionValue(IEdmModel model, IEdmTypeReference typeReferenceFromMetadata, ODataCollectionValue collectionValue, bool isOpenPropertyType, IWriterValidator writerValidator)
        {
            Debug.Assert(model != null, "model != null");

            var typeName = collectionValue.TypeName;

            ValidateIfTypeNameMissing(typeName, model, isOpenPropertyType);

            IEdmType typeFromValue = typeName == null ? null : ResolveAndValidateTypeName(model, typeName, EdmTypeKind.Collection, false, writerValidator);

            if (typeReferenceFromMetadata != null)
            {
                writerValidator.ValidateTypeKind(EdmTypeKind.Collection, typeReferenceFromMetadata.TypeKind(), false, typeFromValue);
            }

            IEdmTypeReference typeReferenceFromValue = ResolveTypeFromMetadataAndValue(typeReferenceFromMetadata, typeFromValue == null ? null : typeFromValue.ToTypeReference(), writerValidator);

            if (typeReferenceFromValue != null)
            {
                // update nullability from metadata
                if (typeReferenceFromMetadata != null)
                {
                    typeReferenceFromValue = typeReferenceFromMetadata;
                }

                // validate that the collection type represents a valid Collection type (e.g., is unordered).
                typeReferenceFromValue = ValidationUtils.ValidateCollectionType(typeReferenceFromValue);
            }

            return(typeReferenceFromValue);
        }
示例#18
0
        /// <summary>
        /// Resolve a type name against the provided <paramref name="model"/>. If not payload type name is specified,
        /// derive the type from the model type (if available).
        /// </summary>
        /// <param name="model">The model to use.</param>
        /// <param name="typeReferenceFromMetadata">The type inferred from the model or null if the model is not a user model.</param>
        /// <param name="resourceValue">The value in question to resolve the type for.</param>
        /// <param name="isOpenPropertyType">True if the type name belongs to an open (dynamic) property.</param>
        /// <param name="writerValidator">The writer validator to use for validation.</param>
        /// <returns>A type for the <paramref name="resourceValue"/> or null if no type name is specified and no metadata is available.</returns>
        internal static IEdmTypeReference ResolveAndValidateTypeForResourceValue(IEdmModel model, IEdmTypeReference typeReferenceFromMetadata,
                                                                                 ODataResourceValue resourceValue, bool isOpenPropertyType, IWriterValidator writerValidator)
        {
            Debug.Assert(model != null, "model != null");
            Debug.Assert(resourceValue != null, "resourceValue != null");

            var typeName = resourceValue.TypeName;

            ValidateIfTypeNameMissing(typeName, model, isOpenPropertyType);

            // It's ok to use "EdmTypeKind.Complex" because the validation will check "IsStructured()".
            IEdmType typeFromValue = typeName == null ? null : ResolveAndValidateTypeName(model, typeName, EdmTypeKind.Complex, true, writerValidator);

            if (typeReferenceFromMetadata != null)
            {
                // It's ok to use "EdmTypeKind.Complex" because the parameter "expectStructuredType" is set to "true".
                writerValidator.ValidateTypeKind(EdmTypeKind.Complex, typeReferenceFromMetadata.TypeKind(), true, typeFromValue);
            }

            return(ResolveTypeFromMetadataAndValue(typeReferenceFromMetadata,
                                                   typeFromValue == null ? null : typeFromValue.ToTypeReference(), writerValidator));
        }
示例#19
0
        /// <summary>
        /// Validates a type name to ensure that it's not an empty string and resolves it against the provided <paramref name="model"/>.
        /// </summary>
        /// <param name="model">The model to use.</param>
        /// <param name="typeName">The type name to validate.</param>
        /// <param name="expectedTypeKind">The expected type kind for the given type name.</param>
        /// <param name="writerValidator">The writer validator to use for validation.</param>
        /// <returns>The type with the given name and kind if a user model was available, otherwise null.</returns>
        internal static IEdmType ResolveAndValidateTypeName(IEdmModel model, string typeName, EdmTypeKind expectedTypeKind, IWriterValidator writerValidator)
        {
            Debug.Assert(model != null, "model != null");

            if (typeName == null)
            {
                // if we have metadata, the type name of an entry must not be null
                if (model.IsUserModel())
                {
                    throw new ODataException(Strings.WriterValidationUtils_MissingTypeNameWithMetadata);
                }

                return(null);
            }

            if (typeName.Length == 0)
            {
                throw new ODataException(Strings.ValidationUtils_TypeNameMustNotBeEmpty);
            }

            if (!model.IsUserModel())
            {
                return(null);
            }

            // If we do have metadata, lookup the type and translate it to a type.
            IEdmType resolvedType = MetadataUtils.ResolveTypeNameForWrite(model, typeName);

            if (resolvedType == null)
            {
                throw new ODataException(Strings.ValidationUtils_UnrecognizedTypeName(typeName));
            }

            writerValidator.ValidateTypeKind(resolvedType.TypeKind, expectedTypeKind, resolvedType);
            return(resolvedType);
        }
示例#20
0
        /// <summary>
        /// Resolve a type name against the provided <paramref name="model"/>. If not payload type name is specified,
        /// derive the type from the model type (if available).
        /// </summary>
        /// <param name="model">The model to use.</param>
        /// <param name="typeReferenceFromMetadata">The type inferred from the model or null if the model is not a user model.</param>
        /// <param name="complexValue">The value in question to resolve the type for.</param>
        /// <param name="isOpenPropertyType">True if the type name belongs to an open property.</param>
        /// <param name="writerValidator">The writer validator to use for validation.</param>
        /// <returns>A type for the <paramref name="complexValue"/> or null if no type name is specified and no metadata is available.</returns>
        internal static IEdmTypeReference ResolveAndValidateTypeForComplexValue(IEdmModel model, IEdmTypeReference typeReferenceFromMetadata, ODataComplexValue complexValue, bool isOpenPropertyType, IWriterValidator writerValidator)
        {
            Debug.Assert(model != null, "model != null");

            var typeName = complexValue.TypeName;

            ValidateIfTypeNameMissing(typeName, model, isOpenPropertyType);

            IEdmType typeFromValue = typeName == null ? null : ResolveAndValidateTypeName(model, typeName, EdmTypeKind.Complex, writerValidator);
            if (typeReferenceFromMetadata != null)
            {
                writerValidator.ValidateTypeKind(EdmTypeKind.Complex, typeReferenceFromMetadata.TypeKind(), typeFromValue);
            }

            IEdmTypeReference typeReferenceFromValue = ResolveTypeFromMetadataAndValue(typeReferenceFromMetadata, typeFromValue == null ? null : typeFromValue.ToTypeReference(), writerValidator);
            return typeReferenceFromValue;
        }
示例#21
0
        /// <summary>
        /// Validates that the (optional) <paramref name="typeReferenceFromMetadata"/> is the same as the (optional) <paramref name="typeReferenceFromValue"/>.
        /// </summary>
        /// <param name="typeReferenceFromMetadata">The (optional) type from the metadata definition (the expected type).</param>
        /// <param name="typeReferenceFromValue">The (optional) type from the value (the actual type).</param>
        /// <param name="writerValidator">The writer validator to use for validation.</param>
        /// <returns>The type as derived from the <paramref name="typeReferenceFromMetadata"/> and/or <paramref name="typeReferenceFromValue"/>.</returns>
        private static IEdmTypeReference ResolveTypeFromMetadataAndValue(IEdmTypeReference typeReferenceFromMetadata, IEdmTypeReference typeReferenceFromValue, IWriterValidator writerValidator)
        {
            if (typeReferenceFromMetadata == null)
            {
                // if we have no metadata information there is nothing to validate
                return typeReferenceFromValue;
            }

            if (typeReferenceFromValue == null)
            {
                // derive the property type from the metadata
                return typeReferenceFromMetadata;
            }

            Debug.Assert(typeReferenceFromValue.TypeKind() == typeReferenceFromMetadata.TypeKind(), "typeReferenceFromValue.TypeKind() == typeReferenceFromMetadata.TypeKind()");

            writerValidator.ValidateTypeReference(typeReferenceFromMetadata, typeReferenceFromValue);

            return typeReferenceFromValue;
        }
示例#22
0
        /// <summary>
        /// Resolve a type name against the provided <paramref name="model"/>. If not payload type name is specified,
        /// derive the type from the model type (if available).
        /// </summary>
        /// <param name="model">The model to use.</param>
        /// <param name="typeReferenceFromMetadata">The type inferred from the model or null if the model is not a user model.</param>
        /// <param name="collectionValue">The value in question to resolve the type for.</param>
        /// <param name="isOpenPropertyType">True if the type name belongs to an open property.</param>
        /// <param name="writerValidator">The writer validator to use for validation.</param>
        /// <returns>A type for the <paramref name="collectionValue"/> or null if no type name is specified and no metadata is available.</returns>
        internal static IEdmTypeReference ResolveAndValidateTypeForCollectionValue(IEdmModel model, IEdmTypeReference typeReferenceFromMetadata, ODataCollectionValue collectionValue, bool isOpenPropertyType, IWriterValidator writerValidator)
        {
            Debug.Assert(model != null, "model != null");

            var typeName = collectionValue.TypeName;

            ValidateIfTypeNameMissing(typeName, model, isOpenPropertyType);

            IEdmType typeFromValue = typeName == null ? null : ResolveAndValidateTypeName(model, typeName, EdmTypeKind.Collection, writerValidator);
            if (typeReferenceFromMetadata != null)
            {
                writerValidator.ValidateTypeKind(EdmTypeKind.Collection, typeReferenceFromMetadata.TypeKind(), typeFromValue);
            }

            IEdmTypeReference typeReferenceFromValue = ResolveTypeFromMetadataAndValue(typeReferenceFromMetadata, typeFromValue == null ? null : typeFromValue.ToTypeReference(), writerValidator);
            if (typeReferenceFromValue != null)
            {
                // update nullability from metadata
                if (typeReferenceFromMetadata != null)
                {
                    typeReferenceFromValue = typeReferenceFromMetadata;
                }

                // validate that the collection type represents a valid Collection type (e.g., is unordered).
                typeReferenceFromValue = writerValidator.ValidateCollectionType(typeReferenceFromValue);
            }

            return typeReferenceFromValue;
        }