public void ParameterJsonLightErrorTests() { IEdmModel model = Microsoft.Test.OData.Utils.Metadata.TestModels.BuildModelWithFunctionImport(); IEdmOperationImport functionImport = model.FindEntityContainer("TestContainer").FindOperationImports("FunctionImport_Primitive").First(); this.CombinatorialEngineProvider.RunCombinations( this.ReaderTestConfigurationProvider.JsonLightFormatConfigurations.Where(c => c.IsRequest), (testConfiguration) => { // Reading a Json parameter payload with an empty name should fail. ODataParameterReader reader = ParameterReaderTests.CreateODataParameterReader(model, functionImport, testConfiguration, "{ \"\" : \"foo\" }"); this.Assert.ExpectedException( () => reader.Read(), ODataExpectedExceptions.ODataException("JsonReader_InvalidPropertyNameOrUnexpectedComma", ""), this.ExceptionVerifier); this.Assert.AreEqual(ODataParameterReaderState.Exception, reader.State, "Reader should be in 'Exception' state."); reader = ParameterReaderTests.CreateODataParameterReader(model, functionImport, testConfiguration, "{ : \"foo\" }"); this.Assert.ExpectedException( () => reader.Read(), ODataExpectedExceptions.ODataException("JsonReader_InvalidPropertyNameOrUnexpectedComma", ""), this.ExceptionVerifier); this.Assert.AreEqual(ODataParameterReaderState.Exception, reader.State, "Reader should be in 'Exception' state."); reader = ParameterReaderTests.CreateODataParameterReader(model, functionImport, testConfiguration, "{ null : \"foo\" }"); this.Assert.ExpectedException( () => reader.Read(), ODataExpectedExceptions.ODataException("ODataParameterReaderCore_ParameterNameNotInMetadata", "null", functionImport.Name), this.ExceptionVerifier); this.Assert.AreEqual(ODataParameterReaderState.Exception, reader.State, "Reader should be in 'Exception' state."); }); }
public static IEnumerable <KeyValuePair <String, Object> > ParseJson(IEdmModel model, String skipToken, IEnumerable <IEdmStructuralProperty> keys) { using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(skipToken))) { IODataRequestMessage requestMessage = new OeInMemoryMessage(stream, null); using (ODataMessageReader messageReader = new ODataMessageReader(requestMessage, ReaderSettings, model)) { var operation = new EdmAction("", "", null); foreach (IEdmStructuralProperty key in keys) { operation.AddParameter(GetPropertyName(key), key.Type); } ODataParameterReader reader = messageReader.CreateODataParameterReader(operation); while (reader.Read()) { Object value = reader.Value; if (value is ODataEnumValue enumValue) { value = OeEdmClrHelper.GetValue(model, enumValue); } yield return(new KeyValuePair <String, Object>(reader.Name, value)); } } } }
private static OeSkipTokenNameValue[] ParseJson(IEdmModel model, String skipToken, IEdmStructuralProperty[] keys) { var skipTokenNameValues = new OeSkipTokenNameValue[keys.Length]; using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(skipToken))) { IODataRequestMessage requestMessage = new OeInMemoryMessage(stream, null); using (ODataMessageReader messageReader = new ODataMessageReader(requestMessage, ReaderSettings, model)) { var operation = new EdmAction("", "", null); foreach (IEdmStructuralProperty key in keys) { operation.AddParameter(GetPropertyName(key), key.Type); } ODataParameterReader reader = messageReader.CreateODataParameterReader(operation); int i = 0; while (reader.Read()) { Object value = reader.Value; if (value is ODataEnumValue enumValue) { value = OeEdmClrHelper.GetValue(model, enumValue); } skipTokenNameValues[i++] = new OeSkipTokenNameValue(reader.Name, value); } } } return(skipTokenNameValues); }
/// <summary> /// Reads the Action parameters payload and returns the WCF DS value representation of each parameter. /// </summary> /// <param name="segmentInfo">Info about the parameters payload to read.</param> /// <returns>The WCF DS representation of the parameters read.</returns> protected override object Read(SegmentInfo segmentInfo) { Debug.Assert(segmentInfo != null, "segmentInfo != null"); Debug.Assert( segmentInfo.TargetSource == RequestTargetSource.ServiceOperation && segmentInfo.Operation != null && segmentInfo.Operation.Kind == OperationKind.Action, "The ParametersDeserializer should only be called for an Action segment."); IEdmOperation operation = this.GetOperation(segmentInfo.Operation); ODataParameterReader reader = this.MessageReader.CreateODataParameterReader(operation); AssertReaderFormatIsExpected(this.MessageReader, ODataFormat.Json); Dictionary <string, object> parameters = new Dictionary <string, object>(EqualityComparer <string> .Default); ResourceType parameterResourceType; object convertedParameterValue; while (reader.Read()) { if (reader.State == ODataParameterReaderState.Completed) { break; } switch (reader.State) { case ODataParameterReaderState.Value: parameterResourceType = segmentInfo.Operation.Parameters.Single(p => p.Name == reader.Name).ParameterType; convertedParameterValue = this.ConvertValue(reader.Value, ref parameterResourceType); break; case ODataParameterReaderState.Collection: ODataCollectionReader collectionReader = reader.CreateCollectionReader(); parameterResourceType = segmentInfo.Operation.Parameters.Single(p => p.Name == reader.Name).ParameterType; Debug.Assert(parameterResourceType.ResourceTypeKind == ResourceTypeKind.Collection, "parameterResourceType.ResourceTypeKind == ResourceTypeKind.Collection"); convertedParameterValue = this.ConvertValue(ParameterDeserializer.ReadCollectionParameterValue(collectionReader), ref parameterResourceType); break; default: Debug.Assert(false, "Unreachable code path in Read()."); throw new InvalidOperationException(Microsoft.OData.Service.Strings.DataServiceException_GeneralError); } parameters.Add(reader.Name, convertedParameterValue); } // ODataLib allows nullable parameters to be missing from the payload. When that happens, we use null for the parameter value. foreach (IEdmOperationParameter parameterMetadata in operation.Parameters.Skip(operation.IsBound ? 1 : 0)) { object value; if (!parameters.TryGetValue(parameterMetadata.Name, out value)) { Debug.Assert(parameterMetadata.Type.IsNullable, "ODataParameterReader should only allows nullable parameters to be missing from the payload."); parameters.Add(parameterMetadata.Name, null); } } return(parameters); }
/// <summary> /// Constructor. /// </summary> /// <param name="parameterReader">The reader to wrap.</param> /// <param name="testConfiguration">The test configuration to use.</param> public ODataParameterReaderTestWrapper(ODataParameterReader parameterReader, ReaderTestConfiguration testConfiguration) { ExceptionUtilities.CheckArgumentNotNull(parameterReader, "parameterReader"); ExceptionUtilities.CheckArgumentNotNull(testConfiguration, "testConfiguration"); this.parameterReader = parameterReader; this.testConfiguration = testConfiguration; }
private static async Task ReadResourceSetAsync(IEdmAction action, ODataParameterReader reader, ODataDeserializerContext readContext, ODataDeserializerProvider deserializerProvider, Dictionary <string, object> payload) { string parameterName; IEdmCollectionTypeReference resourceSetType = GetCollectionParameterType(action, reader, out parameterName); object feed = await reader.CreateResourceSetReader().ReadResourceOrResourceSetAsync(); ProcessResourceSet(feed, resourceSetType, readContext, deserializerProvider, payload, parameterName); }
private static void ReadCollection(IEdmAction action, ODataParameterReader reader, ODataDeserializerContext readContext, ODataDeserializerProvider deserializerProvider, Dictionary <string, object> payload) { string parameterName; IEdmCollectionTypeReference collectionType = GetCollectionParameterType(action, reader, out parameterName); ODataCollectionValue value = ODataCollectionDeserializer.ReadCollection(reader.CreateCollectionReader()); ODataCollectionDeserializer collectionDeserializer = (ODataCollectionDeserializer)deserializerProvider.GetEdmTypeDeserializer(collectionType); payload[parameterName] = collectionDeserializer.ReadInline(value, collectionType, readContext); }
private static IEdmOperationParameter GetParameter(IEdmAction action, ODataParameterReader reader, out string parameterName) { string paramName = parameterName = reader.Name; IEdmOperationParameter parameter = action.Parameters.SingleOrDefault(p => p.Name == paramName); // ODataLib protects against this but asserting just in case. Contract.Assert(parameter != null, String.Format(CultureInfo.InvariantCulture, "Parameter '{0}' not found.", parameterName)); return(parameter); }
/// <summary> /// Reads Parameter names and values provided by a client in a POST request to invoke a particular Action. /// </summary> /// <param name="messageReader">Reader used to read all OData payloads (entries, feeds, metadata documents, service documents, etc.).</param> /// <param name="action">Represents an EDM operation.</param> /// <param name="readContext"> /// Encapsulates the state and settings that get passed to System.Web.OData.Formatter.Deserialization.ODataDeserializer from the System.Web.OData.Formatter.ODataMediaTypeFormatter. /// </param> /// <returns>ActionPayload holds the Parameter names and values provided by a client in a POST request to invoke a particular Action.</returns> private ODataActionParameters ReadParams(ODataMessageReader messageReader, IEdmOperation action, ODataDeserializerContext readContext) { // Create the correct resource type; ODataActionParameters payload = new ODataActionParameters(); try { ODataParameterReader reader = messageReader.CreateODataParameterReader(action); while (reader.Read()) { string parameterName = null; IEdmOperationParameter parameter = null; switch (reader.State) { case ODataParameterReaderState.Value: parameterName = reader.Name; parameter = action.Parameters.SingleOrDefault(p => p.Name == parameterName); // ODataLib protects against this but asserting just in case. Contract.Assert(parameter != null, String.Format(CultureInfo.InvariantCulture, "Parameter '{0}' not found.", parameterName)); if (parameter.Type.IsPrimitive()) { payload[parameterName] = reader.Value; } else { ODataEdmTypeDeserializer deserializer = DefaultODataDeserializerProvider.Instance.GetEdmTypeDeserializer(parameter.Type); payload[parameterName] = deserializer.ReadInline(reader.Value, parameter.Type, readContext); } break; case ODataParameterReaderState.Collection: parameterName = reader.Name; parameter = action.Parameters.SingleOrDefault(p => p.Name == parameterName); // ODataLib protects against this but asserting just in case. Contract.Assert(parameter != null, String.Format(CultureInfo.InvariantCulture, "Parameter '{0}' not found.", parameterName)); IEdmCollectionTypeReference collectionType = parameter.Type as IEdmCollectionTypeReference; Contract.Assert(collectionType != null); ODataCollectionValue value = ReadCollection(reader.CreateCollectionReader()); ODataCollectionDeserializer collectionDeserializer = DefaultODataDeserializerProvider.Instance.GetEdmTypeDeserializer(collectionType) as ODataCollectionDeserializer; payload[parameterName] = collectionDeserializer.ReadInline(value, collectionType, readContext); break; default: break; } } } catch (Exception exception) { DynamicLogger.Instance.WriteLoggerLogError("ReadParams", exception); throw; } return(payload); }
private static void FillParameters(IEdmModel edmModel, List <KeyValuePair <String, Object> > parameters, Stream requestStream, IEdmOperation operation, String contentType) { if (!operation.Parameters.Any()) { return; } IODataRequestMessage requestMessage = new Infrastructure.OeInMemoryMessage(requestStream, contentType); var settings = new ODataMessageReaderSettings() { EnableMessageStreamDisposal = false }; using (var messageReader = new ODataMessageReader(requestMessage, settings, edmModel)) { ODataParameterReader parameterReader = messageReader.CreateODataParameterReader(operation); while (parameterReader.Read()) { Object value; switch (parameterReader.State) { case ODataParameterReaderState.Value: { value = OeEdmClrHelper.GetValue(edmModel, parameterReader.Value); break; } case ODataParameterReaderState.Collection: { ODataCollectionReader collectionReader = parameterReader.CreateCollectionReader(); value = OeEdmClrHelper.GetValue(edmModel, ReadCollection(collectionReader)); break; } case ODataParameterReaderState.Resource: { ODataReader reader = parameterReader.CreateResourceReader(); value = OeEdmClrHelper.GetValue(edmModel, ReadResource(reader)); break; } case ODataParameterReaderState.ResourceSet: { ODataReader reader = parameterReader.CreateResourceSetReader(); value = OeEdmClrHelper.GetValue(edmModel, ReadResourceSet(reader)); break; } default: continue; } parameters.Add(new KeyValuePair <String, Object>(parameterReader.Name, value)); } } }
private static void ReadResource(IEdmAction action, ODataParameterReader reader, ODataDeserializerContext readContext, ODataDeserializerProvider deserializerProvider, Dictionary <string, object> payload) { string parameterName; IEdmOperationParameter parameter = GetParameter(action, reader, out parameterName); Contract.Assert(parameter.Type.IsStructured()); object item = reader.CreateResourceReader().ReadResourceOrResourceSet(); ODataResourceDeserializer resourceDeserializer = (ODataResourceDeserializer)deserializerProvider.GetEdmTypeDeserializer(parameter.Type); payload[parameterName] = resourceDeserializer.ReadInline(item, parameter.Type, readContext); }
private static void ReadValue(IEdmAction action, ODataParameterReader reader, ODataDeserializerContext readContext, ODataDeserializerProvider deserializerProvider, Dictionary <string, object> payload) { string parameterName; IEdmOperationParameter parameter = GetParameter(action, reader, out parameterName); if (parameter.Type.IsPrimitive()) { payload[parameterName] = reader.Value; } else { ODataEdmTypeDeserializer deserializer = deserializerProvider.GetEdmTypeDeserializer(parameter.Type); payload[parameterName] = deserializer.ReadInline(reader.Value, parameter.Type, readContext); } }
public void ParameterReaderAdditionalNullValueTest() { IEdmModel model = TestModels.BuildModelWithFunctionImport(); IEdmOperationImport functionImport_Complex = model.FindEntityContainer("TestContainer").FindOperationImports("FunctionImport_Complex").First(); IEdmOperationImport functionImport_PrimitiveCollection = model.FindEntityContainer("TestContainer").FindOperationImports("FunctionImport_PrimitiveCollection").First(); IEdmOperationImport functionImport_ComplexCollection = model.FindEntityContainer("TestContainer").FindOperationImports("FunctionImport_ComplexCollection").First(); var testConfigurations = this.ReaderTestConfigurationProvider.JsonLightFormatConfigurations.Where(c => c.IsRequest); this.CombinatorialEngineProvider.RunCombinations( testConfigurations, (testConfiguration) => { ODataParameterReader reader = this.CreateParameterReaderForRequestOrResponse(model, functionImport_PrimitiveCollection, testConfiguration, "{\"primitiveCollection\":null}"); reader.Read(); this.Assert.AreEqual("primitiveCollection", reader.Name, "Unexpected first parameter name."); this.Assert.IsNull(reader.Value, "Unexpected first parameter value."); this.Assert.AreEqual(ODataParameterReaderState.Value, reader.State, "Unexpected first parameter state."); reader = this.CreateParameterReaderForRequestOrResponse(model, functionImport_PrimitiveCollection, testConfiguration, "{\"primitiveCollection\":123}"); this.Assert.ExpectedException( () => reader.Read(), ODataExpectedExceptions.ODataException("ODataJsonLightParameterDeserializer_NullCollectionExpected", "PrimitiveValue", "123"), this.ExceptionVerifier); this.Assert.AreEqual(ODataParameterReaderState.Exception, reader.State, "Unexpected first parameter state."); reader = this.CreateParameterReaderForRequestOrResponse(model, functionImport_ComplexCollection, testConfiguration, "{\"complexCollection\":null}"); reader.Read(); this.Assert.AreEqual("complexCollection", reader.Name, "Unexpected first parameter name."); this.Assert.IsNull(reader.Value, "Unexpected first parameter value."); this.Assert.AreEqual(ODataParameterReaderState.Value, reader.State, "Unexpected first parameter state."); reader = this.CreateParameterReaderForRequestOrResponse(model, functionImport_ComplexCollection, testConfiguration, "{\"complexCollection\":123}"); this.Assert.ExpectedException( () => reader.Read(), ODataExpectedExceptions.ODataException("ODataJsonLightParameterDeserializer_NullCollectionExpected", "PrimitiveValue", "123"), this.ExceptionVerifier); this.Assert.AreEqual(ODataParameterReaderState.Exception, reader.State, "Unexpected first parameter state."); reader = this.CreateParameterReaderForRequestOrResponse(model, functionImport_Complex, testConfiguration, "{\"complex\":null}"); reader.Read(); this.Assert.AreEqual("complex", reader.Name, "Unexpected first parameter name."); this.Assert.IsNull(reader.Value, "Unexpected first parameter value."); this.Assert.AreEqual(ODataParameterReaderState.Resource, reader.State, "Unexpected first parameter state."); }); }
/// <inheritdoc /> public override object Read(ODataMessageReader messageReader, Type type, ODataDeserializerContext readContext) { if (messageReader == null) { throw Error.ArgumentNull("messageReader"); } // Create the correct resource type; ODataActionParameters payload = new ODataActionParameters(); IEdmFunctionImport action = GetFunctionImport(readContext); ODataParameterReader reader = messageReader.CreateODataParameterReader(action); while (reader.Read()) { string parameterName = null; IEdmFunctionParameter parameter = null; switch (reader.State) { case ODataParameterReaderState.Value: parameterName = reader.Name; parameter = action.Parameters.SingleOrDefault(p => p.Name == parameterName); // ODataLib protects against this but asserting just in case. Contract.Assert(parameter != null, String.Format(CultureInfo.InvariantCulture, "Parameter '{0}' not found.", parameterName)); payload[parameterName] = Convert(reader.Value, parameter.Type, readContext); break; case ODataParameterReaderState.Collection: parameterName = reader.Name; parameter = action.Parameters.SingleOrDefault(p => p.Name == parameterName); // ODataLib protects against this but asserting just in case. Contract.Assert(parameter != null, String.Format(CultureInfo.InvariantCulture, "Parameter '{0}' not found.", parameterName)); IEdmCollectionTypeReference collectionType = parameter.Type as IEdmCollectionTypeReference; Contract.Assert(collectionType != null); payload[parameterName] = Convert(reader.CreateCollectionReader(), collectionType, readContext); break; default: break; } } return(payload); }
private object CreateSubReader(ODataParameterReader parameterReader, CreateReaderMethods createMethod) { switch (createMethod) { case CreateReaderMethods.CreateResourceReader: return(parameterReader.CreateResourceReader()); case CreateReaderMethods.CreateResourceSetReader: return(parameterReader.CreateResourceSetReader()); case CreateReaderMethods.CreateCollectionReader: return(parameterReader.CreateCollectionReader()); default: throw new NotSupportedException("Unsupported create method: " + createMethod); } }
protected override object Read(System.Data.Services.SegmentInfo segmentInfo) { Func <OperationParameter, bool> predicate = null; Func <OperationParameter, bool> func2 = null; IEdmFunctionImport functionImport = base.GetFunctionImport(segmentInfo.Operation); ODataParameterReader reader = base.MessageReader.CreateODataParameterReader(functionImport); Dictionary <string, object> dictionary = new Dictionary <string, object>(EqualityComparer <string> .Default); while (reader.Read()) { ResourceType parameterType; object obj2; switch (reader.State) { case ODataParameterReaderState.Value: if (predicate == null) { predicate = p => p.Name == reader.Name; } parameterType = segmentInfo.Operation.Parameters.Single <OperationParameter>(predicate).ParameterType; obj2 = base.ConvertValue(reader.Value, ref parameterType); break; case ODataParameterReaderState.Collection: { ODataCollectionReader collectionReader = reader.CreateCollectionReader(); if (func2 == null) { func2 = p => p.Name == reader.Name; } parameterType = segmentInfo.Operation.Parameters.Single <OperationParameter>(func2).ParameterType; obj2 = base.ConvertValue(ReadCollectionParameterValue(collectionReader), ref parameterType); break; } case ODataParameterReaderState.Completed: return(dictionary); default: throw new InvalidOperationException(System.Data.Services.Strings.DataServiceException_GeneralError); } dictionary.Add(reader.Name, obj2); } return(dictionary); }
public override async Task <object> ReadAsync(ODataMessageReader messageReader, Type type, ODataDeserializerContext readContext) { if (messageReader == null) { throw Error.ArgumentNull("messageReader"); } IEdmAction action = GetAction(readContext); Contract.Assert(action != null); // Create the correct resource type; Dictionary <string, object> payload = GetPayload(type, action); ODataParameterReader reader = await messageReader.CreateODataParameterReaderAsync(action); while (await reader.ReadAsync()) { switch (reader.State) { case ODataParameterReaderState.Value: ReadValue(action, reader, readContext, DeserializerProvider, payload); break; case ODataParameterReaderState.Collection: await ReadCollectionAsync(action, reader, readContext, DeserializerProvider, payload); break; case ODataParameterReaderState.Resource: await ReadResourceAsync(action, reader, readContext, DeserializerProvider, payload); break; case ODataParameterReaderState.ResourceSet: await ReadResourceSetAsync(action, reader, readContext, DeserializerProvider, payload); break; } } return(payload); }
private static OeSkipTokenNameValue[] ParseJson(IEdmModel edmModel, String skipToken, IEdmStructuralProperty[] keys, out int?restCount) { restCount = null; var skipTokenNameValues = new OeSkipTokenNameValue[keys.Length]; using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(skipToken))) { IODataRequestMessage requestMessage = new Infrastructure.OeInMemoryMessage(stream, null); using (ODataMessageReader messageReader = new ODataMessageReader(requestMessage, ReaderSettings, edmModel)) { var operation = new EdmAction("", "", null); foreach (IEdmStructuralProperty key in keys) { operation.AddParameter(GetPropertyName(key), key.Type); } operation.AddParameter(RestCountName, OeEdmClrHelper.GetEdmTypeReference(edmModel, typeof(int?))); ODataParameterReader reader = messageReader.CreateODataParameterReader(operation); int i = 0; while (reader.Read()) { Object value = reader.Value; if (value is ODataEnumValue enumValue) { value = OeEdmClrHelper.GetValue(edmModel, enumValue); } if (reader.Name == RestCountName) { restCount = (int)value; } else { skipTokenNameValues[i++] = new OeSkipTokenNameValue(reader.Name, value); } } } } return(skipTokenNameValues); }
/// <inheritdoc /> public override object Read(ODataMessageReader messageReader, Type type, ODataDeserializerContext readContext) { if (messageReader == null) { throw Error.ArgumentNull("messageReader"); } IEdmFunctionImport action = GetFunctionImport(readContext); // Create the correct resource type; Dictionary <string, object> payload; if (type == typeof(ODataActionParameters)) { payload = new ODataActionParameters(); } else { payload = new ODataUntypedActionParameters(action); } ODataParameterReader reader = messageReader.CreateODataParameterReader(action); while (reader.Read()) { string parameterName = null; IEdmFunctionParameter parameter = null; switch (reader.State) { case ODataParameterReaderState.Value: parameterName = reader.Name; parameter = action.Parameters.SingleOrDefault(p => p.Name == parameterName); // ODataLib protects against this but asserting just in case. Contract.Assert(parameter != null, String.Format(CultureInfo.InvariantCulture, "Parameter '{0}' not found.", parameterName)); if (parameter.Type.IsPrimitive()) { payload[parameterName] = reader.Value; } else { ODataEdmTypeDeserializer deserializer = DeserializerProvider.GetEdmTypeDeserializer(parameter.Type); payload[parameterName] = deserializer.ReadInline(reader.Value, parameter.Type, readContext); } break; case ODataParameterReaderState.Collection: parameterName = reader.Name; parameter = action.Parameters.SingleOrDefault(p => p.Name == parameterName); // ODataLib protects against this but asserting just in case. Contract.Assert(parameter != null, String.Format(CultureInfo.InvariantCulture, "Parameter '{0}' not found.", parameterName)); IEdmCollectionTypeReference collectionType = parameter.Type as IEdmCollectionTypeReference; Contract.Assert(collectionType != null); ODataCollectionValue value = ODataCollectionDeserializer.ReadCollection(reader.CreateCollectionReader()); ODataCollectionDeserializer collectionDeserializer = DeserializerProvider.GetEdmTypeDeserializer(collectionType) as ODataCollectionDeserializer; payload[parameterName] = collectionDeserializer.ReadInline(value, collectionType, readContext); break; default: break; } } return(payload); }
public override object Read(ODataMessageReader messageReader, Type type, ODataDeserializerContext readContext) { if (messageReader == null) { throw Error.ArgumentNull("messageReader"); } IEdmAction action = GetAction(readContext); Contract.Assert(action != null); // Create the correct resource type; Dictionary <string, object> payload; if (type == typeof(ODataActionParameters)) { payload = new ODataActionParameters(); } else { payload = new ODataUntypedActionParameters(action); } ODataParameterReader reader = messageReader.CreateODataParameterReader(action); while (reader.Read()) { string parameterName = null; IEdmOperationParameter parameter = null; switch (reader.State) { case ODataParameterReaderState.Value: parameterName = reader.Name; parameter = action.Parameters.SingleOrDefault(p => p.Name == parameterName); // ODataLib protects against this but asserting just in case. Contract.Assert(parameter != null, String.Format(CultureInfo.InvariantCulture, "Parameter '{0}' not found.", parameterName)); if (parameter.Type.IsPrimitive()) { payload[parameterName] = reader.Value; } else { ODataEdmTypeDeserializer deserializer = DeserializerProvider.GetEdmTypeDeserializer(parameter.Type); payload[parameterName] = deserializer.ReadInline(reader.Value, parameter.Type, readContext); } break; case ODataParameterReaderState.Collection: parameterName = reader.Name; parameter = action.Parameters.SingleOrDefault(p => p.Name == parameterName); // ODataLib protects against this but asserting just in case. Contract.Assert(parameter != null, String.Format(CultureInfo.InvariantCulture, "Parameter '{0}' not found.", parameterName)); IEdmCollectionTypeReference collectionType = parameter.Type as IEdmCollectionTypeReference; Contract.Assert(collectionType != null); ODataCollectionValue value = ReadCollection(reader.CreateCollectionReader()); ODataCollectionDeserializer collectionDeserializer = (ODataCollectionDeserializer)DeserializerProvider.GetEdmTypeDeserializer(collectionType); payload[parameterName] = collectionDeserializer.ReadInline(value, collectionType, readContext); break; case ODataParameterReaderState.Entry: parameterName = reader.Name; parameter = action.Parameters.SingleOrDefault(p => p.Name == parameterName); Contract.Assert(parameter != null, String.Format(CultureInfo.InvariantCulture, "Parameter '{0}' not found.", parameterName)); IEdmEntityTypeReference entityTypeReference = parameter.Type as IEdmEntityTypeReference; Contract.Assert(entityTypeReference != null); ODataReader entryReader = reader.CreateEntryReader(); object item = ODataEntityDeserializer.ReadEntryOrFeed(entryReader); var savedProps = new List <ODataProperty>(); if (item is ODataEntryWithNavigationLinks) { var obj = CreateDataObject(readContext.Model as DataObjectEdmModel, entityTypeReference, item as ODataEntryWithNavigationLinks, out Type objType); payload[parameterName] = obj; break; } ODataEntityDeserializer entityDeserializer = (ODataEntityDeserializer)DeserializerProvider.GetEdmTypeDeserializer(entityTypeReference); payload[parameterName] = entityDeserializer.ReadInline(item, entityTypeReference, readContext); break; case ODataParameterReaderState.Feed: parameterName = reader.Name; parameter = action.Parameters.SingleOrDefault(p => p.Name == parameterName); Contract.Assert(parameter != null, String.Format(CultureInfo.InvariantCulture, "Parameter '{0}' not found.", parameterName)); IEdmCollectionTypeReference feedType = parameter.Type as IEdmCollectionTypeReference; Contract.Assert(feedType != null); ODataReader feedReader = reader.CreateFeedReader(); object feed = ODataEntityDeserializer.ReadEntryOrFeed(feedReader); IEnumerable enumerable; ODataFeedWithEntries odataFeedWithEntries = feed as ODataFeedWithEntries; if (odataFeedWithEntries != null) { List <DataObject> list = new List <DataObject>(); Type objType = null; foreach (ODataEntryWithNavigationLinks entry in odataFeedWithEntries.Entries) { list.Add(CreateDataObject(readContext.Model as DataObjectEdmModel, feedType.ElementType() as IEdmEntityTypeReference, entry, out objType)); } IEnumerable castedResult = _castMethodInfo.MakeGenericMethod(objType) .Invoke(null, new[] { list }) as IEnumerable; payload[parameterName] = castedResult; break; } ODataFeedDeserializer feedDeserializer = (ODataFeedDeserializer)DeserializerProvider.GetEdmTypeDeserializer(feedType); object result = feedDeserializer.ReadInline(feed, feedType, readContext); IEdmTypeReference elementTypeReference = feedType.ElementType(); Contract.Assert(elementTypeReference.IsEntity()); enumerable = result as IEnumerable; if (enumerable != null) { var isUntypedProp = readContext.GetType().GetProperty("IsUntyped", BindingFlags.NonPublic | BindingFlags.Instance); bool isUntyped = (bool)isUntypedProp.GetValue(readContext, null); if (isUntyped) { EdmEntityObjectCollection entityCollection = new EdmEntityObjectCollection(feedType); foreach (EdmEntityObject entityObject in enumerable) { entityCollection.Add(entityObject); } payload[parameterName] = entityCollection; } else { Type elementClrType = EdmLibHelpers.GetClrType(elementTypeReference, readContext.Model); IEnumerable castedResult = _castMethodInfo.MakeGenericMethod(elementClrType) .Invoke(null, new[] { result }) as IEnumerable; payload[parameterName] = castedResult; } } break; } } return(payload); }
private static IEdmCollectionTypeReference GetCollectionParameterType(IEdmAction action, ODataParameterReader reader, out string parameterName) { IEdmOperationParameter parameter = GetParameter(action, reader, out parameterName); IEdmCollectionTypeReference collectionType = parameter.Type as IEdmCollectionTypeReference; Contract.Assert(collectionType != null); return(collectionType); }
public override object Read(ODataMessageReader messageReader, Type type, ODataDeserializerContext readContext) { if (messageReader == null) { throw Error.ArgumentNull("messageReader"); } IEdmAction action = GetAction(readContext); Contract.Assert(action != null); // Create the correct resource type; Dictionary <string, object> payload; if (type == typeof(ODataActionParameters)) { payload = new ODataActionParameters(); } else { payload = new ODataUntypedActionParameters(action); } ODataParameterReader reader = messageReader.CreateODataParameterReader(action); while (reader.Read()) { string parameterName = null; IEdmOperationParameter parameter = null; switch (reader.State) { case ODataParameterReaderState.Value: parameterName = reader.Name; parameter = action.Parameters.SingleOrDefault(p => p.Name == parameterName); // ODataLib protects against this but asserting just in case. Contract.Assert(parameter != null, String.Format(CultureInfo.InvariantCulture, "Parameter '{0}' not found.", parameterName)); if (parameter.Type.IsPrimitive()) { payload[parameterName] = reader.Value; } else { ODataEdmTypeDeserializer deserializer = DeserializerProvider.GetEdmTypeDeserializer(parameter.Type); payload[parameterName] = deserializer.ReadInline(reader.Value, parameter.Type, readContext); } break; case ODataParameterReaderState.Collection: parameterName = reader.Name; parameter = action.Parameters.SingleOrDefault(p => p.Name == parameterName); // ODataLib protects against this but asserting just in case. Contract.Assert(parameter != null, String.Format(CultureInfo.InvariantCulture, "Parameter '{0}' not found.", parameterName)); IEdmCollectionTypeReference collectionType = parameter.Type as IEdmCollectionTypeReference; Contract.Assert(collectionType != null); ODataCollectionValue value = ODataCollectionDeserializer.ReadCollection(reader.CreateCollectionReader()); ODataCollectionDeserializer collectionDeserializer = (ODataCollectionDeserializer)DeserializerProvider.GetEdmTypeDeserializer(collectionType); payload[parameterName] = collectionDeserializer.ReadInline(value, collectionType, readContext); break; case ODataParameterReaderState.Resource: parameterName = reader.Name; parameter = action.Parameters.SingleOrDefault(p => p.Name == parameterName); Contract.Assert(parameter != null, String.Format(CultureInfo.InvariantCulture, "Parameter '{0}' not found.", parameterName)); Contract.Assert(parameter.Type.IsStructured()); ODataReader resourceReader = reader.CreateResourceReader(); object item = resourceReader.ReadResourceOrResourceSet(); ODataResourceDeserializer resourceDeserializer = (ODataResourceDeserializer)DeserializerProvider.GetEdmTypeDeserializer(parameter.Type); payload[parameterName] = resourceDeserializer.ReadInline(item, parameter.Type, readContext); break; case ODataParameterReaderState.ResourceSet: parameterName = reader.Name; parameter = action.Parameters.SingleOrDefault(p => p.Name == parameterName); Contract.Assert(parameter != null, String.Format(CultureInfo.InvariantCulture, "Parameter '{0}' not found.", parameterName)); IEdmCollectionTypeReference resourceSetType = parameter.Type as IEdmCollectionTypeReference; Contract.Assert(resourceSetType != null); ODataReader resourceSetReader = reader.CreateResourceSetReader(); object feed = resourceSetReader.ReadResourceOrResourceSet(); ODataResourceSetDeserializer resourceSetDeserializer = (ODataResourceSetDeserializer)DeserializerProvider.GetEdmTypeDeserializer(resourceSetType); object result = resourceSetDeserializer.ReadInline(feed, resourceSetType, readContext); IEdmTypeReference elementTypeReference = resourceSetType.ElementType(); Contract.Assert(elementTypeReference.IsStructured()); IEnumerable enumerable = result as IEnumerable; if (enumerable != null) { if (readContext.IsUntyped) { payload[parameterName] = enumerable.ConvertToEdmObject(resourceSetType); } else { Type elementClrType = EdmLibHelpers.GetClrType(elementTypeReference, readContext.Model); IEnumerable castedResult = _castMethodInfo.MakeGenericMethod(elementClrType) .Invoke(null, new[] { result }) as IEnumerable; payload[parameterName] = castedResult; } } break; } } return(payload); }
public void ParameterReaderCreateReaderStateMachineTests() { IEdmModel model = TestModels.BuildModelWithFunctionImport(); IEdmOperationImport functionImport_Primitive = model.FindEntityContainer("TestContainer").FindOperationImports("FunctionImport_Primitive").First(); IEdmOperationImport functionImport_PrimitiveCollection = model.FindEntityContainer("TestContainer").FindOperationImports("FunctionImport_PrimitiveCollection").First(); IEdmOperationImport functionImport_Complex = model.FindEntityContainer("TestContainer").FindOperationImports("FunctionImport_Complex").First(); IEdmOperationImport functionImport_ComplexCollection = model.FindEntityContainer("TestContainer").FindOperationImports("FunctionImport_ComplexCollection").First(); IEdmOperationImport functionImport_Entry = model.FindEntityContainer("TestContainer").FindOperationImports("FunctionImport_Entry").First(); IEdmOperationImport functionImport_Feed = model.FindEntityContainer("TestContainer").FindOperationImports("FunctionImport_Feed").First(); CreateReaderMethods[] createReaderMethods = new CreateReaderMethods[] { CreateReaderMethods.CreateCollectionReader, }; var testConfigurations = this.ReaderTestConfigurationProvider.JsonLightFormatConfigurations.Where(c => c.IsRequest); this.CombinatorialEngineProvider.RunCombinations( testConfigurations, createReaderMethods, (testConfiguration, createReaderMethod) => { // Calling Create*Reader in Start state should fail. ODataParameterReader reader = this.CreateParameterReaderForRequestOrResponse(model, functionImport_Complex, testConfiguration, "{ complex : { PrimitiveProperty : \"456\" } }"); this.Assert.ExpectedException( () => CreateSubReader(reader, createReaderMethod), ODataExpectedExceptions.ODataException("ODataParameterReaderCore_InvalidCreateReaderMethodCalledForState", createReaderMethod.ToString(), ODataParameterReaderState.Start.ToString()), this.ExceptionVerifier); this.Assert.AreEqual(ODataParameterReaderState.Start, reader.State, "Unexpected parameter reader state."); // Calling Create*Reader in Value state should fail. reader.Read(); this.Assert.AreEqual(ODataParameterReaderState.Resource, reader.State, "Unexpected parameter reader state."); this.Assert.ExpectedException( () => CreateSubReader(reader, createReaderMethod), ODataExpectedExceptions.ODataException("ODataParameterReaderCore_InvalidCreateReaderMethodCalledForState", createReaderMethod.ToString(), ODataParameterReaderState.Resource.ToString()), this.ExceptionVerifier); this.Assert.AreEqual(ODataParameterReaderState.Resource, reader.State, "Unexpected parameter reader state."); if (createReaderMethod != CreateReaderMethods.CreateResourceReader) { // Calling Create*Reader in Entry state should fail. reader = this.CreateParameterReaderForRequestOrResponse(model, functionImport_Entry, testConfiguration, "{ entry : {} }"); reader.Read(); this.Assert.AreEqual(ODataParameterReaderState.Resource, reader.State, "Unexpected parameter reader state."); this.Assert.ExpectedException( () => CreateSubReader(reader, createReaderMethod), ODataExpectedExceptions.ODataException("ODataParameterReaderCore_InvalidCreateReaderMethodCalledForState", createReaderMethod.ToString(), ODataParameterReaderState.Resource.ToString()), this.ExceptionVerifier); this.Assert.AreEqual(ODataParameterReaderState.Resource, reader.State, "Unexpected parameter reader state."); } if (createReaderMethod != CreateReaderMethods.CreateResourceSetReader) { // Calling Create*Reader in Feed state should fail. reader = this.CreateParameterReaderForRequestOrResponse(model, functionImport_Feed, testConfiguration, "{ feed : [] }"); reader.Read(); this.Assert.AreEqual(ODataParameterReaderState.ResourceSet, reader.State, "Unexpected parameter reader state."); this.Assert.ExpectedException( () => CreateSubReader(reader, createReaderMethod), ODataExpectedExceptions.ODataException("ODataParameterReaderCore_InvalidCreateReaderMethodCalledForState", createReaderMethod.ToString(), ODataParameterReaderState.ResourceSet.ToString()), this.ExceptionVerifier); this.Assert.AreEqual(ODataParameterReaderState.ResourceSet, reader.State, "Unexpected parameter reader state."); } if (createReaderMethod != CreateReaderMethods.CreateCollectionReader) { // Calling Create*Reader in Collection state should fail. reader = this.CreateParameterReaderForRequestOrResponse(model, functionImport_ComplexCollection, testConfiguration, "{ complexCollection : [] }"); reader.Read(); this.Assert.AreEqual(ODataParameterReaderState.Collection, reader.State, "Unexpected parameter reader state."); this.Assert.ExpectedException( () => CreateSubReader(reader, createReaderMethod), ODataExpectedExceptions.ODataException("ODataParameterReaderCore_InvalidCreateReaderMethodCalledForState", createReaderMethod.ToString(), ODataParameterReaderState.Collection.ToString()), this.ExceptionVerifier); this.Assert.AreEqual(ODataParameterReaderState.Collection, reader.State, "Unexpected parameter reader state."); } // Calling Read() in Entry/Feed/Collection state without calling Create***Reader should fail. IEdmOperationImport functionImport = createReaderMethod == CreateReaderMethods.CreateResourceReader ? functionImport_Entry : (createReaderMethod == CreateReaderMethods.CreateResourceSetReader ? functionImport_Feed : functionImport_ComplexCollection); string payload = createReaderMethod == CreateReaderMethods.CreateResourceReader ? "{ entry : {} }" : (createReaderMethod == CreateReaderMethods.CreateResourceSetReader ? "{ feed : [] }" : "{ complexCollection : [] }"); ODataParameterReaderState expectedParameterState = createReaderMethod == CreateReaderMethods.CreateResourceReader ? ODataParameterReaderState.Resource : ODataParameterReaderState.ResourceSet; var expectedReaderMethod = createReaderMethod == CreateReaderMethods.CreateCollectionReader ? CreateReaderMethods.CreateResourceSetReader.ToString() : createReaderMethod.ToString(); reader = this.CreateParameterReaderForRequestOrResponse(model, functionImport, testConfiguration, payload); reader.Read(); this.Assert.AreEqual(expectedParameterState, reader.State, "Unexpected parameter reader state."); this.Assert.ExpectedException( () => reader.Read(), ODataExpectedExceptions.ODataException("ODataParameterReaderCore_SubReaderMustBeCreatedAndReadToCompletionBeforeTheNextReadOrReadAsyncCall", expectedParameterState.ToString(), expectedReaderMethod), this.ExceptionVerifier); this.Assert.AreEqual(expectedParameterState, reader.State, "Unexpected parameter reader state."); // Calling Read() in Entry/Feed/Collection state after Create***Reader() is called but before the created reader finishes should fail. var subReaderMethod = createReaderMethod == CreateReaderMethods.CreateCollectionReader ? CreateReaderMethods.CreateResourceSetReader : createReaderMethod; object subReader = CreateSubReader(reader, subReaderMethod); this.Assert.ExpectedException( () => reader.Read(), ODataExpectedExceptions.ODataException("ODataParameterReaderCore_SubReaderMustBeInCompletedStateBeforeTheNextReadOrReadAsyncCall", expectedParameterState.ToString(), expectedReaderMethod), this.ExceptionVerifier); this.Assert.AreEqual(expectedParameterState, reader.State, "Unexpected parameter reader state."); // Calling Create*Reader() before the sub-reader is completed should fail. string parameterName = createReaderMethod == CreateReaderMethods.CreateResourceReader ? "entry" : (createReaderMethod == CreateReaderMethods.CreateResourceSetReader ? "feed" : "complexCollection"); subReader.GetType().GetMethod("Read").Invoke(subReader, null); this.Assert.ExpectedException( () => CreateSubReader(reader, subReaderMethod), ODataExpectedExceptions.ODataException("ODataParameterReaderCore_CreateReaderAlreadyCalled", expectedReaderMethod, parameterName), this.ExceptionVerifier); this.Assert.AreEqual(expectedParameterState, reader.State, "Unexpected parameter reader state."); // Calling Create*Reader() after sub-reader is completed should fail. while ((bool)subReader.GetType().GetMethod("Read").Invoke(subReader, null)) { ; } this.Assert.AreEqual("Completed", subReader.GetType().GetProperty("State").GetValue(subReader, null).ToString(), "Unexpected sub-reader state."); this.Assert.ExpectedException( () => CreateSubReader(reader, subReaderMethod), ODataExpectedExceptions.ODataException("ODataParameterReaderCore_CreateReaderAlreadyCalled", expectedReaderMethod, parameterName), this.ExceptionVerifier); this.Assert.AreEqual(expectedParameterState, reader.State, "Unexpected parameter reader state."); // Finish reading... reader.Read(); this.Assert.AreEqual(ODataParameterReaderState.Completed, reader.State, "Unexpected parameter reader state."); // Calling Create*Reader in Completed state should fail. this.Assert.ExpectedException( () => CreateSubReader(reader, subReaderMethod), ODataExpectedExceptions.ODataException("ODataParameterReaderCore_InvalidCreateReaderMethodCalledForState", expectedReaderMethod, ODataParameterReaderState.Completed.ToString()), this.ExceptionVerifier); this.Assert.AreEqual(ODataParameterReaderState.Completed, reader.State, "Unexpected parameter reader state."); // Exception in subReader should put parent reader in Exception state. payload = createReaderMethod == CreateReaderMethods.CreateResourceReader ? "{ entry : \"foo\" }" : (createReaderMethod == CreateReaderMethods.CreateResourceSetReader ? "{ feed : { \"foo\" : \"bar\" } }" : "{ complexCollection : { \"foo\" : \"bar\" } }"); reader = this.CreateParameterReaderForRequestOrResponse(model, functionImport, testConfiguration, payload); reader.Read(); this.Assert.AreEqual(expectedParameterState, reader.State, "Unexpected parameter reader state."); subReader = CreateSubReader(reader, subReaderMethod); this.Assert.IsNotNull(TestExceptionUtils.RunCatching(() => { while ((bool)subReader.GetType().GetMethod("Read").Invoke(subReader, null)) { } }), "Expecting sub-reader.Read() to fail."); this.Assert.AreEqual("Exception", subReader.GetType().GetProperty("State").GetValue(subReader, null).ToString(), "Unexpected sub-reader state."); this.Assert.AreEqual(ODataParameterReaderState.Exception, reader.State, "Unexpected parameter reader state."); // Calling Create*Reader in Exception state should fail. this.Assert.ExpectedException( () => CreateSubReader(reader, subReaderMethod), ODataExpectedExceptions.ODataException("ODataParameterReaderCore_InvalidCreateReaderMethodCalledForState", expectedReaderMethod, ODataParameterReaderState.Exception.ToString()), this.ExceptionVerifier); this.Assert.AreEqual(ODataParameterReaderState.Exception, reader.State, "Unexpected parameter reader state."); }); }