/// <summary> /// Validates property uniqueness. /// </summary> /// <param name="property">The property.</param> public void ValidatePropertyUniqueness(ODataNestedResourceInfo property) { State state; if (!propertyState.TryGetValue(property.Name, out state)) { propertyState[property.Name] = State.NestedResource; } else { if (state != State.AssociationLink) { throw new ODataException( Strings.DuplicatePropertyNamesNotAllowed( property.Name)); } else { propertyState[property.Name] = State.AssociationLink | State.NestedResource; } } }
internal static IEdmNavigationProperty ValidateNestedResourceInfo( ODataNestedResourceInfo nestedResourceInfo, IEdmStructuredType declaringStructuredType, ODataPayloadKind?expandedPayloadKind, bool throwOnUndeclaredProperty) { Debug.Assert(nestedResourceInfo != null, "nestedResourceInfo != null"); Debug.Assert( !expandedPayloadKind.HasValue || expandedPayloadKind.Value == ODataPayloadKind.EntityReferenceLink || expandedPayloadKind.Value == ODataPayloadKind.Resource || expandedPayloadKind.Value == ODataPayloadKind.ResourceSet, "If an expanded payload kind is specified it must be resource, resource set or entity reference link."); // Navigation link must have a non-empty name if (string.IsNullOrEmpty(nestedResourceInfo.Name)) { throw new ODataException(Strings.ValidationUtils_LinkMustSpecifyName); } // If we write an entity reference link, don't validate the multiplicity of the IsCollection // property if it is 'false' (since we allow writing a singleton navigation link for // a collection navigation property in requests) nor the consistency of payload kind and metadata // (which is done separately in ODataWriterCore.CheckForNestedResourceInfoWithContent). bool isEntityReferenceLinkPayload = expandedPayloadKind == ODataPayloadKind.EntityReferenceLink; // true only if the expandedPayloadKind has a value and the value is 'Resource Set' bool isResourceSetPayload = expandedPayloadKind == ODataPayloadKind.ResourceSet; // Make sure the IsCollection property agrees with the payload kind for resource and resource set payloads Func <object, string> errorTemplate = null; if (!isEntityReferenceLinkPayload && nestedResourceInfo.IsCollection.HasValue && expandedPayloadKind.HasValue) { // For resource set/resource make sure the IsCollection property is set correctly. if (isResourceSetPayload != nestedResourceInfo.IsCollection.Value) { errorTemplate = expandedPayloadKind.Value == ODataPayloadKind.ResourceSet ? (Func <object, string>)Strings.WriterValidationUtils_ExpandedLinkIsCollectionFalseWithResourceSetContent : Strings.WriterValidationUtils_ExpandedLinkIsCollectionTrueWithResourceContent; } } IEdmNavigationProperty navigationProperty = null; if (errorTemplate == null && declaringStructuredType != null) { navigationProperty = ValidateNavigationPropertyDefined(nestedResourceInfo.Name, declaringStructuredType, throwOnUndeclaredProperty); if (navigationProperty != null) { bool isCollectionType = navigationProperty.Type.TypeKind() == EdmTypeKind.Collection; // Make sure the IsCollection property agrees with the metadata type for resource and resource set payloads if (nestedResourceInfo.IsCollection.HasValue && isCollectionType != nestedResourceInfo.IsCollection) { // Ignore the case where IsCollection is 'false' and we are writing an entity reference link // (see comment above) if (!(nestedResourceInfo.IsCollection == false && isEntityReferenceLinkPayload)) { errorTemplate = isCollectionType ? (Func <object, string>)Strings.WriterValidationUtils_ExpandedLinkIsCollectionFalseWithResourceSetMetadata : Strings.WriterValidationUtils_ExpandedLinkIsCollectionTrueWithResourceMetadata; } } // Make sure that the payload kind agrees with the metadata. // For entity reference links we check separately in ODataWriterCore.CheckForNestedResourceInfoWithContent. if (!isEntityReferenceLinkPayload && expandedPayloadKind.HasValue && isCollectionType != isResourceSetPayload) { errorTemplate = isCollectionType ? (Func <object, string>)Strings.WriterValidationUtils_ExpandedLinkWithResourcePayloadAndResourceSetMetadata : Strings.WriterValidationUtils_ExpandedLinkWithResourceSetPayloadAndResourceMetadata; } } } if (errorTemplate != null) { string uri = nestedResourceInfo.Url == null ? "null" : UriUtils.UriToString(nestedResourceInfo.Url); throw new ODataException(errorTemplate(uri)); } return(navigationProperty); }
/// <summary> /// Validates that the specified nested resource info has cardinality set, i.e., it has the /// IsCollection value set. /// </summary> /// <param name="nestedResourceInfo">The nested resource info to validate.</param> public virtual void ValidateNestedResourceInfoHasCardinality( ODataNestedResourceInfo nestedResourceInfo) { WriterValidationUtils.ValidateNestedResourceInfoHasCardinality(nestedResourceInfo); }
/// <summary> /// Asynchronously start writing a nested resource info. /// </summary> /// <param name="nestedResourceInfo">The nested resource info to write.</param> /// <returns>A task instance that represents the asynchronous write operation.</returns> public abstract Task WriteStartAsync(ODataNestedResourceInfo nestedResourceInfo);
/// <summary> /// Start writing a nested resource info. /// </summary> /// <param name="nestedResourceInfo">The nested resource info to write.</param> public abstract void WriteStart(ODataNestedResourceInfo nestedResourceInfo);
/// <summary>Writes a nested resource info.</summary> /// <param name="nestedResourceInfo">The nested resource info to write.</param> /// <returns>This ODataWriter, allowing for chaining operations.</returns> public ODataWriter Write(ODataNestedResourceInfo nestedResourceInfo) { WriteStart(nestedResourceInfo); WriteEnd(); return(this); }
/// <summary> Asynchronously start writing a nested resource info. </summary> /// <returns>A task instance that represents the asynchronous write operation.</returns> /// <param name="nestedResourceInfo">The nested resource info to writer.</param> public virtual Task WriteStartAsync(ODataNestedResourceInfo nestedResourceInfo) { return(TaskUtils.GetTaskForSynchronousOperation(() => this.WriteStart(nestedResourceInfo))); }
public void ValidatePropertyUniqueness(ODataNestedResourceInfo property) { // nop }
/// <summary> /// Provide additional serialization information to the <see cref="ODataWriter"/> for <paramref name="nestedResourceInfo"/>. /// </summary> /// <param name="nestedResourceInfo">The instance to set the serialization info.</param> /// <param name="serializationInfo">The serialization info to set.</param> public static void SetSerializationInfo(this ODataNestedResourceInfo nestedResourceInfo, ODataNestedResourceInfoSerializationInfo serializationInfo) { ExceptionUtils.CheckArgumentNotNull(nestedResourceInfo, "resource"); nestedResourceInfo.SerializationInfo = serializationInfo; }
public void MaterializeEntityShouldWork() { var odataEntry = new OData.ODataResource() { Id = new Uri("http://www.odata.org/service.svc/entitySet(1)") }; odataEntry.Properties = new OData.ODataProperty[] { new OData.ODataProperty { Name = "keyProp", Value = 1 }, new OData.ODataProperty { Name = "colorProp", Value = new OData.ODataEnumValue("blue") }, new OData.ODataProperty { Name = "primitiveCollection", Value = new OData.ODataCollectionValue { TypeName = "Edm.Int32", Items = new List <object> { 1, 2, 3 } } }, new OData.ODataProperty { Name = "enumCollection", Value = new OData.ODataCollectionValue { TypeName = "color", Items = new List <OData.ODataEnumValue> { new OData.ODataEnumValue("white"), new OData.ODataEnumValue("blue") } } } }; var complexP = new OData.ODataNestedResourceInfo() { Name = "complexProp", IsCollection = false }; var complexResource = new OData.ODataResource { Properties = new OData.ODataProperty[] { new OData.ODataProperty { Name = "age", Value = 11 }, new OData.ODataProperty { Name = "name", Value = "June" } } }; var complexColP = new OData.ODataNestedResourceInfo { Name = "complexCollection", IsCollection = true }; var complexColResourceSet = new OData.ODataResourceSet(); var items = new List <OData.ODataResource> { new OData.ODataResource { Properties = new OData.ODataProperty[] { new OData.ODataProperty { Name = "name", Value = "Aug" }, new OData.ODataProperty { Name = "age", Value = 8 }, new OData.ODataProperty { Name = "color", Value = new OData.ODataEnumValue("white") } } }, new OData.ODataResource { Properties = new OData.ODataProperty[] { new OData.ODataProperty { Name = "name", Value = "Sep" }, new OData.ODataProperty { Name = "age", Value = 9 }, new OData.ODataProperty { Name = "color", Value = new OData.ODataEnumValue("blue") } } } }; var clientEdmModel = new ClientEdmModel(ODataProtocolVersion.V4); var context = new DataServiceContext(); var materializerEntry = MaterializerEntry.CreateEntry(odataEntry, OData.ODataFormat.Json, true, clientEdmModel); MaterializerNavigationLink.CreateLink(complexP, MaterializerEntry.CreateEntry(complexResource, OData.ODataFormat.Json, true, clientEdmModel)); MaterializerFeed.CreateFeed(complexColResourceSet, items); MaterializerNavigationLink.CreateLink(complexColP, complexColResourceSet); var materializerContext = new TestMaterializerContext() { Model = clientEdmModel, Context = context }; var adapter = new EntityTrackingAdapter(new TestEntityTracker(), MergeOption.OverwriteChanges, clientEdmModel, context); QueryComponents components = new QueryComponents(new Uri("http://foo.com/Service"), new Version(4, 0), typeof(EntityType), null, new Dictionary <Expression, Expression>()); var entriesMaterializer = new ODataEntriesEntityMaterializer(new OData.ODataResource[] { odataEntry }, materializerContext, adapter, components, typeof(EntityType), null, OData.ODataFormat.Json); var customersRead = new List <EntityType>(); while (entriesMaterializer.Read()) { customersRead.Add(entriesMaterializer.CurrentValue as EntityType); } customersRead.Should().HaveCount(1); customersRead[0].KeyProp.Should().Be(1); customersRead[0].ComplexProp.Should().Equals(new ComplexType { Age = 11, Name = "June" }); customersRead[0].ColorProp.Should().Equals(Color.Blue); customersRead[0].PrimitiveCollection.Should().Equals(new List <int> { 1, 2, 3 }); ComplexType complex1 = new ComplexType { Name = "Aug", Age = 8, Color = Color.White }; ComplexType complex2 = new ComplexType { Name = "Sep", Age = 9, Color = Color.Blue }; customersRead[0].ComplexCollection.Should().Equals(new List <ComplexType> { complex1, complex2 }); customersRead[0].EnumCollection.Should().Equals(new List <Color> { Color.White, Color.Blue }); }