public async Task InvokeOperation_ServerValidationException() { TestProvider_Scenarios provider = ServerTestHelper.CreateInitializedDomainService <TestProvider_Scenarios>(DomainOperationType.Invoke); DomainServiceDescription serviceDescription = DomainServiceDescription.GetDescription(typeof(TestProvider_Scenarios)); DomainOperationEntry throwValidationExceptionMethod = serviceDescription.GetInvokeOperation("ThrowValidationException"); Assert.IsNotNull(throwValidationExceptionMethod); var invokeResult = await provider.InvokeAsync(new InvokeDescription(throwValidationExceptionMethod, Array.Empty <object>()), CancellationToken.None); Assert.IsNull(invokeResult.Result); Assert.IsNotNull(invokeResult.ValidationErrors); Assert.AreEqual(1, invokeResult.ValidationErrors.Count); Assert.AreEqual("Validation error.", invokeResult.ValidationErrors.ElementAt(0).ErrorMessage); }
public void InvokeOperation_ServerValidationException() { TestProvider_Scenarios provider = ServerTestHelper.CreateInitializedDomainService <TestProvider_Scenarios>(DomainOperationType.Invoke); DomainServiceDescription serviceDescription = DomainServiceDescription.GetDescription(typeof(TestProvider_Scenarios)); DomainOperationEntry throwValidationExceptionMethod = serviceDescription.GetInvokeOperation("ThrowValidationException"); Assert.IsNotNull(throwValidationExceptionMethod); IEnumerable <ValidationResult> validationErrors; object result = provider.Invoke(new InvokeDescription(throwValidationExceptionMethod, new object[0]), out validationErrors); Assert.IsNull(result); Assert.IsNotNull(validationErrors); Assert.AreEqual(1, validationErrors.Count()); Assert.AreEqual("Validation error.", validationErrors.ElementAt(0).ErrorMessage); }
public async Task ServiceContext_CurrentOperation() { DomainServiceDescription dsd = DomainServiceDescription.GetDescription(typeof(ServiceContext_CurrentOperation_DomainService)); ServiceContext_CurrentOperation_DomainService ds; // Execute a query. ds = new ServiceContext_CurrentOperation_DomainService(DomainOperationType.Query); DomainOperationEntry queryOp = dsd.GetQueryMethod("GetEntities"); Assert.IsNotNull(queryOp); QueryDescription desc = new QueryDescription(queryOp); var queryResult = await ds.QueryAsync <ServiceContext_CurrentOperation_Entity>(desc, CancellationToken.None); Assert.AreEqual(queryOp, ServiceContext_CurrentOperation_DomainService.LastOperation); Assert.IsNull(ds.Context.Operation); // Invoke an operation. ds = new ServiceContext_CurrentOperation_DomainService(DomainOperationType.Invoke); DomainOperationEntry invokeOp = dsd.GetInvokeOperation("Echo"); Assert.IsNotNull(invokeOp); await ds.InvokeAsync(new InvokeDescription(invokeOp, null), CancellationToken.None); Assert.AreEqual(invokeOp, ServiceContext_CurrentOperation_DomainService.LastOperation); Assert.IsNull(ds.Context.Operation); // Invoke an insert operation. ds = new ServiceContext_CurrentOperation_DomainService(DomainOperationType.Submit); DomainOperationEntry insertOp = dsd.GetSubmitMethod(typeof(ServiceContext_CurrentOperation_Entity), DomainOperation.Insert); Assert.IsNotNull(insertOp); await ds.SubmitAsync(new ChangeSet(new ChangeSetEntry[] { new ChangeSetEntry() { Entity = new ServiceContext_CurrentOperation_Entity() { Key = 1 }, Operation = DomainOperation.Insert } }), CancellationToken.None); Assert.AreEqual(insertOp, ServiceContext_CurrentOperation_DomainService.LastOperation); Assert.IsNull(ds.Context.Operation); }
public void ServiceContext_CurrentOperation() { DomainServiceDescription dsd = DomainServiceDescription.GetDescription(typeof(ServiceContext_CurrentOperation_DomainService)); ServiceContext_CurrentOperation_DomainService ds; IEnumerable <ValidationResult> validationErrors; // Execute a query. ds = new ServiceContext_CurrentOperation_DomainService(DomainOperationType.Query); DomainOperationEntry queryOp = dsd.GetQueryMethod("GetEntities"); Assert.IsNotNull(queryOp); QueryDescription desc = new QueryDescription(queryOp); int totalCount; ds.Query(desc, out validationErrors, out totalCount); Assert.AreEqual(queryOp, ServiceContext_CurrentOperation_DomainService.LastOperation); Assert.IsNull(ds.Context.Operation); // Invoke an operation. ds = new ServiceContext_CurrentOperation_DomainService(DomainOperationType.Invoke); DomainOperationEntry invokeOp = dsd.GetInvokeOperation("Echo"); Assert.IsNotNull(invokeOp); ds.Invoke(new InvokeDescription(invokeOp, null), out validationErrors); Assert.AreEqual(invokeOp, ServiceContext_CurrentOperation_DomainService.LastOperation); Assert.IsNull(ds.Context.Operation); // Invoke an insert operation. ds = new ServiceContext_CurrentOperation_DomainService(DomainOperationType.Submit); DomainOperationEntry insertOp = dsd.GetSubmitMethod(typeof(ServiceContext_CurrentOperation_Entity), DomainOperation.Insert); Assert.IsNotNull(insertOp); ds.Submit(new ChangeSet(new ChangeSetEntry[] { new ChangeSetEntry() { Entity = new ServiceContext_CurrentOperation_Entity() { Key = 1 }, Operation = DomainOperation.Insert } })); Assert.AreEqual(insertOp, ServiceContext_CurrentOperation_DomainService.LastOperation); Assert.IsNull(ds.Context.Operation); }
/// <summary> /// Helper method performs a invoke operation against a given proxy instance. /// </summary> /// <param name="domainService">The type of <see cref="DomainService"/> to perform this query operation against.</param> /// <param name="context">The current context.</param> /// <param name="domainServiceInstances">The list of tracked <see cref="DomainService"/> instances that any newly created /// <see cref="DomainServices"/> will be added to.</param> /// <param name="name">The name of the operation to invoke.</param> /// <param name="parameters">The operation parameters.</param> /// <returns>The result of the invoke operation.</returns> /// <exception cref="ArgumentNullException">if <paramref name="context"/> is null.</exception> /// <exception cref="ArgumentNullException">if <paramref name="name"/> is null or an empty string.</exception> /// <exception cref="OperationException">if operation errors are thrown during execution of the invoke operation.</exception> public static object Invoke(Type domainService, DomainServiceContext context, IList <DomainService> domainServiceInstances, string name, object[] parameters) { context = new DomainServiceContext(context, DomainOperationType.Invoke); DomainService service = CreateDomainServiceInstance(domainService, context, domainServiceInstances); DomainServiceDescription serviceDescription = DomainServiceDescription.GetDescription(service.GetType()); DomainOperationEntry method = serviceDescription.GetInvokeOperation(name); IEnumerable <ValidationResult> validationErrors; InvokeDescription invokeDescription = new InvokeDescription(method, parameters); object result = service.Invoke(invokeDescription, out validationErrors); if (validationErrors != null && validationErrors.Any()) { IEnumerable <ValidationResultInfo> operationErrors = validationErrors.Select(ve => new ValidationResultInfo(ve.ErrorMessage, ve.MemberNames)); throw new OperationException(Resource.DomainServiceProxy_OperationError, operationErrors); } return(result); }
public async Task InvokeOperation_ServerValidationError() { TestProvider_Scenarios provider = ServerTestHelper.CreateInitializedDomainService <TestProvider_Scenarios>(DomainOperationType.Invoke); DomainServiceDescription serviceDescription = DomainServiceDescription.GetDescription(typeof(TestProvider_Scenarios)); DomainOperationEntry incrementBid1ForAByMethod = serviceDescription.GetInvokeOperation("IncrementBid1ForABy"); Assert.IsNotNull(incrementBid1ForAByMethod); TestDomainServices.A inputA = new TestDomainServices.A() { BID1 = 1 }; var invokeResult = await provider.InvokeAsync(new InvokeDescription(incrementBid1ForAByMethod, new object[] { inputA, 2 }), CancellationToken.None); Assert.IsNull(invokeResult.Result); Assert.IsNotNull(invokeResult.ValidationErrors); Assert.AreEqual(2, invokeResult.ValidationErrors.Count); Assert.AreEqual("The field delta must be between 5 and 10.", invokeResult.ValidationErrors.ElementAt(0).ErrorMessage); Assert.AreEqual("The RequiredString field is required.", invokeResult.ValidationErrors.ElementAt(1).ErrorMessage); }
/// <summary> /// Helper method performs a invoke operation against a given proxy instance. /// </summary> /// <param name="domainService">The type of <see cref="DomainService"/> to perform this query operation against.</param> /// <param name="context">The current context.</param> /// <param name="domainServiceInstances">The list of tracked <see cref="DomainService"/> instances that any newly created /// <see cref="DomainServices"/> will be added to.</param> /// <param name="name">The name of the operation to invoke.</param> /// <param name="parameters">The operation parameters.</param> /// <returns>The result of the invoke operation.</returns> /// <exception cref="ArgumentNullException">if <paramref name="context"/> is null.</exception> /// <exception cref="ArgumentNullException">if <paramref name="name"/> is null or an empty string.</exception> /// <exception cref="OperationException">if operation errors are thrown during execution of the invoke operation.</exception> public static object Invoke(Type domainService, DomainServiceContext context, IList <DomainService> domainServiceInstances, string name, object[] parameters) { context = new DomainServiceContext(context, DomainOperationType.Invoke); DomainService service = CreateDomainServiceInstance(domainService, context, domainServiceInstances); DomainServiceDescription serviceDescription = DomainServiceDescription.GetDescription(service.GetType()); DomainOperationEntry method = serviceDescription.GetInvokeOperation(name); InvokeDescription invokeDescription = new InvokeDescription(method, parameters); // TODO: Look into removing this blocking Wait var loadResult = service.InvokeAsync(invokeDescription, CancellationToken.None) .GetAwaiter().GetResult(); if (loadResult.HasValidationErrors) { IEnumerable <ValidationResultInfo> operationErrors = loadResult.ValidationErrors.Select(ve => new ValidationResultInfo(ve.ErrorMessage, ve.MemberNames)); throw new OperationException(Resource.DomainServiceProxy_OperationError, operationErrors); } return(loadResult.Result); }
public void DomainServiceWithMultipleValidOnlineMethods() { DomainServiceDescription description = DomainServiceDescription.GetDescription(typeof(OnlineMethod_ValidProvider_MultipleMethods)); Assert.IsNotNull(description); // verify GetOnlineMethod returns the correct DomainOperationEntry DomainOperationEntry returnedMethod = description.GetInvokeOperation("Process_VoidReturn"); Assert.IsNotNull(returnedMethod); Assert.AreEqual(DomainOperation.Invoke, returnedMethod.Operation); Assert.AreEqual("Process_VoidReturn", returnedMethod.Name); // verify GetOnlineMethods return all the invoke operations on this provider IEnumerable <DomainOperationEntry> returnedMethods = description.DomainOperationEntries.Where(p => p.Operation == DomainOperation.Invoke); Assert.IsNotNull(returnedMethods); Assert.AreEqual(10, returnedMethods.Count()); Assert.IsTrue(returnedMethods.Any(p => p.Name == "Process_EntitiesAndSimpleParams")); Assert.IsTrue(returnedMethods.Any(p => p.Name == "Process_Return_EntityListParam")); }
public void InvokeOperation_ServerValidationError() { TestProvider_Scenarios provider = ServerTestHelper.CreateInitializedDomainService <TestProvider_Scenarios>(DomainOperationType.Invoke); DomainServiceDescription serviceDescription = DomainServiceDescription.GetDescription(typeof(TestProvider_Scenarios)); DomainOperationEntry incrementBid1ForAByMethod = serviceDescription.GetInvokeOperation("IncrementBid1ForABy"); Assert.IsNotNull(incrementBid1ForAByMethod); IEnumerable <ValidationResult> validationErrors; TestDomainServices.A inputA = new TestDomainServices.A() { BID1 = 1 }; object result = provider.Invoke(new InvokeDescription(incrementBid1ForAByMethod, new object[] { inputA, 2 }), out validationErrors); Assert.IsNull(result); Assert.IsNotNull(validationErrors); Assert.AreEqual(2, validationErrors.Count()); Assert.AreEqual("The field delta must be between 5 and 10.", validationErrors.ElementAt(0).ErrorMessage); Assert.AreEqual("The RequiredString field is required.", validationErrors.ElementAt(1).ErrorMessage); }
public async Task Authorization_Custom_Authorization_On_Invoke() { // Specifically, the City data is marked so that no one can delete a Zip code // from WA unless their user name is WAGuy MockUser notWaGuy = new MockUser("notWAGuy"); notWaGuy.IsAuthenticated = true; DomainServiceDescription serviceDescription = DomainServiceDescription.GetDescription(typeof(CityDomainService)); DomainOperationEntry invokeOperation = serviceDescription.GetInvokeOperation("GetStateIfUser"); Assert.IsNotNull(invokeOperation, "Could not locate GetStateIfUser Invoke operation"); DomainOperationEntry getCitiesQuery = serviceDescription.GetQueryMethod("GetCities"); City city = null; // Execute a query to get a City from WA using (CityDomainService cities = new CityDomainService()) { // Now prepare for a query to find a Zip in WA DomainServiceContext ctxt = new WcfDomainServiceContext(new MockDataService(notWaGuy), DomainOperationType.Query); cities.Initialize(ctxt); IEnumerable result = (await cities.QueryAsync <City>(new QueryDescription(getCitiesQuery), CancellationToken.None)).Result; city = result.OfType <City>().FirstOrDefault(z => z.StateName == "WA"); Assert.IsNotNull(city, "Could not find a city in WA"); } // Perform an invoke against a method that has a custom auth attribute requiring WaGuy // where the user is something else -- should be denied using (CityDomainService cities = new CityDomainService()) { // Prepare an invoke to call a method that has a custom auth attribute DomainServiceContext ctxt = new WcfDomainServiceContext(new MockDataService(notWaGuy), DomainOperationType.Invoke); cities.Initialize(ctxt); // verify that even top level exceptions go through // the OnError handler UnauthorizedAccessException expectedException = null; try { // cause a domain service not initialized exception await cities.InvokeAsync(new InvokeDescription(invokeOperation, new object[] { city }), CancellationToken.None); } catch (UnauthorizedAccessException e) { expectedException = e; } Assert.IsNotNull(expectedException, "Expected Invoke to be denied"); Assert.AreEqual("Access to operation 'GetStateIfUser' was denied.", expectedException.Message); } // Perform an invoke against a method that has a custom auth attribute requiring WaGuy // where the user is correct -- should be allowed using (CityDomainService cities = new CityDomainService()) { MockUser waGuy = new MockUser("WAGuy"); waGuy.IsAuthenticated = true; // Prepare an invoke to call a method that has a custom auth attribute DomainServiceContext ctxt = new WcfDomainServiceContext(new MockDataService(waGuy), DomainOperationType.Invoke); cities.Initialize(ctxt); // verify that even top level exceptions go through // the OnError handler UnauthorizedAccessException expectedException = null; try { // cause a domain service not initialized exception await cities.InvokeAsync(new InvokeDescription(invokeOperation, new object[] { city }), CancellationToken.None); } catch (UnauthorizedAccessException e) { expectedException = e; } Assert.IsNull(expectedException, "Expected Invoke to be allowed"); } }