protected void EnterScope(ODataParameterReaderState state, string name, object value) { if (((state == ODataParameterReaderState.Value) && (value != null)) && (!(value is ODataComplexValue) && !EdmLibraryExtensions.IsPrimitiveType(value.GetType()))) { throw new ODataException(Microsoft.Data.OData.Strings.General_InternalError(InternalErrorCodes.ODataParameterReaderCore_ValueMustBePrimitiveOrComplexOrNull)); } if ((this.scopes.Count == 0) || (this.State != ODataParameterReaderState.Exception)) { if (state == ODataParameterReaderState.Completed) { List <string> list = new List <string>(); foreach (IEdmFunctionParameter parameter in this.FunctionImport.Parameters.Skip <IEdmFunctionParameter>(this.FunctionImport.IsBindable ? 1 : 0)) { if (!this.parametersRead.Contains(parameter.Name)) { list.Add(parameter.Name); } } if (list.Count > 0) { this.scopes.Push(new Scope(ODataParameterReaderState.Exception, null, null)); throw new ODataException(Microsoft.Data.OData.Strings.ODataParameterReaderCore_ParametersMissingInPayload(this.FunctionImport.Name, string.Join(",", list.ToArray()))); } } this.scopes.Push(new Scope(state, name, value)); } }
public override bool Read() { switch (this.State) { case ODataParameterReaderState.Start: if (!this.inputContext.AvroReader.MoveNext()) { this.state = ODataParameterReaderState.Completed; return false; } this.avroRecord = this.inputContext.AvroReader.Current as AvroRecord; if (this.avroRecord == null) { this.state = ODataParameterReaderState.Exception; return false; } this.enumerator = this.avroRecord.Schema.Fields.GetEnumerator(); return this.UpdateState(); case ODataParameterReaderState.Value: case ODataParameterReaderState.Entry: case ODataParameterReaderState.Feed: return this.UpdateState(); default: throw new ApplicationException("Invalid state " + this.State); } }
/// <summary> /// Creates a new <see cref="Scope"/> for the specified <paramref name="state"/> with the provided /// <paramref name="name"/> and <paramref name="value"/> and pushes it on the stack of scopes. /// </summary> /// <param name="state">The <see cref="ODataParameterReaderState"/> to use for the new scope.</param> /// <param name="name">The parameter name to attach with the state in the new scope.</param> /// <param name="value">The parameter value to attach with the state in the new scope.</param> protected internal void EnterScope(ODataParameterReaderState state, string name, object value) { if (state == ODataParameterReaderState.Value) { if (value != null && !EdmLibraryExtensions.IsPrimitiveType(value.GetType()) && !(value is ODataEnumValue)) { throw new ODataException(Strings.General_InternalError(InternalErrorCodes.ODataParameterReaderCore_ValueMustBePrimitiveOrNull)); } } Debug.Assert(this.scopes.Count == 0 || this.State != ODataParameterReaderState.Exception || state == ODataParameterReaderState.Exception, "If the reader is already in Exception state, we shouldn't call EnterScope() except for another Exception."); // We only need to enter the exception state once. if (this.scopes.Count == 0 || this.State != ODataParameterReaderState.Exception) { Debug.Assert( state == ODataParameterReaderState.Exception || state == ODataParameterReaderState.Start && this.scopes.Count == 0 || state == ODataParameterReaderState.Completed && this.scopes.Count == 0 || this.scopes.Count == 1 && this.scopes.Peek().State == ODataParameterReaderState.Start, "Unexpected state in the scopes stack."); // Make sure there aren't any missing parameter in the payload. if (state == ODataParameterReaderState.Completed) { List <string> missingParameters = new List <string>(); // Note that the binding parameter will be specified on the Uri rather than the payload, skip the binding parameter. foreach (IEdmOperationParameter parameter in this.Operation.Parameters.Skip(this.Operation.IsBound ? 1 : 0)) { // only check the non-optional parameter if (!(parameter is IEdmOptionalParameter)) { if (!this.parametersRead.Contains(parameter.Name) && !this.inputContext.EdmTypeResolver.GetParameterType(parameter).IsNullable) { missingParameters.Add(parameter.Name); } } } if (missingParameters.Count > 0) { this.scopes.Push(new Scope(ODataParameterReaderState.Exception, null, null)); throw new ODataException(Strings.ODataParameterReaderCore_ParametersMissingInPayload(this.Operation.Name, string.Join(",", missingParameters.ToArray()))); } } else if (name != null) { // Record the parameter names we read and check for duplicates. if (this.parametersRead.Contains(name)) { throw new ODataException(Strings.ODataParameterReaderCore_DuplicateParametersInPayload(name)); } this.parametersRead.Add(name); } this.scopes.Push(new Scope(state, name, value)); } }
public override bool Read() { switch (this.State) { case ODataParameterReaderState.Start: if (!this.inputContext.AvroReader.MoveNext()) { this.state = ODataParameterReaderState.Completed; return(false); } this.avroRecord = this.inputContext.AvroReader.Current as AvroRecord; if (this.avroRecord == null) { this.state = ODataParameterReaderState.Exception; return(false); } this.enumerator = this.avroRecord.Schema.Fields.GetEnumerator(); return(this.UpdateState()); case ODataParameterReaderState.Value: case ODataParameterReaderState.Resource: case ODataParameterReaderState.ResourceSet: return(this.UpdateState()); default: throw new ApplicationException("Invalid state " + this.State); } }
protected internal void PopScope(ODataParameterReaderState state) { Debug.Assert(this.scopes.Count > 0, "Stack must have more than 1 items in order to pop an item."); Scope scope = this.scopes.Pop(); Debug.Assert(scope.State == state, "scope.State == state"); }
public ODataAvroParameterReader(ODataAvroInputContext inputContext, IEdmOperation operation) { Debug.Assert(inputContext != null, "inputContext != null"); Debug.Assert(operation != null, "operation != null"); this.inputContext = inputContext; this.operation = operation; this.state = ODataParameterReaderState.Start; }
/// <summary> /// Gets the corresponding create reader method name for the given state. /// </summary> /// <param name="state">State in question.</param> /// <returns>Returns the name of the method to create the correct reader for the given state.</returns> private static string GetCreateReaderMethodName(ODataParameterReaderState state) { #if SUPPORT_ENTITY_PARAMETER Debug.Assert(state == ODataParameterReaderState.Entry || state == ODataParameterReaderState.Feed || state == ODataParameterReaderState.Collection, "state must be Entry, Feed or Collection."); #else Debug.Assert(state == ODataParameterReaderState.Collection, "state must be Collection."); #endif return("Create" + state.ToString() + "Reader"); }
private void VerifyCanCreateSubReader(ODataParameterReaderState expectedState) { this.inputContext.VerifyNotDisposed(); if (this.State != expectedState) { throw new ODataException(Microsoft.Data.OData.Strings.ODataParameterReaderCore_InvalidCreateReaderMethodCalledForState(GetCreateReaderMethodName(expectedState), this.State)); } if (this.subReaderState != SubReaderState.None) { throw new ODataException(Microsoft.Data.OData.Strings.ODataParameterReaderCore_CreateReaderAlreadyCalled(GetCreateReaderMethodName(expectedState), this.Name)); } }
private void RunParameterReaderErrorTest( ODataParameterReaderTestWrapper reader, ExpectedException expectedException, ODataParameterReaderState expectedState = ODataParameterReaderState.Exception) { if (reader == null) { // Reader creation failed and we verified the exception already return; } this.Assert.ExpectedException(() => reader.Read(), expectedException, this.ExceptionVerifier); this.Assert.AreEqual(expectedState, reader.State, "Reader should be in '" + expectedState.ToString() + "' state."); }
/// <summary> /// Verifies that one of CreateEntryReader(), CreateFeedReader() or CreateCollectionReader() can be called. /// </summary> /// <param name="expectedState">The expected state of the reader.</param> private void VerifyCanCreateSubReader(ODataParameterReaderState expectedState) { this.inputContext.VerifyNotDisposed(); if (this.State != expectedState) { throw new ODataException(Strings.ODataParameterReaderCore_InvalidCreateReaderMethodCalledForState(ODataParameterReaderCore.GetCreateReaderMethodName(expectedState), this.State)); } if (this.subReaderState != SubReaderState.None) { Debug.Assert(this.Name != null, "this.Name != null"); throw new ODataException(Strings.ODataParameterReaderCore_CreateReaderAlreadyCalled(ODataParameterReaderCore.GetCreateReaderMethodName(expectedState), this.Name)); } }
/// <summary> /// Constructor creating a new reader scope. /// </summary> /// <param name="state">The reader state of this scope.</param> /// <param name="name">The parameter name attached to this scope.</param> /// <param name="value">The parameter value attached to this scope.</param> public Scope(ODataParameterReaderState state, string name, object value) { Debug.Assert( state == ODataParameterReaderState.Start && name == null && value == null || state == ODataParameterReaderState.Value && !string.IsNullOrEmpty(name) && (value == null || value is ODataEnumValue || EdmLibraryExtensions.IsPrimitiveType(value.GetType())) || state == ODataParameterReaderState.Resource && !string.IsNullOrEmpty(name) && value == null || state == ODataParameterReaderState.ResourceSet && !string.IsNullOrEmpty(name) && value == null || state == ODataParameterReaderState.Collection && !string.IsNullOrEmpty(name) && value == null || state == ODataParameterReaderState.Exception && name == null && value == null || state == ODataParameterReaderState.Completed && name == null && value == null, "Reader state and associated item do not match."); this.state = state; this.name = name; this.value = value; }
/// <summary> /// Creates a new <see cref="Scope"/> for the specified <paramref name="state"/> with the provided /// <paramref name="name"/> and <paramref name="value"/> and pushes it on the stack of scopes. /// </summary> /// <param name="state">The <see cref="ODataParameterReaderState"/> to use for the new scope.</param> /// <param name="name">The paramter name to attach with the state in the new scope.</param> /// <param name="value">The paramter value to attach with the state in the new scope.</param> protected void EnterScope(ODataParameterReaderState state, string name, object value) { if (state == ODataParameterReaderState.Value) { if (value != null && !(value is ODataComplexValue) && !EdmLibraryExtensions.IsPrimitiveType(value.GetType())) { throw new ODataException(Strings.General_InternalError(InternalErrorCodes.ODataParameterReaderCore_ValueMustBePrimitiveOrComplexOrNull)); } } Debug.Assert(this.scopes.Count == 0 || this.State != ODataParameterReaderState.Exception || state == ODataParameterReaderState.Exception, "If the reader is already in Exception state, we shouldn't call EnterScope() except for another Exception."); // We only need to enter the exception state once. if (this.scopes.Count == 0 || this.State != ODataParameterReaderState.Exception) { Debug.Assert( state == ODataParameterReaderState.Exception || state == ODataParameterReaderState.Start && this.scopes.Count == 0 || state == ODataParameterReaderState.Completed && this.scopes.Count == 0 || this.scopes.Count == 1 && this.scopes.Peek().State == ODataParameterReaderState.Start, "Unexpected state in the scopes stack."); // Make sure there aren't any missing parameter in the payload. if (state == ODataParameterReaderState.Completed) { List <string> missingParameters = new List <string>(); // Note that the binding parameter will be specified on the Uri rather than the payload, skip the binding parameter. foreach (IEdmFunctionParameter parameter in this.FunctionImport.Parameters.Skip(this.FunctionImport.IsBindable ? 1 : 0)) { if (!this.parametersRead.Contains(parameter.Name) && !parameter.Type.IsNullable) { missingParameters.Add(parameter.Name); } } if (missingParameters.Count > 0) { this.scopes.Push(new Scope(ODataParameterReaderState.Exception, null, null)); throw new ODataException(Strings.ODataParameterReaderCore_ParametersMissingInPayload(this.FunctionImport.Name, string.Join(",", missingParameters.ToArray()))); } } this.scopes.Push(new Scope(state, name, value)); } }
private bool UpdateState() { if (!this.enumerator.MoveNext()) { this.state = ODataParameterReaderState.Completed; return(false); } var parameter = this.operation.Parameters.SingleOrDefault(para => para.Name == this.enumerator.Current.Name); if (parameter == null) { throw new ApplicationException("Given parameter name " + this.enumerator.Current.Name + " not found."); } this.name = parameter.Name; this.value = this.avroRecord[this.enumerator.Current.Position]; if (this.value is AvroRecord) { if (parameter.Type.Definition is IEdmComplexType) { this.value = ODataAvroConvert.ToODataComplexValue((AvroRecord)this.value); this.state = ODataParameterReaderState.Value; } else if (parameter.Type.Definition is IEdmEntityType) { this.state = ODataParameterReaderState.Entry; } else { this.state = ODataParameterReaderState.Exception; return(false); } } else if (this.value is Array && !(this.value is byte[])) { this.state = ODataParameterReaderState.Feed; } else { this.state = ODataParameterReaderState.Value; } return(true); }
/// <summary> /// Constructor creating a new reader scope. /// </summary> /// <param name="state">The reader state of this scope.</param> /// <param name="name">The parameter name attached to this scope.</param> /// <param name="value">The parameter value attached to this scope.</param> public Scope(ODataParameterReaderState state, string name, object value) { Debug.Assert( state == ODataParameterReaderState.Start && name == null && value == null || state == ODataParameterReaderState.Value && !string.IsNullOrEmpty(name) && (value == null || value is ODataComplexValue || EdmLibraryExtensions.IsPrimitiveType(value.GetType())) || #if SUPPORT_ENTITY_PARAMETER state == ODataParameterReaderState.Entry && !string.IsNullOrEmpty(name) && value == null || state == ODataParameterReaderState.Feed && !string.IsNullOrEmpty(name) && value == null || #endif state == ODataParameterReaderState.Collection && !string.IsNullOrEmpty(name) && value == null || state == ODataParameterReaderState.Exception && name == null && value == null || state == ODataParameterReaderState.Completed && name == null && value == null, "Reader state and associated item do not match."); this.state = state; this.name = name; this.value = value; }
private bool UpdateState() { if (!this.enumerator.MoveNext()) { this.state = ODataParameterReaderState.Completed; return false; } var parameter = this.operation.Parameters.SingleOrDefault(para => para.Name == this.enumerator.Current.Name); if (parameter == null) { throw new ApplicationException("Given parameter name " + this.enumerator.Current.Name + " not found."); } this.name = parameter.Name; this.value = this.avroRecord[this.enumerator.Current.Position]; if (this.value is AvroRecord) { if (parameter.Type.Definition is IEdmComplexType) { this.value = ODataAvroConvert.ToODataComplexValue((AvroRecord)this.value); this.state = ODataParameterReaderState.Value; } else if (parameter.Type.Definition is IEdmEntityType) { this.state = ODataParameterReaderState.Entry; } else { this.state = ODataParameterReaderState.Exception; return false; } } else if (this.value is Array && !(this.value is byte[])) { this.state = ODataParameterReaderState.Feed; } else { this.state = ODataParameterReaderState.Value; } return true; }
/// <summary> /// Gets the corresponding create reader method name for the given state. /// </summary> /// <param name="state">State in question.</param> /// <returns>Returns the name of the method to create the correct reader for the given state.</returns> private static string GetCreateReaderMethodName(ODataParameterReaderState state) { Debug.Assert(state == ODataParameterReaderState.Entry || state == ODataParameterReaderState.Feed || state == ODataParameterReaderState.Collection, "state must be Entry, Feed or Collection."); return("Create" + state.ToString() + "Reader"); }
protected void PopScope(ODataParameterReaderState state) { this.scopes.Pop(); }
/// <summary> /// Gets the corresponding create reader method name for the given state. /// </summary> /// <param name="state">State in question.</param> /// <returns>Returns the name of the method to create the correct reader for the given state.</returns> private static string GetCreateReaderMethodName(ODataParameterReaderState state) { Debug.Assert(state == ODataParameterReaderState.Resource || state == ODataParameterReaderState.ResourceSet || state == ODataParameterReaderState.Collection, "state must be Resource, ResourceSet or Collection."); return("Create" + state.ToString() + "Reader"); }
public Scope(ODataParameterReaderState state, string name, object value) { this.state = state; this.name = name; this.value = value; }
private static string GetCreateReaderMethodName(ODataParameterReaderState state) { return("Create" + state.ToString() + "Reader"); }
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."); }); }