/// <summary> /// Because the test deserializer used to parse the actual payload will not have metadata, we fix it up here. /// Note: this should probably move to happen just before comparison, rather than when generating expectations. /// </summary> /// <param name="payloadElement">The payload element</param> private void SortAndNormalizeProperties(ComplexInstance payloadElement) { var sortedProperties = payloadElement.Properties.OrderBy(p => p.Name).ToList(); foreach (var p in sortedProperties) { var property = p; payloadElement.Remove(property); // If we have a primitive property with null value, we write a type name for the null value // in V1 and V2. If not type name is available or we are in V3, we don't do that and thus expect a null property instance. var primitiveProperty = property as PrimitiveProperty; if (primitiveProperty != null && primitiveProperty.Value.IsNull && (this.dsv >= DataServiceProtocolVersion.V4 || string.IsNullOrEmpty(primitiveProperty.Value.FullTypeName))) { property = new NullPropertyInstance(property.Name, null).WithAnnotations(property.Annotations); } var complexProperty = property as ComplexProperty; if (complexProperty != null && complexProperty.Value.IsNull) { property = new NullPropertyInstance(property.Name, complexProperty.Value.FullTypeName).WithAnnotations(property.Annotations); } var complexCollectionProperty = property as ComplexMultiValueProperty; if (complexCollectionProperty != null && complexCollectionProperty.Value.Count == 0 && complexCollectionProperty.Value.FullTypeName == null) { property = new PrimitiveProperty(complexCollectionProperty.Name, complexCollectionProperty.Value.FullTypeName, string.Empty); } payloadElement.Add(property); } }
/// <summary> /// Visits a payload element whose root is a PrimitiveProperty. /// </summary> /// <param name="payloadElement">The root node of the payload element being visited.</param> public override void Visit(PrimitiveProperty payloadElement) { base.Visit(payloadElement); if (this.CurrentElementIsRoot()) { Func <MemberProperty, bool> matchesProperty = (p) => p.Name == payloadElement.Name && p.PropertyType is PrimitiveDataType && ((PrimitiveDataType)p.PropertyType).FullEdmName() == payloadElement.Value.FullTypeName; Func <IEdmProperty, bool> EdmMatchesProperty = (p) => p.Name == payloadElement.Name && p.DeclaringType as IEdmPrimitiveType != null && ((IEdmPrimitiveType)p).FullName() == payloadElement.Value.FullTypeName; var valueTypeAnnotation = payloadElement.Value.Annotations.OfType <EntityModelTypeAnnotation>().SingleOrDefault(); if (valueTypeAnnotation != null) { if (valueTypeAnnotation.EdmModelType != null) { var edmEntityType = valueTypeAnnotation.EdmModelType; this.AddExpectedTypeToProperty(payloadElement, edmEntityType, EdmMatchesProperty); } } else { var edmEntityType = this.ResolvePropertyEdmDataType(payloadElement.Value.FullTypeName); this.AddExpectedTypeToProperty(payloadElement, edmEntityType, EdmMatchesProperty); } } this.AnnotateIfOpenProperty(payloadElement, payloadElement.Value); }
/// <summary> /// Creates a primitive ODataProperty and sets the value. /// </summary> /// <param name="payloadElement">The primitive property to process.</param> public override void Visit(PrimitiveProperty payloadElement) { var odataProperty = new ODataProperty() { Name = payloadElement.Name, Value = payloadElement.Value.ClrValue, }; var parent = this.items.Peek(); // not calling the base since we don't want to visit the value //If there is no parent then this is top level and add to items //otherwise add to parent. if (parent == null) { this.items.Push(odataProperty); } else { var entry = parent as ODataResource; if (entry != null) { var properties = (List <ODataProperty>)entry.Properties; properties.Add(odataProperty); } var complexValue = parent as ODataComplexValue; if (complexValue != null) { var properties = (List <ODataProperty>)complexValue.Properties; properties.Add(odataProperty); } } }
/// <summary> /// Visits the payload element /// </summary> /// <param name="payloadElement">The payload element to visit</param> public override void Visit(PrimitiveProperty payloadElement) { ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement"); var annotation = payloadElement.Annotations.Where(a => a is MemberPropertyAnnotation).SingleOrDefault(); payloadElement.Annotations.Remove(annotation); this.VisitProperty(payloadElement, payloadElement.Value); }
/// <summary> /// Visits the payload element /// </summary> /// <param name="payloadElement">The payload element to visit</param> public override void Visit(PrimitiveProperty payloadElement) { ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement"); ExceptionUtilities.CheckObjectNotNull(this.currentXElement, "Current XElement is not defined"); // when name is null, it means that it is in the top level. We should use <m:value XElement propertyElement = payloadElement.Name == null?CreateMetadataElement(this.currentXElement, AtomValueElement) : CreateDataServicesElement(this.currentXElement, payloadElement.Name); this.VisitPayloadElement(payloadElement.Value, propertyElement); PostProcessXElement(payloadElement, propertyElement); }
/// <summary> /// Visits a payload element whose root is a PrimitiveProperty. /// </summary> /// <param name="expected">The root node of payload element being visited.</param> public void Visit(PrimitiveProperty expected) { ExceptionUtilities.CheckArgumentNotNull(expected, "expected"); var observed = this.GetNextObservedElement <PrimitiveProperty>(); using (this.Assert.WithMessage("Primitive property '{0}' did not match expectation", expected.Name)) { this.Assert.AreEqual(expected.Name, observed.Name, "Name did not match expectation"); this.CompareAnnotations(expected.Annotations, observed.Annotations); this.WrapAccept(expected.Value, observed.Value); } }
/// <summary> /// Creates a primitive ODataProperty and sets the value. /// </summary> /// <param name="payloadElement">The primitive property to process.</param> public override void Visit(PrimitiveProperty payloadElement) { var odataProperty = new ODataProperty() { Name = payloadElement.Name, Value = payloadElement.Value.ClrValue, }; // not calling the base since we don't want to visit the value this.currentProperties.Add(odataProperty); }
/// <summary> /// Visits the children of the given payload element and replaces it with a copy if any child changes /// </summary> /// <param name="payloadElement">The payload element to potentially replace</param> /// <returns>The original element or a copy to replace it with</returns> public virtual ODataPayloadElement Visit(PrimitiveProperty payloadElement) { ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement"); var replacedValue = this.Recurse(payloadElement.Value) as PrimitiveValue; ExceptionUtilities.CheckObjectNotNull(replacedValue, "Replaced value was null or wrong type"); if (!this.ShouldReplace(payloadElement.Value, replacedValue)) { return(payloadElement); } return(payloadElement.ReplaceWith(new PrimitiveProperty(payloadElement.Name, replacedValue))); }
/// <summary> /// Build QueryValue from action response payload /// </summary> /// <param name="payload">response payload element</param> /// <param name="queryType">query type to build</param> /// <returns>query value that represents the payload</returns> private QueryValue BuildQueryValueForActionResponse(ODataPayloadElement payload, QueryType queryType) { EntitySetInstance entitySetInstance = payload as EntitySetInstance; PrimitiveProperty primitiveProperty = payload as PrimitiveProperty; ComplexProperty complexProperty = payload as ComplexProperty; PrimitiveMultiValueProperty primitiveMultiValueProperty = payload as PrimitiveMultiValueProperty; ComplexMultiValueProperty complexMultiValueProperty = payload as ComplexMultiValueProperty; PrimitiveCollection primitiveCollection = payload as PrimitiveCollection; ComplexInstanceCollection complexInstanceCollection = payload as ComplexInstanceCollection; if (entitySetInstance != null) { var xmlBaseAnnotations = payload.Annotations.OfType <XmlBaseAnnotation>(); var collectionType = this.currentExpression.ExpressionType as QueryCollectionType; ExceptionUtilities.CheckObjectNotNull(collectionType, "Cannot cast expression type to QueryCollectionType."); var elementType = collectionType.ElementType as QueryEntityType; return(this.BuildFromEntitySetInstance(entitySetInstance, elementType, xmlBaseAnnotations)); } else if (primitiveProperty != null) { return(this.PayloadElementToQueryValueConverter.Convert(primitiveProperty.Value, queryType)); } else if (complexProperty != null) { return(this.PayloadElementToQueryValueConverter.Convert(complexProperty.Value, queryType)); } else if (primitiveMultiValueProperty != null) { return(this.PayloadElementToQueryValueConverter.Convert(primitiveMultiValueProperty.Value, queryType)); } else if (complexMultiValueProperty != null) { return(this.PayloadElementToQueryValueConverter.Convert(complexMultiValueProperty.Value, queryType)); } else if (primitiveCollection != null) { return(this.PayloadElementToQueryValueConverter.Convert(primitiveCollection, queryType)); } else if (complexInstanceCollection != null) { return(this.PayloadElementToQueryValueConverter.Convert(complexInstanceCollection, queryType)); } else { ExceptionUtilities.CheckArgumentNotNull(payload as EntityInstance, "Unexpected response payload type: " + payload.ElementType + "."); return(this.PayloadElementToQueryValueConverter.Convert(payload, queryType)); } }
/// <summary> /// Normalizes primitive properties, potentially replacing them with collections if the metadata indicates the payload is from a service operation /// </summary> /// <param name="payloadElement">The payload element to potentially replace</param> /// <returns>The original element or a copy to replace it with</returns> public override ODataPayloadElement Visit(PrimitiveProperty payloadElement) { var replaced = base.Visit(payloadElement); if (replaced.ElementType == ODataPayloadElementType.PrimitiveProperty) { payloadElement = (PrimitiveProperty)replaced; // if the payload looks like // <Foo /> // then it will be deserialized as a primitive property, when it could be an empty collection // if (this.ShouldReplaceWithCollection(payloadElement, payloadElement.Value.IsNull, payloadElement.Value.FullTypeName)) { // if the value is an empty string var stringValue = payloadElement.Value.ClrValue as string; if (stringValue != null && stringValue.Length == 0) { // get the element data type. Note that this must succeed based on the checks performed earlier var dataType = ((CollectionDataType)payloadElement.Annotations.OfType <DataTypeAnnotation>().Single().DataType).ElementDataType; // determine whether to return a complex or primitive collection based on the data type ODataPayloadElementCollection collection; if (dataType is PrimitiveDataType) { collection = new PrimitiveCollection(); } else { ExceptionUtilities.Assert(dataType is ComplexDataType, "Data type was neither primitive nor complex"); collection = new ComplexInstanceCollection(); } // return the replacement return(payloadElement .ReplaceWith(collection) .WithAnnotations(new CollectionNameAnnotation() { Name = payloadElement.Name })); } } } return(replaced); }
/// <summary> /// Visits the children of the given payload element and replaces it with a copy if any child changes /// </summary> /// <param name="payloadElement">The payload element to potentially replace</param> /// <returns>The original element or a copy to replace it with</returns> public override ODataPayloadElement Visit(PrimitiveProperty payloadElement) { if (payloadElement.Value == null || payloadElement.Value.ClrValue == null || payloadElement.Value.IsNull) { var nullProperty = new NullPropertyInstance() { Name = payloadElement.Name, }; foreach (ODataPayloadElementAnnotation annotation in payloadElement.Annotations) { nullProperty.Add(annotation); } return(nullProperty); } return(payloadElement); }
internal string macroPlayGetValue(string output, string field, TreeNodeCollection trc, ref int counter) { string s = string.Empty; foreach (TreeNode tn in trc) { TreeNodeProperty tnp = (tn.Tag as TreeNodeProperty); if (tnp != null) { if (string.Compare(field, tnp.Name, StringComparison.InvariantCultureIgnoreCase) == 0) { if (counter > 1) { counter--; continue; } treeOutput.SelectedNode = tn; ClassProperty cp = tn.Tag as ClassProperty; if (cp != null) { return(cp.InternalValue.ToString()); } PrimitiveProperty pp = tn.Tag as PrimitiveProperty; if (pp != null) { return(pp.Value.ToString()); } throw new ApplicationException("Unsupported type in macroPlayGetValue"); } } s = macroPlayGetValue(output, field, tn.Nodes, ref counter); if (!string.IsNullOrEmpty(s)) { break; } } return(s); }
/// <summary> /// Visits a payload element whose root is a PrimitiveProperty. /// </summary> /// <param name="payloadElement">The root node of payload element being visited.</param> public void Visit(PrimitiveProperty payloadElement) { ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement"); bool needsWrapping = this.isRootElement; this.isRootElement = false; if (needsWrapping) { this.writer.StartObjectScope(); } this.writer.WriteName(payloadElement.Name); this.Recurse(payloadElement.Value); if (needsWrapping) { this.writer.EndScope(); } }
private static PrimitiveProperty GetPrimitiveProperty(IRandomNumberGenerator random, EdmModel model = null) { var val = GetPrimitiveValue(random, model); var name = "ArbitraryPrimitiveProperty"; var payload = new PrimitiveProperty() { Name = name, Value = val }; if (model != null) { var entity = val.GetAnnotation <EntityModelTypeAnnotation>().EdmModelType.Definition as IEdmEntityType; // Finding a property name which exists in the model. We are using first because we don't care what property is returned so long as one exists. var property = entity.Properties().First(p => p.Type.Definition == val.GetAnnotation <DataTypeAnnotation>().EdmDataType); payload.Name = property.Name; payload.WithTypeAnnotation(entity); } return(payload); }
private static ComplexInstance GenerateSimilarComplexInstance(IRandomNumberGenerator random, ComplexInstance currentInstance, bool randomizePropertyValues = false) { ComplexInstance instance = ((ComplexInstance)currentInstance.DeepCopy()); if (!randomizePropertyValues) { return(instance); } foreach (var property in instance.Properties) { PrimitiveProperty primitive = property as PrimitiveProperty; if (primitive != null) { primitive.Value = TestValues.GetDifferentPrimitiveValue(primitive.Value); } ComplexProperty complex = property as ComplexProperty; if (complex != null) { complex.Value = GenerateSimilarComplexInstance(random, complex.Value); } PrimitiveMultiValueProperty pmultival = property as PrimitiveMultiValueProperty; if (pmultival != null) { pmultival.Value = GenerateSimilarPrimitiveMultiValue(random, pmultival.Value); } ComplexMultiValueProperty cmultival = property as ComplexMultiValueProperty; if (cmultival != null) { cmultival.Value = GenerateSimilarComplexMultiValue(random, cmultival.Value); } } return(instance); }
private static PrimitiveProperty GetPrimitiveProperty(IRandomNumberGenerator random, EdmModel model = null) { var val = GetPrimitiveValue(random, model); var name = "ArbitraryPrimitiveProperty"; var payload = new PrimitiveProperty() { Name = name, Value = val }; if (model != null) { var entity = val.GetAnnotation<EntityModelTypeAnnotation>().EdmModelType.Definition as IEdmEntityType; // Finding a property name which exists in the model. We are using first because we don't care what property is returned so long as one exists. var property = entity.Properties().First(p => p.Type.Definition == val.GetAnnotation<DataTypeAnnotation>().EdmDataType); payload.Name = property.Name; payload.WithTypeAnnotation(entity); } return payload; }
private static ODataPayloadElement CreatePayloadElement(IEdmModel model, ODataPayloadKind payloadKind, ReaderTestConfiguration testConfig) { IEdmEntitySet citySet = model.EntityContainer.FindEntitySet("Cities"); IEdmEntityType cityType = model.EntityTypes().Single(e => e.Name == "CityType"); IEdmProperty cityNameProperty = cityType.Properties().Single(e => e.Name == "Name"); IEdmNavigationProperty policeStationNavProp = cityType.NavigationProperties().Single(e => e.Name == "PoliceStation"); IEdmOperationImport primitiveCollectionResultOperation = model.EntityContainer.FindOperationImports("PrimitiveCollectionResultOperation").Single(); IEdmOperationImport serviceOp1 = model.EntityContainer.FindOperationImports("ServiceOperation1").Single(); bool isRequest = testConfig.IsRequest; bool isJsonLightRequest = isRequest && testConfig.Format == ODataFormat.Json; switch (payloadKind) { case ODataPayloadKind.Feed: { return(PayloadBuilder.EntitySet().WithTypeAnnotation(cityType).ExpectedEntityType(cityType, citySet)); } case ODataPayloadKind.Entry: { return(PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).WithTypeAnnotation(cityType).ExpectedEntityType(cityType, citySet)); } case ODataPayloadKind.Property: return(PayloadBuilder.PrimitiveProperty(isJsonLightRequest ? string.Empty : null, "SomeCityValue").ExpectedProperty(cityType, "Name")); case ODataPayloadKind.EntityReferenceLink: return(PayloadBuilder.DeferredLink("http://odata.org/entityreferencelink").ExpectedNavigationProperty(citySet, cityType, "PoliceStation")); case ODataPayloadKind.EntityReferenceLinks: return(PayloadBuilder.LinkCollection().Item(PayloadBuilder.DeferredLink("http://odata.org/entityreferencelink")).ExpectedNavigationProperty((EdmEntitySet)citySet, (EdmEntityType)cityType, "CityHall")); case ODataPayloadKind.Value: return(PayloadBuilder.PrimitiveValue("PrimitiveValue")); case ODataPayloadKind.BinaryValue: return(PayloadBuilder.PrimitiveValue(new byte[] { 0, 0, 1, 1 })); case ODataPayloadKind.Collection: return(PayloadBuilder.PrimitiveCollection().CollectionName(null).ExpectedFunctionImport((EdmOperationImport)primitiveCollectionResultOperation)); case ODataPayloadKind.ServiceDocument: Debug.Assert(!isRequest, "Not supported in requests."); return(new ServiceDocumentInstance().Workspace(PayloadBuilder.Workspace())); case ODataPayloadKind.MetadataDocument: Debug.Assert(!isRequest, "Not supported in requests."); throw new NotImplementedException(); case ODataPayloadKind.Error: Debug.Assert(!isRequest, "Not supported in requests."); return(PayloadBuilder.Error("ErrorCode")); case ODataPayloadKind.Parameter: // build parameter payload based on model definition var parameterPayload = new ComplexInstance(null, false); ODataPayloadElement a = PayloadBuilder.PrimitiveValue(123).WithTypeAnnotation(EdmCoreModel.Instance.GetInt32(false)); ODataPayloadElement b = PayloadBuilder.PrimitiveValue("stringvalue").WithTypeAnnotation(EdmCoreModel.Instance.GetString(false)); PrimitiveProperty parametera = new PrimitiveProperty("a", "Edm.Integer", ((PrimitiveValue)a).ClrValue); PrimitiveProperty parameterb = new PrimitiveProperty("b", "Edm.String", ((PrimitiveValue)b).ClrValue); parameterPayload.Add(parametera); parameterPayload.Add(parameterb); parameterPayload.ExpectedFunctionImport((EdmOperationImport)serviceOp1); return(parameterPayload); case ODataPayloadKind.Unsupported: // fall through default: throw new NotSupportedException(); } }
/// <summary> /// Visits the payload element. /// </summary> /// <param name="payloadElement">The payload element to visit.</param> public override void Visit(PrimitiveProperty payloadElement) { var observed = this.GetNextObservedElement <PrimitiveProperty>(); this.WrapAccept(payloadElement.Value, observed.Value); }
/// <summary> /// Builds a complex instance from the given payloadElements to represent a parameters payload. /// </summary> /// <param name="payloadElements">Each ODataPayloadElement represents the value for each parameter.</param> /// <param name="model">EdmModel instance.</param> /// <param name="functionImportName">Name of the function import to add to the model.</param> /// <returns></returns> private static ComplexInstance PayloadElementsToParameterPayload(ODataPayloadElement[] payloadElements, EdmModel model, string functionImportName) { EdmOperationImport operationImport = (EdmOperationImport)model.EntityContainer.FindOperationImports(functionImportName).FirstOrDefault(); EdmOperation operation = (EdmOperation)operationImport.Operation; var parameterPayload = new ComplexInstance(null, false); for (int idx = 0; idx < payloadElements.Length; idx++) { ODataPayloadElement p = payloadElements[idx]; string parameterName = "p" + idx; PropertyInstance parameter; IEdmTypeReference entityModelType = p.GetAnnotation <EntityModelTypeAnnotation>().EdmModelType; switch (p.ElementType) { case ODataPayloadElementType.PrimitiveValue: object clrValue = ((PrimitiveValue)p).ClrValue; PrimitiveValue primitiveValue = new PrimitiveValue(clrValue == null ? null : clrValue.GetType().FullName, clrValue); primitiveValue.CopyAnnotation <PrimitiveValue, EntityModelTypeAnnotation>(p); parameter = new PrimitiveProperty(parameterName, primitiveValue); operation.AddParameter(parameterName, MetadataUtils.GetPrimitiveTypeReference(primitiveValue.ClrValue.GetType())); break; case ODataPayloadElementType.ComplexInstance: parameter = new ComplexProperty(parameterName, (ComplexInstance)p); operation.AddParameter(parameterName, entityModelType); break; case ODataPayloadElementType.PrimitiveMultiValue: PrimitiveMultiValue primitiveMultiValue = (PrimitiveMultiValue)p; if (primitiveMultiValue.Annotations.OfType <JsonCollectionResultWrapperAnnotation>().SingleOrDefault() == null) { primitiveMultiValue.Annotations.Add(new JsonCollectionResultWrapperAnnotation(false)); } parameter = new PrimitiveMultiValueProperty(parameterName, primitiveMultiValue); operation.AddParameter(parameterName, entityModelType); break; case ODataPayloadElementType.ComplexMultiValue: ComplexMultiValue complexMultiValue = (ComplexMultiValue)p; if (complexMultiValue.Annotations.OfType <JsonCollectionResultWrapperAnnotation>().SingleOrDefault() == null) { complexMultiValue.Annotations.Add(new JsonCollectionResultWrapperAnnotation(false)); } parameter = new ComplexMultiValueProperty(parameterName, complexMultiValue); operation.AddParameter(parameterName, entityModelType); break; case ODataPayloadElementType.EntityInstance: parameter = new NavigationPropertyInstance(parameterName, (EntityInstance)p); operation.AddParameter(parameterName, entityModelType); break; case ODataPayloadElementType.EntitySetInstance: parameter = new NavigationPropertyInstance(parameterName, (EntitySetInstance)p); operation.AddParameter(parameterName, entityModelType); break; default: throw new NotSupportedException("PayloadElementsToParameterPayload() is called on unsupported ODataPayloadElement type: " + p.ElementType); } parameterPayload.Add(parameter); } parameterPayload.ExpectedFunctionImport(operationImport); return(parameterPayload); }
/// <summary> /// Normalizes primitive property. /// </summary> /// <param name="payloadElement">The payload element to normalize.</param> public override void Visit(PrimitiveProperty payloadElement) { base.Visit(payloadElement); this.NormalizePropertyName(payloadElement); }
/// <summary> /// Creates a primitive ODataProperty and sets the value. /// </summary> /// <param name="payloadElement">The primitive property to process.</param> public override void Visit(PrimitiveProperty payloadElement) { var odataProperty = new ODataProperty() { Name = payloadElement.Name, Value = payloadElement.Value.ClrValue, }; var parent = this.items.Peek(); // not calling the base since we don't want to visit the value //If there is no parent then this is top level and add to items //otherwise add to parent. if (parent == null) { this.items.Push(odataProperty); } else { var entry = parent as ODataEntry; if (entry != null) { var properties = (List<ODataProperty>)entry.Properties; properties.Add(odataProperty); } var complexValue = parent as ODataComplexValue; if (complexValue != null) { var properties = (List<ODataProperty>)complexValue.Properties; properties.Add(odataProperty); } } }
/// <summary> /// Visits the payload element /// </summary> /// <param name="payloadElement">The payload element to visit</param> public virtual void Visit(PrimitiveProperty payloadElement) { ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement"); this.VisitProperty(payloadElement, payloadElement.Value); }
/// <summary> /// Asserts that two payload elements are equal. /// </summary> /// <param name="expected">The expected element</param> /// <param name="observed">The actual, observed element</param> public void Compare(ODataPayloadElement expected, ODataPayloadElement observed) { if (expected == null) { this.Assert.IsNull(observed, "Observed element must be null"); return; } this.Assert.AreEqual(expected.ElementType, observed.ElementType, "Element types are not equal."); this.Assert.AreEqual(expected.Annotations.Count, observed.Annotations.Count, "Annotation counts are not equal"); Compare(expected.Annotations, observed.Annotations); switch (expected.ElementType) { case ODataPayloadElementType.EntitySetInstance: EntitySetInstance expectedSet = expected as EntitySetInstance; EntitySetInstance observedSet = observed as EntitySetInstance; this.Assert.AreEqual(expectedSet.NextLink, observedSet.NextLink, "Next links are not equal"); this.Assert.AreEqual(expectedSet.InlineCount, observedSet.InlineCount, "Inline counts are not equal"); this.Assert.AreEqual(expectedSet.Count, observedSet.Count, "Entity counts are not equal"); for (int i = 0; i < expectedSet.Count; i++) { Compare(expectedSet[i], observedSet[i]); } break; case ODataPayloadElementType.EntityInstance: EntityInstance expectedEntity = expected as EntityInstance; EntityInstance observedEntity = observed as EntityInstance; this.Assert.AreEqual(expectedEntity.Id, observedEntity.Id, "Entity IDs are not equal"); this.Assert.AreEqual(expectedEntity.ETag, observedEntity.ETag, "ETags are not equal"); this.Assert.AreEqual(expectedEntity.IsNull, observedEntity.IsNull, "IsNull flags are not equal"); this.Assert.AreEqual(expectedEntity.FullTypeName, observedEntity.FullTypeName, "FullTypeNames are not equal"); this.Assert.AreEqual(expectedEntity.StreamContentType, observedEntity.StreamContentType, "Stream content types are not equal"); this.Assert.AreEqual(expectedEntity.StreamEditLink, observedEntity.StreamEditLink, "Stream edit links are not equal"); this.Assert.AreEqual(expectedEntity.StreamETag, observedEntity.StreamETag, "Stream ETags are not equal"); this.Assert.AreEqual(expectedEntity.StreamSourceLink, observedEntity.StreamSourceLink, "Stream source links are not equal"); this.Assert.AreEqual(expectedEntity.Properties.Count(), observedEntity.Properties.Count(), "Property counts are not equal"); for (int i = 0; i < expectedEntity.Properties.Count(); i++) { Compare(expectedEntity.Properties.ElementAt(i), observedEntity.Properties.ElementAt(i)); } break; case ODataPayloadElementType.ComplexInstance: ComplexInstance expectedCI = expected as ComplexInstance; ComplexInstance observedCI = observed as ComplexInstance; this.Assert.AreEqual(expectedCI.IsNull, observedCI.IsNull, "IsNull flags are not equal"); this.Assert.AreEqual(expectedCI.FullTypeName, observedCI.FullTypeName, "Full type names are not equal"); this.Assert.AreEqual(expectedCI.Properties.Count(), observedCI.Properties.Count(), "Property counts are not equal"); for (int i = 0; i < expectedCI.Properties.Count(); i++) { Compare(expectedCI.Properties.ElementAt(i), observedCI.Properties.ElementAt(i)); } break; case ODataPayloadElementType.NamedStreamInstance: NamedStreamInstance expectedNsi = expected as NamedStreamInstance; NamedStreamInstance observedNsi = observed as NamedStreamInstance; this.Assert.AreEqual(expectedNsi.Name, observedNsi.Name, "Stream names are not equal"); this.Assert.AreEqual(expectedNsi.ETag, observedNsi.ETag, "Stream ETags are not equal"); this.Assert.AreEqual(expectedNsi.EditLink, observedNsi.EditLink, "Edit links are not equal"); this.Assert.AreEqual(expectedNsi.EditLinkContentType, observedNsi.EditLinkContentType, "Edit link content types are not equal"); this.Assert.AreEqual(expectedNsi.SourceLink, observedNsi.SourceLink, "Source links are not equal"); this.Assert.AreEqual(expectedNsi.SourceLinkContentType, observedNsi.SourceLinkContentType, "Source links content types are not equal"); break; case ODataPayloadElementType.NavigationPropertyInstance: NavigationPropertyInstance expectedNav = expected as NavigationPropertyInstance; NavigationPropertyInstance observedNav = observed as NavigationPropertyInstance; Assert.AreEqual(expectedNav.Name, observedNav.Name, "Navigation property names are not equal"); Compare(expectedNav.AssociationLink, observedNav.AssociationLink); Compare(expectedNav.Value, observedNav.Value); break; case ODataPayloadElementType.ComplexProperty: ComplexProperty expectedCP = expected as ComplexProperty; ComplexProperty observedCP = observed as ComplexProperty; this.Assert.AreEqual(expectedCP.Name, observedCP.Name, "Complex property names are not equal"); Compare(expectedCP.Value, observedCP.Value); break; case ODataPayloadElementType.PrimitiveProperty: PrimitiveProperty expectedProperty = expected as PrimitiveProperty; PrimitiveProperty observedProperty = observed as PrimitiveProperty; this.Assert.AreEqual(expectedProperty.Name, observedProperty.Name, "Primitive property names are not equal"); Compare(expectedProperty.Value, observedProperty.Value); break; case ODataPayloadElementType.PrimitiveValue: PrimitiveValue expectedValue = expected as PrimitiveValue; PrimitiveValue observedValue = observed as PrimitiveValue; this.Assert.AreEqual(expectedValue.IsNull, observedValue.IsNull, "IsNull flags are not equal"); if (expectedValue.FullTypeName != null) { if (expectedValue.FullTypeName.Equals("Edm.String")) { this.Assert.IsTrue(string.IsNullOrEmpty(observedValue.FullTypeName) || observedValue.FullTypeName.Equals("Edm.String"), "FullTypeName should be null or Edm.String"); } else { this.Assert.AreEqual(expectedValue.FullTypeName, observedValue.FullTypeName, "Full type names are not equal"); } } else { this.Assert.IsNull(observedValue.FullTypeName, "observed full type name should be null"); } this.Assert.AreEqual(expectedValue.ClrValue, observedValue.ClrValue, "Clr values are not equal"); break; case ODataPayloadElementType.DeferredLink: DeferredLink expectedLink = expected as DeferredLink; DeferredLink observedLink = observed as DeferredLink; this.Assert.AreEqual(expectedLink.UriString, observedLink.UriString, "Uris are not equal"); break; case ODataPayloadElementType.ExpandedLink: ExpandedLink expectedExpand = expected as ExpandedLink; ExpandedLink observedExpand = observed as ExpandedLink; Compare(expectedExpand.ExpandedElement, observedExpand.ExpandedElement); break; case ODataPayloadElementType.LinkCollection: LinkCollection expectedLinks = expected as LinkCollection; LinkCollection observedLinks = observed as LinkCollection; this.Assert.AreEqual(expectedLinks.Count, observedLinks.Count, "Link counts are not equal"); this.Assert.AreEqual(expectedLinks.InlineCount, observedLinks.InlineCount, "Link inline counts are not equal"); for (int i = 0; i < expectedLinks.Count; i++) { Compare(expectedLinks[i], observedLinks[i]); } break; case ODataPayloadElementType.PrimitiveMultiValueProperty: var expectedPrimitiveCollectionProperty = expected as PrimitiveMultiValueProperty; var observedPrimitiveCollectionProperty = observed as PrimitiveMultiValueProperty; this.Assert.AreEqual(expectedPrimitiveCollectionProperty.Name, observedPrimitiveCollectionProperty.Name, "Property names are not equal"); this.Assert.AreEqual(expectedPrimitiveCollectionProperty.Value.FullTypeName, observedPrimitiveCollectionProperty.Value.FullTypeName, "Full type names are not equal"); this.Assert.AreEqual(expectedPrimitiveCollectionProperty.Value.Count, observedPrimitiveCollectionProperty.Value.Count, "Collection counts are not equal"); for (int i = 0; i < expectedPrimitiveCollectionProperty.Value.Count; i++) { Compare(expectedPrimitiveCollectionProperty.Value[i], observedPrimitiveCollectionProperty.Value[i]); } break; case ODataPayloadElementType.ComplexMultiValueProperty: var expectedComplexCollectionProperty = expected as ComplexMultiValueProperty; var observedComplexCollectionProperty = observed as ComplexMultiValueProperty; this.Assert.AreEqual(expectedComplexCollectionProperty.Name, observedComplexCollectionProperty.Name, "Property names are not equal"); this.Assert.AreEqual(expectedComplexCollectionProperty.Value.FullTypeName, observedComplexCollectionProperty.Value.FullTypeName, "Full type names are not equal"); this.Assert.AreEqual(expectedComplexCollectionProperty.Value.Count, observedComplexCollectionProperty.Value.Count, "Collection counts are not equal"); for (int i = 0; i < expectedComplexCollectionProperty.Value.Count; i++) { Compare(expectedComplexCollectionProperty.Value[i], observedComplexCollectionProperty.Value[i]); } break; case ODataPayloadElementType.PrimitiveCollection: var expectedPrimitiveCollection = expected as PrimitiveCollection; var observedPrimitiveCollection = observed as PrimitiveCollection; this.Assert.AreEqual(expectedPrimitiveCollection.Count, observedPrimitiveCollection.Count, "Collection counts are not equal"); for (int i = 0; i < expectedPrimitiveCollection.Count; i++) { Compare(expectedPrimitiveCollection[i], observedPrimitiveCollection[i]); } break; case ODataPayloadElementType.ComplexInstanceCollection: var expectedComplexCollection = expected as ComplexInstanceCollection; var observedComplexCollection = observed as ComplexInstanceCollection; this.Assert.AreEqual(expectedComplexCollection.Count, observedComplexCollection.Count, "Collection counts are not equal"); for (int i = 0; i < expectedComplexCollection.Count; i++) { Compare(expectedComplexCollection[i], observedComplexCollection[i]); } break; case ODataPayloadElementType.NullPropertyInstance: case ODataPayloadElementType.EmptyUntypedCollection: break; default: this.Assert.Fail("Case " + expected.ElementType + " unhandled"); break; } }
public override void Visit(PrimitiveProperty payloadElement) { base.Visit(payloadElement); this.ReplaceExpectedTypeAnnotationIfRootElement(payloadElement); }
/// <summary> /// Visits a primitive property and adds a property to the list of values to be written /// </summary> /// <param name="payloadElement">The property to be added to the list</param> public override void Visit(PrimitiveProperty payloadElement) { this.odataProperties.Add(CreateProperty(payloadElement.Name, payloadElement.Value.ClrValue)); }
/// <summary> /// Builds a complex instance from the given payloadElements to represent a parameters payload. /// </summary> /// <param name="payloadElements">Each ODataPayloadElement represents the value for each parameter.</param> /// <param name="model">EdmModel instance.</param> /// <param name="functionImportName">Name of the function import to add to the model.</param> /// <returns></returns> private static ComplexInstance PayloadElementsToParameterPayload(ODataPayloadElement[] payloadElements, EdmModel model, string functionImportName) { EdmOperationImport operationImport = (EdmOperationImport)model.EntityContainer.FindOperationImports(functionImportName).FirstOrDefault(); EdmOperation operation = (EdmOperation)operationImport.Operation; var parameterPayload = new ComplexInstance(null, false); for (int idx = 0; idx < payloadElements.Length; idx++) { ODataPayloadElement p = payloadElements[idx]; string parameterName = "p" + idx; PropertyInstance parameter; IEdmTypeReference entityModelType = p.GetAnnotation<EntityModelTypeAnnotation>().EdmModelType; switch (p.ElementType) { case ODataPayloadElementType.PrimitiveValue: object clrValue = ((PrimitiveValue)p).ClrValue; PrimitiveValue primitiveValue = new PrimitiveValue(clrValue == null ? null : clrValue.GetType().FullName, clrValue); primitiveValue.CopyAnnotation<PrimitiveValue, EntityModelTypeAnnotation>(p); parameter = new PrimitiveProperty(parameterName, primitiveValue); operation.AddParameter(parameterName, MetadataUtils.GetPrimitiveTypeReference(primitiveValue.ClrValue.GetType())); break; case ODataPayloadElementType.ComplexInstance: parameter = new ComplexProperty(parameterName, (ComplexInstance)p); operation.AddParameter(parameterName, entityModelType); break; case ODataPayloadElementType.PrimitiveMultiValue: PrimitiveMultiValue primitiveMultiValue = (PrimitiveMultiValue)p; if (primitiveMultiValue.Annotations.OfType<JsonCollectionResultWrapperAnnotation>().SingleOrDefault() == null) { primitiveMultiValue.Annotations.Add(new JsonCollectionResultWrapperAnnotation(false)); } parameter = new PrimitiveMultiValueProperty(parameterName, primitiveMultiValue); operation.AddParameter(parameterName, entityModelType); break; case ODataPayloadElementType.ComplexMultiValue: ComplexMultiValue complexMultiValue = (ComplexMultiValue)p; if (complexMultiValue.Annotations.OfType<JsonCollectionResultWrapperAnnotation>().SingleOrDefault() == null) { complexMultiValue.Annotations.Add(new JsonCollectionResultWrapperAnnotation(false)); } parameter = new ComplexMultiValueProperty(parameterName, complexMultiValue); operation.AddParameter(parameterName, entityModelType); break; case ODataPayloadElementType.EntityInstance: parameter = new NavigationPropertyInstance(parameterName, (EntityInstance)p); operation.AddParameter(parameterName, entityModelType); break; case ODataPayloadElementType.EntitySetInstance: parameter = new NavigationPropertyInstance(parameterName, (EntitySetInstance)p); operation.AddParameter(parameterName, entityModelType); break; default: throw new NotSupportedException("PayloadElementsToParameterPayload() is called on unsupported ODataPayloadElement type: " + p.ElementType); } parameterPayload.Add(parameter); } parameterPayload.ExpectedFunctionImport(operationImport); return parameterPayload; }
/// <summary> /// Normalizes primitive properties, potentially replacing them with collections if the metadata indicates the payload is from a service operation /// </summary> /// <param name="payloadElement">The payload element to potentially replace</param> /// <returns>The original element or a copy to replace it with</returns> public override ODataPayloadElement Visit(PrimitiveProperty payloadElement) { var replaced = base.Visit(payloadElement); if (replaced.ElementType == ODataPayloadElementType.PrimitiveProperty) { payloadElement = (PrimitiveProperty)replaced; // if the payload looks like // <Foo /> // then it will be deserialized as a primitive property, when it could be an empty collection // if (this.ShouldReplaceWithCollection(payloadElement, payloadElement.Value.IsNull, payloadElement.Value.FullTypeName)) { // if the value is an empty string var stringValue = payloadElement.Value.ClrValue as string; if (stringValue != null && stringValue.Length == 0) { // get the element data type. Note that this must succeed based on the checks performed earlier var dataType = ((CollectionDataType)payloadElement.Annotations.OfType<DataTypeAnnotation>().Single().DataType).ElementDataType; // determine whether to return a complex or primitive collection based on the data type ODataPayloadElementCollection collection; if (dataType is PrimitiveDataType) { collection = new PrimitiveCollection(); } else { ExceptionUtilities.Assert(dataType is ComplexDataType, "Data type was neither primitive nor complex"); collection = new ComplexInstanceCollection(); } // return the replacement return payloadElement .ReplaceWith(collection) .WithAnnotations(new CollectionNameAnnotation() { Name = payloadElement.Name }); } } } return replaced; }
/// <summary> /// Creates a set of interesting entity instances along with metadata. /// </summary> /// <param name="settings">The test descriptor settings to use.</param> /// <param name="model">If non-null, the method creates complex types for the complex values and adds them to the model.</param> /// <param name="withTypeNames">true if the payloads should specify type names.</param> /// <returns>List of test descriptors with interesting entity instances as payload.</returns> public static IEnumerable <PayloadTestDescriptor> CreateEntityInstanceTestDescriptors( EdmModel model, bool withTypeNames) { IEnumerable <PrimitiveValue> primitiveValues = TestValues.CreatePrimitiveValuesWithMetadata(fullSet: false); IEnumerable <ComplexInstance> complexValues = TestValues.CreateComplexValues(model, withTypeNames, fullSet: false); IEnumerable <NamedStreamInstance> streamReferenceValues = TestValues.CreateStreamReferenceValues(fullSet: false); IEnumerable <PrimitiveMultiValue> primitiveMultiValues = TestValues.CreatePrimitiveCollections(withTypeNames, fullSet: false); IEnumerable <ComplexMultiValue> complexMultiValues = TestValues.CreateComplexCollections(model, withTypeNames, fullSet: false); IEnumerable <NavigationPropertyInstance> navigationProperties = TestValues.CreateDeferredNavigationLinks(); // NOTE we have to copy the EntityModelTypeAnnotation on the primitive value to the NullPropertyInstance for null values since the // NullPropertyInstance does not expose a value. We will later copy it back to the value we generate for the null property. IEnumerable <PropertyInstance> primitiveProperties = primitiveValues.Select((pv, ix) => PayloadBuilder.Property("PrimitiveProperty" + ix, pv).CopyAnnotation <PropertyInstance, EntityModelTypeAnnotation>(pv)); IEnumerable <PropertyInstance> complexProperties = complexValues.Select((cv, ix) => PayloadBuilder.Property("ComplexProperty" + ix, cv)); IEnumerable <PropertyInstance> primitiveMultiValueProperties = primitiveMultiValues.Select((pmv, ix) => PayloadBuilder.Property("PrimitiveMultiValueProperty" + ix, pmv)); IEnumerable <PropertyInstance> complexMultiValueProperties = complexMultiValues.Select((cmv, ix) => PayloadBuilder.Property("ComplexMultiValueProperty" + ix, cmv)); PropertyInstance[][] propertyMatrix = new PropertyInstance[6][]; propertyMatrix[0] = primitiveProperties.ToArray(); propertyMatrix[1] = complexProperties.ToArray(); propertyMatrix[2] = streamReferenceValues.ToArray(); propertyMatrix[3] = primitiveMultiValueProperties.ToArray(); propertyMatrix[4] = complexMultiValueProperties.ToArray(); propertyMatrix[5] = navigationProperties.ToArray(); IEnumerable <PropertyInstance[]> propertyCombinations = propertyMatrix.ColumnCombinations(0, 1, 6); int count = 0; foreach (PropertyInstance[] propertyCombination in propertyCombinations) { // build the entity type, add it to the model EdmEntityType generatedEntityType = null; string typeName = "PGEntityType" + count; EdmEntityContainer container = null; EdmEntitySet entitySet = null; if (model != null) { // generate a new type with the auto-generated name, check that no type with this name exists and add the default key property to it. Debug.Assert(model.FindDeclaredType(typeName) == null, "Entity type '" + typeName + "' already exists."); generatedEntityType = new EdmEntityType("TestModel", typeName); generatedEntityType.AddKeys(generatedEntityType.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32)); model.AddElement(generatedEntityType); container = model.EntityContainer as EdmEntityContainer; if (container == null) { container = new EdmEntityContainer("TestModel", "DefaultNamespace"); model.AddElement(container); } entitySet = container.AddEntitySet(typeName, generatedEntityType); } EntityInstance entityInstance = PayloadBuilder.Entity("TestModel." + typeName) .Property("Id", PayloadBuilder.PrimitiveValue(count).WithTypeAnnotation(EdmCoreModel.Instance.GetInt32(false))); for (int i = 0; i < propertyCombination.Length; ++i) { PropertyInstance currentProperty = propertyCombination[i]; entityInstance.Add(currentProperty); if (model != null) { if (entitySet == null) { entitySet = container.FindEntitySet(typeName) as EdmEntitySet; } switch (currentProperty.ElementType) { case ODataPayloadElementType.ComplexProperty: ComplexProperty complexProperty = (ComplexProperty)currentProperty; generatedEntityType.AddStructuralProperty(complexProperty.Name, complexProperty.Value.GetAnnotation <EntityModelTypeAnnotation>().EdmModelType); break; case ODataPayloadElementType.PrimitiveProperty: PrimitiveProperty primitiveProperty = (PrimitiveProperty)currentProperty; if (primitiveProperty.Value == null) { generatedEntityType.AddStructuralProperty( primitiveProperty.Name, PayloadBuilder.PrimitiveValueType(null)); } else { generatedEntityType.AddStructuralProperty(primitiveProperty.Name, primitiveProperty.Value.GetAnnotation <EntityModelTypeAnnotation>().EdmModelType); } break; case ODataPayloadElementType.NamedStreamInstance: NamedStreamInstance streamProperty = (NamedStreamInstance)currentProperty; generatedEntityType.AddStructuralProperty(streamProperty.Name, EdmPrimitiveTypeKind.Stream); break; case ODataPayloadElementType.EmptyCollectionProperty: throw new NotImplementedException(); case ODataPayloadElementType.NavigationPropertyInstance: NavigationPropertyInstance navigationProperty = (NavigationPropertyInstance)currentProperty; var navProperty = generatedEntityType.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo() { ContainsTarget = false, Name = navigationProperty.Name, Target = generatedEntityType, TargetMultiplicity = EdmMultiplicity.One }); entitySet.AddNavigationTarget(navProperty, entitySet); break; case ODataPayloadElementType.ComplexMultiValueProperty: ComplexMultiValueProperty complexMultiValueProperty = (ComplexMultiValueProperty)currentProperty; generatedEntityType.AddStructuralProperty(complexMultiValueProperty.Name, complexMultiValueProperty.Value.GetAnnotation <EntityModelTypeAnnotation>().EdmModelType); break; case ODataPayloadElementType.PrimitiveMultiValueProperty: PrimitiveMultiValueProperty primitiveMultiValueProperty = (PrimitiveMultiValueProperty)currentProperty; generatedEntityType.AddStructuralProperty(primitiveMultiValueProperty.Name, primitiveMultiValueProperty.Value.GetAnnotation <EntityModelTypeAnnotation>().EdmModelType); break; default: throw new NotSupportedException("Unsupported element type found : " + propertyCombination[i].ElementType); } } } if (generatedEntityType != null) { entityInstance.AddAnnotation(new EntityModelTypeAnnotation(generatedEntityType.ToTypeReference(true))); } yield return(new PayloadTestDescriptor() { PayloadElement = entityInstance, PayloadEdmModel = model }); count++; } }
private static ODataPayloadElement CreatePayloadElement(IEdmModel model, ODataPayloadKind payloadKind, ReaderTestConfiguration testConfig) { IEdmEntitySet citySet = model.EntityContainer.FindEntitySet("Cities"); IEdmEntityType cityType = model.EntityTypes().Single(e => e.Name == "CityType"); IEdmProperty cityNameProperty = cityType.Properties().Single(e => e.Name == "Name"); IEdmNavigationProperty policeStationNavProp = cityType.NavigationProperties().Single(e => e.Name == "PoliceStation"); IEdmOperationImport primitiveCollectionResultOperation = model.EntityContainer.FindOperationImports("PrimitiveCollectionResultOperation").Single(); IEdmOperationImport serviceOp1 = model.EntityContainer.FindOperationImports("ServiceOperation1").Single(); bool isRequest = testConfig.IsRequest; bool isJsonLightRequest = isRequest && testConfig.Format == ODataFormat.Json; switch (payloadKind) { case ODataPayloadKind.Feed: { return PayloadBuilder.EntitySet().WithTypeAnnotation(cityType).ExpectedEntityType(cityType, citySet); } case ODataPayloadKind.Entry: { return PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).WithTypeAnnotation(cityType).ExpectedEntityType(cityType, citySet); } case ODataPayloadKind.Property: return PayloadBuilder.PrimitiveProperty(isJsonLightRequest ? string.Empty : null, "SomeCityValue").ExpectedProperty(cityType, "Name"); case ODataPayloadKind.EntityReferenceLink: return PayloadBuilder.DeferredLink("http://odata.org/entityreferencelink").ExpectedNavigationProperty(citySet, cityType, "PoliceStation"); case ODataPayloadKind.EntityReferenceLinks: return PayloadBuilder.LinkCollection().Item(PayloadBuilder.DeferredLink("http://odata.org/entityreferencelink")).ExpectedNavigationProperty((EdmEntitySet)citySet, (EdmEntityType)cityType, "CityHall"); case ODataPayloadKind.Value: return PayloadBuilder.PrimitiveValue("PrimitiveValue"); case ODataPayloadKind.BinaryValue: return PayloadBuilder.PrimitiveValue(new byte[] { 0, 0, 1, 1 }); case ODataPayloadKind.Collection: return PayloadBuilder.PrimitiveCollection().CollectionName(null).ExpectedFunctionImport((EdmOperationImport)primitiveCollectionResultOperation); case ODataPayloadKind.ServiceDocument: Debug.Assert(!isRequest, "Not supported in requests."); return new ServiceDocumentInstance().Workspace(PayloadBuilder.Workspace()); case ODataPayloadKind.MetadataDocument: Debug.Assert(!isRequest, "Not supported in requests."); throw new NotImplementedException(); case ODataPayloadKind.Error: Debug.Assert(!isRequest, "Not supported in requests."); return PayloadBuilder.Error("ErrorCode"); case ODataPayloadKind.Parameter: // build parameter payload based on model definition var parameterPayload = new ComplexInstance(null, false); ODataPayloadElement a = PayloadBuilder.PrimitiveValue(123).WithTypeAnnotation(EdmCoreModel.Instance.GetInt32(false)); ODataPayloadElement b = PayloadBuilder.PrimitiveValue("stringvalue").WithTypeAnnotation(EdmCoreModel.Instance.GetString(false)); PrimitiveProperty parametera = new PrimitiveProperty("a", "Edm.Integer", ((PrimitiveValue)a).ClrValue); PrimitiveProperty parameterb = new PrimitiveProperty("b", "Edm.String", ((PrimitiveValue)b).ClrValue); parameterPayload.Add(parametera); parameterPayload.Add(parameterb); parameterPayload.ExpectedFunctionImport((EdmOperationImport)serviceOp1); return parameterPayload; case ODataPayloadKind.Unsupported: // fall through default: throw new NotSupportedException(); } }
/// <summary> /// Visits a payload element whose root is a PrimitiveProperty. /// </summary> /// <param name="payloadElement">The root node of payload element being visited.</param> public override void Visit(PrimitiveProperty payloadElement) { RemoveChangeAnnotations(payloadElement); base.Visit(payloadElement); }
/// <summary> /// Visits a payload element whose root is a PrimitiveProperty. /// </summary> /// <param name="payloadElement">The root node of payload element being visited.</param> public void Visit(PrimitiveProperty payloadElement) { ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement"); var current = this.expectedValueStack.Peek(); var value = current as QueryScalarValue; ExceptionUtilities.CheckObjectNotNull(value, "Value was not a primitive. Value was: '{0}'", current.ToString()); this.RecurseWithMessage(payloadElement.Value, value, "Primitive property '{0}' did not match expectation", payloadElement.Name); }
/// <summary> /// Deserializes the element as either a complex, a primitive, or a null property, based on the content /// </summary> /// <param name="property">The xml to deserialize</param> /// <param name="typeNameFallback">TypeName to use instead of the one from the XElement[type] attribute</param> /// <returns>A property representing the given xml</returns> private PropertyInstance DeserializeProperty(XElement property, string typeNameFallback) { string propertyName = property.Name.LocalName; // get the type name string typeNameFromPayload = null; XAttribute typeAttribute = property.Attribute(MetadataType); if (typeAttribute != null) { typeNameFromPayload = typeAttribute.Value; } // set type to be fallback when typeattribute does not exist var typeNameForClrTypeLookup = typeNameFromPayload; if (typeNameForClrTypeLookup == null && !string.IsNullOrEmpty(typeNameFallback)) { typeNameForClrTypeLookup = typeNameFallback; } // try to infer the clr type Type clrType = null; if (!string.IsNullOrEmpty(typeNameForClrTypeLookup)) { ExceptionUtilities.CheckObjectNotNull(this.PrimitiveDataTypeConverter, "Cannot infer clr type from edm type without converter"); clrType = this.PrimitiveDataTypeConverter.ToClrType(typeNameForClrTypeLookup); } PropertyInstance result; if (property.HasElements) { // must be complex, a multivalue, or spatial ExceptionUtilities.CheckObjectNotNull(this.SpatialFormatter, "Cannot safely deserialize element with children without spatial formatter."); // try to infer which spatial type hierarchy it is from the type name in the payload SpatialTypeKind?kind = null; if (clrType != null) { SpatialUtilities.TryInferSpatialTypeKind(clrType, out kind); } object spatialInstance; if (this.SpatialFormatter.TryParse(property.Elements().First(), kind, out spatialInstance)) { ExceptionUtilities.Assert(property.Elements().Count() == 1, "Spatial property had more than 1 sub-element"); result = new PrimitiveProperty(propertyName, typeNameFromPayload, spatialInstance); } else if (property.Elements().All(e => e.Name == DataServicesElement)) { result = this.DeserializeCollectionProperty(property); } else { result = new ComplexProperty(propertyName, this.DeserializeComplexInstance(property)); } } else { // check for the null attribute bool isNull = false; XAttribute isNullAttribute = property.Attribute(MetadataNull); if (isNullAttribute != null) { isNull = bool.Parse(isNullAttribute.Value); } // If its null and we can't tell whether it is primitive or complex, then return a null marker if (isNull && clrType == null) { result = new NullPropertyInstance(propertyName, typeNameFromPayload); } else if (typeNameFromPayload != null && typeNameFromPayload.StartsWith(ODataConstants.BeginMultiValueTypeIdentifier, StringComparison.Ordinal)) { ExceptionUtilities.CheckObjectNotNull(this.PrimitiveDataTypeConverter, "Cannot infer clr type from edm type without converter"); string elementTypeName = ParseBagElementTypeName(typeNameFromPayload); if (this.PrimitiveDataTypeConverter.ToClrType(elementTypeName) != null) { result = new PrimitiveMultiValueProperty(propertyName, new PrimitiveMultiValue(typeNameFromPayload, isNull)); } else { result = new ComplexMultiValueProperty(propertyName, new ComplexMultiValue(typeNameFromPayload, isNull)); } } else { object value; if (isNull) { value = null; } else if (clrType != null) { ExceptionUtilities.CheckObjectNotNull(this.PrimitiveConverter, "PrimitiveConverter has not been set."); value = this.PrimitiveConverter.DeserializePrimitive(property.Value, clrType); } else { value = property.Value; } result = new PrimitiveProperty(propertyName, typeNameFromPayload, value); } } AddXmlBaseAnnotation(result, property); return(result); }
/// <summary> /// Deserializes the element as either a complex, a primitive, or a null property, based on the content /// </summary> /// <param name="property">The xml to deserialize</param> /// <param name="typeNameFallback">TypeName to use instead of the one from the XElement[type] attribute</param> /// <returns>A property representing the given xml</returns> private PropertyInstance DeserializeProperty(XElement property, string typeNameFallback) { string propertyName = property.Name.LocalName; // get the type name string typeNameFromPayload = null; XAttribute typeAttribute = property.Attribute(MetadataType); if (typeAttribute != null) { typeNameFromPayload = typeAttribute.Value; } // set type to be fallback when typeattribute does not exist var typeNameForClrTypeLookup = typeNameFromPayload; if (typeNameForClrTypeLookup == null && !string.IsNullOrEmpty(typeNameFallback)) { typeNameForClrTypeLookup = typeNameFallback; } // try to infer the clr type Type clrType = null; if (!string.IsNullOrEmpty(typeNameForClrTypeLookup)) { ExceptionUtilities.CheckObjectNotNull(this.PrimitiveDataTypeConverter, "Cannot infer clr type from edm type without converter"); clrType = this.PrimitiveDataTypeConverter.ToClrType(typeNameForClrTypeLookup); } PropertyInstance result; if (property.HasElements) { // must be complex, a multivalue, or spatial ExceptionUtilities.CheckObjectNotNull(this.SpatialFormatter, "Cannot safely deserialize element with children without spatial formatter."); // try to infer which spatial type hierarchy it is from the type name in the payload SpatialTypeKind? kind = null; if (clrType != null) { SpatialUtilities.TryInferSpatialTypeKind(clrType, out kind); } object spatialInstance; if (this.SpatialFormatter.TryParse(property.Elements().First(), kind, out spatialInstance)) { ExceptionUtilities.Assert(property.Elements().Count() == 1, "Spatial property had more than 1 sub-element"); result = new PrimitiveProperty(propertyName, typeNameFromPayload, spatialInstance); } else if (property.Elements().All(e => e.Name == DataServicesElement)) { result = this.DeserializeCollectionProperty(property); } else { result = new ComplexProperty(propertyName, this.DeserializeComplexInstance(property)); } } else { // check for the null attribute bool isNull = false; XAttribute isNullAttribute = property.Attribute(MetadataNull); if (isNullAttribute != null) { isNull = bool.Parse(isNullAttribute.Value); } // If its null and we can't tell whether it is primitive or complex, then return a null marker if (isNull && clrType == null) { result = new NullPropertyInstance(propertyName, typeNameFromPayload); } else if (typeNameFromPayload != null && typeNameFromPayload.StartsWith(ODataConstants.BeginMultiValueTypeIdentifier, StringComparison.Ordinal)) { ExceptionUtilities.CheckObjectNotNull(this.PrimitiveDataTypeConverter, "Cannot infer clr type from edm type without converter"); string elementTypeName = ParseBagElementTypeName(typeNameFromPayload); if (this.PrimitiveDataTypeConverter.ToClrType(elementTypeName) != null) { result = new PrimitiveMultiValueProperty(propertyName, new PrimitiveMultiValue(typeNameFromPayload, isNull)); } else { result = new ComplexMultiValueProperty(propertyName, new ComplexMultiValue(typeNameFromPayload, isNull)); } } else { object value; if (isNull) { value = null; } else if (clrType != null) { ExceptionUtilities.CheckObjectNotNull(this.PrimitiveConverter, "PrimitiveConverter has not been set."); value = this.PrimitiveConverter.DeserializePrimitive(property.Value, clrType); } else { value = property.Value; } result = new PrimitiveProperty(propertyName, typeNameFromPayload, value); } } AddXmlBaseAnnotation(result, property); return result; }
/// <summary> /// Visits a payload element whose root is a PrimitiveProperty. /// </summary> /// <param name="payloadElement">The root node of the payload element being visited.</param> public override void Visit(PrimitiveProperty payloadElement) { base.Visit(payloadElement); if (this.CurrentElementIsRoot()) { Func<MemberProperty, bool> matchesProperty = (p) => p.Name == payloadElement.Name && p.PropertyType is PrimitiveDataType && ((PrimitiveDataType)p.PropertyType).FullEdmName() == payloadElement.Value.FullTypeName; Func<IEdmProperty, bool> EdmMatchesProperty = (p) => p.Name == payloadElement.Name && p.DeclaringType as IEdmPrimitiveType != null && ((IEdmPrimitiveType)p).FullName() == payloadElement.Value.FullTypeName; var valueTypeAnnotation = payloadElement.Value.Annotations.OfType<EntityModelTypeAnnotation>().SingleOrDefault(); if (valueTypeAnnotation != null) { if (valueTypeAnnotation.EdmModelType != null) { var edmEntityType = valueTypeAnnotation.EdmModelType; this.AddExpectedTypeToProperty(payloadElement, edmEntityType, EdmMatchesProperty); } } else { var edmEntityType = this.ResolvePropertyEdmDataType(payloadElement.Value.FullTypeName); this.AddExpectedTypeToProperty(payloadElement, edmEntityType, EdmMatchesProperty); } } this.AnnotateIfOpenProperty(payloadElement, payloadElement.Value); }