public void QueryAttribute_DomainService_Illegal_Default_With_Params() { ExceptionHelper.ExpectInvalidOperationException(delegate { DomainServiceDescription.GetDescription(typeof(QueryAttribute_DomainService_Default_Query_Has_Params)); }, string.Format(CultureInfo.CurrentCulture, Resource.DomainServiceDescription_DefaultQuery_Cannot_Have_Params, "GetEntity1")); }
/// <summary> /// Helper method performs a query 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="queryName">The name of the query to invoke.</param> /// <param name="parameters">The query parameters.</param> /// <returns>The query results. May be null if there are no query results.</returns> /// <exception cref="ArgumentNullException">if <paramref name="context"/> is null.</exception> /// <exception cref="ArgumentNullException">if <paramref name="queryName"/> is null or an empty string.</exception> /// <exception cref="InvalidOperationException">if no match query operation exists on the <paramref name="context"/>.</exception> /// <exception cref="OperationException">if operation errors are thrown during execution of the query operation.</exception> public static IEnumerable Query(Type domainService, DomainServiceContext context, IList <DomainService> domainServiceInstances, string queryName, object[] parameters) { context = new DomainServiceContext(context, DomainOperationType.Query); DomainService service = CreateDomainServiceInstance(domainService, context, domainServiceInstances); DomainServiceDescription serviceDescription = DomainServiceDescription.GetDescription(service.GetType()); DomainOperationEntry queryOperation = serviceDescription.GetQueryMethod(queryName); if (queryOperation == null) { string errorMessage = string.Format( CultureInfo.InvariantCulture, Resource.DomainServiceProxy_QueryOperationNotFound, queryName, domainService); throw new InvalidOperationException(errorMessage); } int totalCount; IEnumerable <ValidationResult> validationErrors; object[] parameterValues = parameters ?? new object[0]; QueryDescription queryDescription = new QueryDescription(queryOperation, parameterValues); IEnumerable result = service.Query(queryDescription, out validationErrors, out totalCount); 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 void OverloadsNotSupported() { ExceptionHelper.ExpectException <InvalidOperationException>(delegate { DomainServiceDescription.GetDescription(typeof(DomainMethod_InvalidProvider_MethodOverloads)); }, string.Format(CultureInfo.CurrentCulture, Resource.DomainOperationEntryOverload_NotSupported, "ProcessCity")); }
/// <summary> /// Generates the properties on the WebContext class. /// </summary> protected virtual void GenerateProperties() { this.Write("public new static WebContext Current\r\n{\r\n\tget\r\n\t{\r\n\t\treturn ((WebContext)(OpenRia" + "Services.DomainServices.Client.ApplicationServices.WebContextBase.Current));\r\n\t}" + "\r\n}\r\n"); DomainServiceDescription defaultAuthDescription = this.GetDefaultAuthDescription(); if (defaultAuthDescription != null) { Type genericType = null; typeof(IAuthentication <>).DefinitionIsAssignableFrom(defaultAuthDescription.DomainServiceType, out genericType); if ((genericType != null) && (genericType.GetGenericArguments().Count() == 1)) { string typeName = CodeGenUtilities.GetTypeName(genericType.GetGenericArguments()[0]); this.Write("public new "); this.Write(this.ToStringHelper.ToStringWithCulture(typeName)); this.Write(" User\r\n{\r\n\tget { return ("); this.Write(this.ToStringHelper.ToStringWithCulture(typeName)); this.Write(")base.User; }\r\n}\r\n"); } } }
private static void Generate <T>() { new AuthenticationCodeProcessor(new CSharpCodeProvider()).ProcessGeneratedCode( DomainServiceDescription.GetDescription(typeof(T)), null /* unused in negative tests */, null /* unused in negative tests */); }
public void OtherArgsMustBeOfPredefinedTypes() { ExceptionHelper.ExpectException <InvalidOperationException>(delegate { DomainServiceDescription.GetDescription(typeof(DomainMethod_InvalidProvider_MultipleEntities)); }, string.Format(CultureInfo.CurrentCulture, Resource.InvalidDomainOperationEntry_ParamMustBeSimple, "ProcessCity", "county")); ExceptionHelper.ExpectException <InvalidOperationException>(delegate { DomainServiceDescription.GetDescription(typeof(DomainMethod_InvalidProvider_ArgOfTypeObject)); }, string.Format(CultureInfo.CurrentCulture, Resource.InvalidDomainOperationEntry_ParamMustBeSimple, "ProcessCity", "objArg")); ExceptionHelper.ExpectException <InvalidOperationException>(delegate { DomainServiceDescription.GetDescription(typeof(DomainMethod_InvalidProvider_ArgOfTypeIntPtr)); }, string.Format(CultureInfo.CurrentCulture, Resource.InvalidDomainOperationEntry_ParamMustBeSimple, "ProcessCity", "intPtrArg")); ExceptionHelper.ExpectException <InvalidOperationException>(delegate { DomainServiceDescription.GetDescription(typeof(DomainMethod_InvalidProvider_ArgOfTypeUIntPtr)); }, string.Format(CultureInfo.CurrentCulture, Resource.InvalidDomainOperationEntry_ParamMustBeSimple, "ProcessCity", "uintPtrArg")); ExceptionHelper.ExpectException <InvalidOperationException>(delegate { DomainServiceDescription.GetDescription(typeof(DomainMethod_InvalidProvider_ArgOfComplexTypeIEnumerable)); }, string.Format(CultureInfo.CurrentCulture, Resource.InvalidDomainOperationEntry_ParamMustBeSimple, "ProcessCity", "ienumerableArg")); ExceptionHelper.ExpectException <InvalidOperationException>(delegate { DomainServiceDescription.GetDescription(typeof(DomainMethod_InvalidProvider_ArgOfComplexTypeList)); }, string.Format(CultureInfo.CurrentCulture, Resource.InvalidDomainOperationEntry_ParamMustBeSimple, "ProcessCity", "listArg")); }
public async Task DomainService_DirectQuery() { DomainServiceDescription description = DomainServiceDescription.GetDescription(typeof(TestDomainServices.EF.Catalog)); TestDomainServices.EF.Catalog service = new TestDomainServices.EF.Catalog(); DomainServiceContext dsc = new DomainServiceContext(new MockDataService(new MockUser("mathew") { IsAuthenticated = true }), DomainOperationType.Query); service.Initialize(dsc); DomainOperationEntry queryOperation = description.GetQueryMethod("GetPurchaseOrders"); ServiceQuery serviceQuery = new ServiceQuery(); serviceQuery.QueryParts = new ServiceQueryPart[] { new ServiceQueryPart("where", "(it.Freight!=0)"), new ServiceQueryPart("take", "1") }; QueryResult <AdventureWorksModel.PurchaseOrder> result = await QueryProcessor.ProcessAsync <AdventureWorksModel.PurchaseOrder>(service, queryOperation, Array.Empty <object>(), serviceQuery); Assert.AreEqual(1, result.RootResults.Count()); }
public override void ProcessGeneratedCode(DomainServiceDescription domainServiceDescription, CodeCompileUnit codeCompileUnit, IDictionary <Type, CodeTypeDeclaration> typeMapping) { // Get a reference to the entity class CodeTypeDeclaration codeGenEntity = typeMapping[typeof(TestEntity)]; AppDomain appDomain = AppDomain.CurrentDomain; AppDomainSetup setup = appDomain.SetupInformation; string baseDir = appDomain.BaseDirectory; codeGenEntity.Comments.Add(new CodeCommentStatement("[CodeProcessor] BaseDirectory:" + baseDir)); Configuration cfg = WebConfigurationManager.OpenWebConfiguration(null); AuthenticationSection authSection = (AuthenticationSection)cfg.GetSection("system.web/authentication"); FormsAuthenticationConfiguration formsAuth = authSection.Forms; if (formsAuth != null) { codeGenEntity.Comments.Add(new CodeCommentStatement("[CodeProcessor] Authentication:forms")); } ConnectionStringsSection connSect = cfg.ConnectionStrings; if (connSect != null) { ConnectionStringSettingsCollection connColl = connSect.ConnectionStrings; foreach (ConnectionStringSettings connSetting in connColl) { codeGenEntity.Comments.Add(new CodeCommentStatement("[CodeProcessor] ConnectionString:" + connSetting.ConnectionString)); } } }
public void ClientCodeGenerationDispatcher_Finds_Default_By_Name() { ConsoleLogger logger = new ConsoleLogger(); ClientCodeGenerationOptions options = new ClientCodeGenerationOptions() { Language = "C#" }; ICodeGenerationHost host = TestHelper.CreateMockCodeGenerationHost(logger, /*sharedTypeService*/ null); // Create a new dispatcher and call an internal extensibility point to add ourselves // into the MEF composition container using (ClientCodeGenerationDispatcher dispatcher = new ClientCodeGenerationDispatcher()) { string[] compositionAssemblies = new string[] { Assembly.GetExecutingAssembly().Location, typeof(T4DomainServiceClientCodeGenerator).Assembly.Location }; IDomainServiceClientCodeGenerator generator = dispatcher.FindCodeGenerator(host, options, compositionAssemblies, CodeDomClientCodeGenerator.GeneratorName); Assert.IsNotNull(generator, "the dispatcher did not find any code generator"); Assert.IsTrue(typeof(CodeDomClientCodeGenerator).IsAssignableFrom(generator.GetType()), "dispatcher found " + generator.GetType() + " but should have found CodeDomClientCodeGenerator"); DomainServiceDescription dsd = DomainServiceDescription.GetDescription(typeof(DispatcherDomainService)); string generatedCode = generator.GenerateCode(host, new DomainServiceDescription[] { dsd }, options); Assert.IsFalse(string.IsNullOrEmpty(generatedCode), "expected code to have been generated"); Assert.IsTrue(generatedCode.Contains("public sealed partial class DispatcherDomainContext : DomainContext"), "Expected generated code to contain public sealed partial class DispatcherDomainContext : DomainContext"); } }
public void RequiresRoleAttribute_Authorize_MultipleAttributes_Denied() { // Create user in only role1, which should be denied because we require (1 or 2) AND (3 or 4) IPrincipal user = this.CreateIPrincipal("user1", "role1"); // Instantiate a new DomainService to use for an Invoke using (RequiresRoleTestService testDomainService = new RequiresRoleTestService()) { testDomainService.Initialize(new DomainServiceContext(new MockDataService(user), DomainOperationType.Invoke)); // Get a DomainServiceDescription for that same domain service DomainServiceDescription description = DomainServiceDescription.GetDescription(typeof(RequiresRoleTestService)); // Locate the invoke method DomainOperationEntry invokeEntry = description.DomainOperationEntries.Single(p => p.Name == "Method1"); // Ask the domain service to perform authorization. // The principal will be located via the mock data service created above. // Invokes do not expect an entity instance. AuthorizationResult result = testDomainService.IsAuthorized(invokeEntry, entity: null); Assert.AreNotSame(AuthorizationResult.Allowed, result, "Expected user in role1 to be denied against invoke requiring roles (1 or 2) && (3 or 4) in multiple attributes"); // Validate the formatted denial message includes the invoke we attempted string expectedMessage = String.Format(CultureInfo.CurrentCulture, Resource.AuthorizationAttribute_Default_Message, "Method1"); Assert.AreEqual(expectedMessage, result.ErrorMessage, "Expected default denial message plus name of the invoke method"); } }
/// <summary> /// Creates endpoints based on the specified description. /// </summary> /// <param name="description">The <see cref="DomainServiceDescription"/> of the <see cref="DomainService"/> to create the endpoints for.</param> /// <param name="serviceHost">The service host for which the endpoints will be created.</param> /// <returns>The endpoints that were created.</returns> public override IEnumerable <ServiceEndpoint> CreateEndpoints(DomainServiceDescription description, DomainServiceHost serviceHost) { Debug.Assert(this.Name != null, "Name has not been set."); Debug.Assert(this.domainDataServiceMetadata == null, "this.domainDataServiceMetadata == null"); if (description.Attributes[typeof(EnableClientAccessAttribute)] != null) { // The metadata object will tell us which operations we should expose for the OData end point. this.domainDataServiceMetadata = new OData.DomainDataServiceMetadata(description); // The OData endpoint doesn't expose all operations in the DomainService, but only operations with parameter and return types // which are supported by the data service. WCF doesn't allow us to create a contract without any operation. if (this.domainDataServiceMetadata.Sets.Count > 0 || this.domainDataServiceMetadata.ServiceOperations.Count > 0) { // Infer the contract from Domain service description. ContractDescription contract = this.CreateContract(description); // Make endpoints that expose the inferred contract on the given base addresses. foreach (Uri address in serviceHost.BaseAddresses) { yield return(this.CreateEndpointForAddress(description, contract, address)); } } } }
public void DomainService_DirectQuery() { DomainServiceDescription description = DomainServiceDescription.GetDescription(typeof(TestDomainServices.EF.Catalog)); TestDomainServices.EF.Catalog service = new TestDomainServices.EF.Catalog(); DomainServiceContext dsc = new DomainServiceContext(new MockDataService(new MockUser("mathew") { IsAuthenticated = true }), DomainOperationType.Query); service.Initialize(dsc); DomainOperationEntry queryOperation = description.GetQueryMethod("GetPurchaseOrders"); ServiceQuery serviceQuery = new ServiceQuery(); serviceQuery.QueryParts = new ServiceQueryPart[] { new ServiceQueryPart("where", "(it.Freight!=0)"), new ServiceQueryPart("take", "1") }; IEnumerable <ValidationResult> validationErrors; int totalCount; QueryResult <AdventureWorksModel.PurchaseOrder> result = QueryProcessor.Process <AdventureWorksModel.PurchaseOrder>(service, queryOperation, new object[0], serviceQuery, out validationErrors, out totalCount); Assert.AreEqual(1, result.RootResults.Count()); }
/// <summary> /// Creates an endpoint based on the specified address. /// </summary> /// <param name="domainServiceDescription">Domain service description from which the <paramref name="contract"/> was inferred.</param> /// <param name="contract">The endpoint's contract.</param> /// <param name="address">The endpoint's base address.</param> /// <returns>An endpoint.</returns> private ServiceEndpoint CreateEndpointForAddress(DomainServiceDescription domainServiceDescription, ContractDescription contract, Uri address) { WebHttpBinding binding = new WebHttpBinding(); binding.MaxReceivedMessageSize = Int32.MaxValue; ServiceUtils.SetReaderQuotas(binding.ReaderQuotas); if (address.Scheme.Equals(Uri.UriSchemeHttps)) { binding.Security.Mode = WebHttpSecurityMode.Transport; } else if (ServiceUtils.CredentialType != HttpClientCredentialType.None) { binding.Security.Mode = WebHttpSecurityMode.TransportCredentialOnly; } if (ServiceUtils.CredentialType != HttpClientCredentialType.None) { binding.Security.Transport.ClientCredentialType = ServiceUtils.CredentialType; } ServiceEndpoint ep = new ServiceEndpoint(contract, binding, new EndpointAddress(address.OriginalString + "/" + this.Name)); // Data service end point has data service behavior. ep.Behaviors.Add(new DomainDataServiceEndpointBehavior() { DomainDataServiceMetadata = this.domainDataServiceMetadata, DefaultBodyStyle = WebMessageBodyStyle.Wrapped }); return(ep); }
/// <summary> /// Populates a contract description from a domain service description. /// </summary> /// <param name="contractDesc">Contract description to populate.</param> /// <param name="domainServiceDescription">Domain service description.</param> private void LoadContractDescription(ContractDescription contractDesc, DomainServiceDescription domainServiceDescription) { OperationDescription operationDesc; Debug.Assert(this.domainDataServiceMetadata != null, "this.domainDataServiceMetadata != null"); // Create contract operations by inferring them from the [Query] & [Invoke] methods on the domain service. foreach (DomainOperationEntry operation in domainServiceDescription.DomainOperationEntries) { if (this.domainDataServiceMetadata.Sets.ContainsKey(operation.Name) || this.domainDataServiceMetadata.ServiceOperations.ContainsKey(operation.Name)) { switch (operation.Operation) { case DomainOperation.Query: operationDesc = ODataEndpointFactory.CreateQueryOperationDescription(contractDesc, operation); Type queryOperationType = typeof(DomainDataServiceQueryOperationBehavior <>).MakeGenericType(operation.AssociatedType); // Add as first behavior such that our operation invoker is the first in the chain. operationDesc.Behaviors.Insert(0, (IOperationBehavior)Activator.CreateInstance(queryOperationType, operation)); contractDesc.Operations.Add(operationDesc); break; case DomainOperation.Invoke: operationDesc = ODataEndpointFactory.CreateOperationDescription(contractDesc, operation); // Add as first behavior such that our operation invoker is the first in the chain. operationDesc.Behaviors.Insert(0, new DomainDataServiceInvokeOperationBehavior(operation)); contractDesc.Operations.Add(operationDesc); break; default: break; } } } }
public void AuthorizationAttribute_Invoke_Allowed_No_Attributes() { IPrincipal user = this.CreateIPrincipal("user1"); // Instantiate a new DomainService to use for an Invoke using (AuthorizationTestDomainService testDomainService = new AuthorizationTestDomainService()) { testDomainService.Initialize(new DomainServiceContext(new MockDataService(user), DomainOperationType.Invoke)); // Get a DomainServiceDescription for that same domain service DomainServiceDescription description = DomainServiceDescription.GetDescription(typeof(AuthorizationTestDomainService)); // Locate the invoke method DomainOperationEntry invokeEntry = description.DomainOperationEntries.SingleOrDefault(p => p.Name == "InvokeNoAuth"); Assert.IsNotNull(invokeEntry, "Could not locate InvokeNoAuth invoke"); Assert.AreEqual("Invoke", invokeEntry.OperationType, "Invoke operation entry should show Invoke operation type"); // Ask the domain service to perform authorization. // The principal will be located via the mock data service created above. // Invokes do not expect an entity instance. AuthorizationResult result = testDomainService.IsAuthorized(invokeEntry, entity: null); Assert.AreSame(AuthorizationResult.Allowed, result, "Expected invoke with no auth attributes to be allowed."); } }
public void AuthorizationAttribute_Query_Custom_Attribute() { IPrincipal user = this.CreateIPrincipal("user1"); // Instantiate a new DomainService to use for a Query using (AuthorizationTestDomainService testDomainService = new AuthorizationTestDomainService()) { testDomainService.Initialize(new DomainServiceContext(new MockDataService(user), DomainOperationType.Query)); // Get a DomainServiceDescription for that same domain service DomainServiceDescription description = DomainServiceDescription.GetDescription(typeof(AuthorizationTestDomainService)); // Locate the QueryAllow query DomainOperationEntry entry = description.DomainOperationEntries.SingleOrDefault(p => p.Name == "QueryAllow"); Assert.IsNotNull(entry, "Did not find QueryAllow entry"); Assert.AreEqual("Query", entry.OperationType, "Query operation type expected for query operation"); // Ask the domain service to perform authorization. // The principal will be located via the mock data service created above. AuthorizationResult result = testDomainService.IsAuthorized(entry, entity: null); if (result != AuthorizationResult.Allowed) { Assert.Fail("Expected QueryAllow to be approved: " + result.ErrorMessage); } // Try again with a different query that will be denied entry = description.DomainOperationEntries.SingleOrDefault(p => p.Name == "QueryDeny"); Assert.IsNotNull(entry, "Did not find QueryDeny entry"); result = testDomainService.IsAuthorized(entry, entity: null); Assert.AreNotSame(AuthorizationResult.Allowed, result, "Expected QueryDeny to be denied"); } }
public void AuthorizationAttribute_Invoke_Custom_Attribute() { IPrincipal user = this.CreateIPrincipal("user1"); // Instantiate a new DomainService to use for an Invoke using (AuthorizationTestDomainService testDomainService = new AuthorizationTestDomainService()) { testDomainService.Initialize(new DomainServiceContext(new MockDataService(user), DomainOperationType.Invoke)); // Get a DomainServiceDescription for that same domain service DomainServiceDescription description = DomainServiceDescription.GetDescription(typeof(AuthorizationTestDomainService)); // Locate the invoke method DomainOperationEntry invokeEntry = description.DomainOperationEntries.Single(p => p.Name == "InvokeAllow"); // Ask the domain service to perform authorization. // The principal will be located via the mock data service created above. // Invokes do not expect an entity instance. AuthorizationResult result = testDomainService.IsAuthorized(invokeEntry, entity: null); Assert.AreSame(AuthorizationResult.Allowed, result, "Expected invoke with custom auth attributes to be allowed."); // Do that again but using an Invoke that will deny based on its own name invokeEntry = description.DomainOperationEntries.Single(p => p.Name == "InvokeDeny"); result = testDomainService.IsAuthorized(invokeEntry, entity: null); Assert.AreNotSame(AuthorizationResult.Allowed, result, "Expected invoke with denying custom attributes to be denied."); } }
public void ParameterlessDomainMethodNotSupported() { ExceptionHelper.ExpectException <InvalidOperationException>(delegate { DomainServiceDescription.GetDescription(typeof(DomainMethod_InvalidProvider_Parameterless)); }, Resource.InvalidCustomMethod_MethodCannotBeParameterless); }
internal static IQueryable Deserialize(DomainServiceDescription domainServiceDescription, IQueryable query, IEnumerable <ServiceQueryPart> queryParts, QueryResolver queryResolver) { foreach (ServiceQueryPart part in queryParts) { switch (part.QueryOperator) { case "where": query = DynamicQueryable.Where(query, part.Expression, queryResolver); break; case "orderby": query = DynamicQueryable.OrderBy(query, part.Expression, queryResolver); break; case "skip": query = DynamicQueryable.Skip(query, Convert.ToInt32(part.Expression, System.Globalization.CultureInfo.InvariantCulture)); break; case "take": query = DynamicQueryable.Take(query, Convert.ToInt32(part.Expression, System.Globalization.CultureInfo.InvariantCulture)); break; } } // Perform any required post processing transformations to the // expression tree Expression expr = PostProcessor.Process(domainServiceDescription, query.Expression); query = query.Provider.CreateQuery(expr); return(query); }
public async Task DomainService_CallSubmitDirectly() { DomainServiceDescription description = DomainServiceDescription.GetDescription(typeof(DomainMethod_ValidProvider_MultipleMethods)); List <ChangeSetEntry> changeSetEntries = new List <ChangeSetEntry>(); ChangeSetEntry processCityOperation = new ChangeSetEntry(); processCityOperation.Entity = new City { Name = "Redmond", CountyName = "King", StateName = "WA" }; processCityOperation.DomainOperationEntry = description.GetCustomMethod(typeof(City), "ProcessCity"); processCityOperation.Operation = DomainOperation.Update; processCityOperation.EntityActions = new EntityActionCollection { { "ProcessCity", new object[] { new byte[] { byte.MaxValue, byte.MinValue, 123 } } } }; changeSetEntries.Add(processCityOperation); ChangeSet changeset = new ChangeSet(changeSetEntries); DomainMethod_ValidProvider_MultipleMethods myTestProvider = ServerTestHelper.CreateInitializedDomainService <DomainMethod_ValidProvider_MultipleMethods>(DomainOperationType.Submit); await myTestProvider.SubmitAsync(changeset, CancellationToken.None); // check that the domain services have invoked the domain method correctly by checking the internal variables set Assert.AreEqual <string>("ProcessCity_", myTestProvider.Invoked); Assert.AreEqual <int>(3, myTestProvider.InputData.Length); Assert.AreEqual <byte>(123, myTestProvider.InputData[2]); }
public void DomainOperationEntry_All_Types() { DomainServiceDescription description = DomainServiceDescription.GetDescription(typeof(DomainOperationEntryTestDomainService)); // Invoke DomainOperationEntry entry = description.DomainOperationEntries.SingleOrDefault(p => p.Name == "InvokeMethod"); Assert.IsNotNull(entry, "Could not locate InvokeMethod"); Assert.IsNull(entry.AssociatedType, "Invoke should have no associated type"); Assert.AreEqual(typeof(DomainOperationEntryTestDomainService), entry.DomainServiceType, "Wrong domain service type"); Assert.AreEqual(DomainOperation.Invoke, entry.Operation, "Wrong domain operation"); Assert.AreEqual("Invoke", entry.OperationType, "Wrong operation type for this DomainOperationEntry"); // Invoke with entity entry = description.DomainOperationEntries.SingleOrDefault(p => p.Name == "InvokeMethodEntity"); Assert.IsNotNull(entry, "Could not locate InvokeMethodEntity"); Assert.AreEqual(typeof(DomainOperationEntryTestEntity), entry.AssociatedType, "Wrong associated type"); Assert.AreEqual(typeof(DomainOperationEntryTestDomainService), entry.DomainServiceType, "Wrong domain service type"); Assert.AreEqual(DomainOperation.Invoke, entry.Operation, "Wrong domain operation"); Assert.AreEqual("Invoke", entry.OperationType, "Wrong operation type for this DomainOperationEntry"); // Query entry = description.DomainOperationEntries.SingleOrDefault(p => p.Name == "GetEntities"); Assert.IsNotNull(entry, "Could not locate GetEntities"); Assert.AreEqual(typeof(DomainOperationEntryTestEntity), entry.AssociatedType, "Wrong associated type"); Assert.AreEqual(typeof(DomainOperationEntryTestDomainService), entry.DomainServiceType, "Wrong domain service type"); Assert.AreEqual(DomainOperation.Query, entry.Operation, "Wrong domain operation"); Assert.AreEqual("Query", entry.OperationType, "Wrong operation type for this DomainOperationEntry"); // Insert entry = description.DomainOperationEntries.SingleOrDefault(p => p.Name == "InsertMethod"); Assert.IsNotNull(entry, "Could not locate InsertMethod"); Assert.AreEqual(typeof(DomainOperationEntryTestEntity), entry.AssociatedType, "Wrong associated type"); Assert.AreEqual(typeof(DomainOperationEntryTestDomainService), entry.DomainServiceType, "Wrong domain service type"); Assert.AreEqual(DomainOperation.Insert, entry.Operation, "Wrong domain operation"); Assert.AreEqual("Insert", entry.OperationType, "Wrong operation type for this DomainOperationEntry"); // Update entry = description.DomainOperationEntries.SingleOrDefault(p => p.Name == "UpdateMethod"); Assert.IsNotNull(entry, "Could not locate InvokeMethod"); Assert.AreEqual(typeof(DomainOperationEntryTestEntity), entry.AssociatedType, "Wrong associated type"); Assert.AreEqual(typeof(DomainOperationEntryTestDomainService), entry.DomainServiceType, "Wrong domain service type"); Assert.AreEqual(DomainOperation.Update, entry.Operation, "Wrong domain operation"); Assert.AreEqual("Update", entry.OperationType, "Wrong operation type for this DomainOperationEntry"); // Custom Update entry = description.DomainOperationEntries.SingleOrDefault(p => p.Name == "CustomMethod"); Assert.IsNotNull(entry, "Could not locate CustomMethod"); Assert.AreEqual(typeof(DomainOperationEntryTestEntity), entry.AssociatedType, "Wrong associated type"); Assert.AreEqual(typeof(DomainOperationEntryTestDomainService), entry.DomainServiceType, "Wrong domain service type"); Assert.AreEqual(DomainOperation.Custom, entry.Operation, "Wrong domain operation"); Assert.AreEqual("Update", entry.OperationType, "Wrong operation type for this DomainOperationEntry"); // Delete entry = description.DomainOperationEntries.SingleOrDefault(p => p.Name == "DeleteMethod"); Assert.IsNotNull(entry, "Could not locate DeleteMethod"); Assert.AreEqual(typeof(DomainOperationEntryTestEntity), entry.AssociatedType, "Wrong associated type"); Assert.AreEqual(typeof(DomainOperationEntryTestDomainService), entry.DomainServiceType, "Wrong domain service type"); Assert.AreEqual(DomainOperation.Delete, entry.Operation, "Wrong domain operation"); Assert.AreEqual("Delete", entry.OperationType, "Wrong operation type for this DomainOperationEntry"); }
public void ServerValidation_Query() { TestDomainServices.TestProvider_Scenarios service = ServerTestHelper.CreateInitializedDomainService <TestDomainServices.TestProvider_Scenarios>(DomainOperationType.Query); DomainServiceDescription serviceDescription = DomainServiceDescription.GetDescription(service.GetType()); DomainOperationEntry method = serviceDescription.DomainOperationEntries.Single(p => p.Name == "QueryWithParamValidation"); QueryDescription qd = new QueryDescription(method, new object[] { -1, "ABC" }); int totalCount; IEnumerable <ValidationResult> validationErrors; service.Query(qd, out validationErrors, out totalCount); Assert.IsNotNull(validationErrors); Assert.AreEqual(2, validationErrors.Count()); ValidationResult error = validationErrors.ElementAt(0); Assert.AreEqual("The field a must be between 0 and 10.", error.ErrorMessage); Assert.AreEqual("a", error.MemberNames.Single()); error = validationErrors.ElementAt(1); Assert.AreEqual("The field b must be a string with a maximum length of 2.", error.ErrorMessage); Assert.AreEqual("b", error.MemberNames.Single()); }
public void GetDomainMethods_Sanity() { DomainServiceDescription description = DomainServiceDescription.GetDescription(typeof(DomainMethod_ValidProvider_MultipleMethods)); // verify that GetDomainMethods with City type only returns methods that are associated with City IEnumerable <DomainOperationEntry> domainMethods = description.GetCustomMethods(typeof(City)); Assert.IsNotNull(domainMethods); Assert.AreEqual(4, domainMethods.Count()); Assert.IsNotNull(domainMethods.Single(m => m.Name == "ProcessCity")); Assert.IsNotNull(domainMethods.Single(m => m.Name == "AssignCityZone")); Assert.IsNotNull(domainMethods.Single(m => m.Name == "AssignCityZoneIfAuthorized")); Assert.IsNotNull(domainMethods.Single(m => m.Name == "AutoAssignCityZone")); Assert.IsNull(domainMethods.FirstOrDefault(m => m.Name == "ProcessCounty")); // verify that GetDomainMethods with Zip type returns one method domainMethods = description.GetCustomMethods(typeof(Zip)); Assert.AreEqual(2, domainMethods.Count()); Assert.IsNotNull(domainMethods.Single(m => m.Name == "ReassignZipCode")); // verify that GetDomainMethods with County type returns one method domainMethods = description.GetCustomMethods(typeof(County)); Assert.AreEqual(1, domainMethods.Count()); Assert.IsNotNull(domainMethods.Single(m => m.Name == "ProcessCounty")); // verify that GetDomainMethods return empty collection when passing in type that is not associated with any methods on the provider domainMethods = description.GetCustomMethods(typeof(State)); Assert.IsNotNull(domainMethods); Assert.AreEqual(0, domainMethods.Count()); }
public void ClientCodeGenerationDispatcher_Generate_Using_T4_Custom() { ConsoleLogger logger = new ConsoleLogger(); ClientCodeGenerationOptions options = new ClientCodeGenerationOptions() { Language = "C#" }; ICodeGenerationHost host = TestHelper.CreateMockCodeGenerationHost(logger, /*sharedTypeService*/ null); // Create a new dispatcher and call an internal extensibility point to add ourselves // into the MEF composition container using (ClientCodeGenerationDispatcher dispatcher = new ClientCodeGenerationDispatcher()) { string[] compositionAssemblies = new string[] { typeof(T4DomainServiceClientCodeGenerator).Assembly.Location }; IDomainServiceClientCodeGenerator generator = dispatcher.FindCodeGenerator(host, options, compositionAssemblies, null); Assert.IsNotNull(generator, "the dispatcher did not find any code generator"); Assert.AreEqual(generator.GetType(), typeof(T4DomainServiceClientCodeGenerator), "dispatcher found " + generator.GetType() + " but should have found T4DomainServiceClientProxyGenerator"); DomainServiceDescription dsd = DomainServiceDescription.GetDescription(typeof(DispatcherDomainService)); string generatedCode = generator.GenerateCode(host, new DomainServiceDescription[] { dsd }, options); Assert.IsFalse(string.IsNullOrEmpty(generatedCode), "expected T4 generator to generate code"); TestHelper.AssertGeneratedCodeContains(generatedCode, T4DomainServiceClientCodeGenerator.GeneratedBoilerPlate); TestHelper.AssertGeneratedCodeContains(generatedCode, "public class DispatcherEntity : Entity"); TestHelper.AssertNoErrorsOrWarnings(logger); } }
/// <summary> /// Verifies that the <see cref="MetadataTypeAttribute"/> reference does not contain a cyclic reference and /// registers the AssociatedMetadataTypeTypeDescriptionProvider in that case. /// </summary> /// <param name="type">The entity type with the MetadataType attribute.</param> private static void RegisterAssociatedMetadataTypeTypeDescriptor(Type type) { Type currentType = type; HashSet <Type> metadataTypeReferences = new HashSet <Type>(); metadataTypeReferences.Add(currentType); while (true) { MetadataTypeAttribute attribute = (MetadataTypeAttribute)Attribute.GetCustomAttribute(currentType, typeof(MetadataTypeAttribute)); if (attribute == null) { break; } else { currentType = attribute.MetadataClassType; // If we find a cyclic reference, throw an error. if (metadataTypeReferences.Contains(currentType)) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, Resource.CyclicMetadataTypeAttributesFound, type.FullName)); } else { metadataTypeReferences.Add(currentType); } } } // If the MetadataType reference chain doesn't contain a cycle, register the use of the AssociatedMetadataTypeTypeDescriptionProvider. DomainServiceDescription.RegisterCustomTypeDescriptor(new AssociatedMetadataTypeTypeDescriptionProvider(type), type); }
public void InvalidProvider_DupMethodName() { ExceptionHelper.ExpectException <InvalidOperationException>(delegate { DomainServiceDescription description = DomainServiceDescription.GetDescription(typeof(OnlineMethod_InvalidProvider_DupMethodName)); }, string.Format(CultureInfo.CurrentCulture, Resource.DomainOperationEntryOverload_NotSupported, "TestMethod")); }
public void InvalidReturnType() { ExceptionHelper.ExpectException <InvalidOperationException>(delegate { DomainServiceDescription.GetDescription(typeof(DomainMethod_InvalidProvider_InvalidReturnType)); }, string.Format(CultureInfo.CurrentCulture, Resource.InvalidDomainOperationEntry_NonQueryMustReturnVoid, "ProcessCity")); }
public void TestDomainService_UpdateMemberToDefaultValue() { TestDomainServices.EF.Catalog service = ServerTestHelper.CreateInitializedDomainService <TestDomainServices.EF.Catalog>(DomainOperationType.Submit); DomainServiceDescription serviceDescription = DomainServiceDescription.GetDescription(service.GetType()); // in the below, non RTO is simulated by leaving ReorderPoint as its default value in the // original instance AdventureWorksModel.Product currProduct = new AdventureWorksModel.Product { ProductID = 1, ReorderPoint = 0, Weight = 0 }; AdventureWorksModel.Product origProduct = new AdventureWorksModel.Product { ProductID = 1, Weight = 50.0M }; // verify expected test state - this test relies on the below attribute values PropertyDescriptor pd = TypeDescriptor.GetProperties(typeof(AdventureWorksModel.Product))["ReorderPoint"]; Assert.IsNull(pd.Attributes[typeof(RoundtripOriginalAttribute)]); pd = TypeDescriptor.GetProperties(typeof(AdventureWorksModel.Product))["Weight"]; Assert.IsNotNull(pd.Attributes[typeof(RoundtripOriginalAttribute)]); pd = TypeDescriptor.GetProperties(typeof(AdventureWorksModel.Product))["SafetyStockLevel"]; Assert.IsNotNull(pd.Attributes[typeof(ExcludeAttribute)]); ObjectContextExtensions.AttachAsModified(service.ObjectContext.Products, currProduct, origProduct); // verify the expected property modifications ObjectStateEntry stateEntry = service.ObjectContext.ObjectStateManager.GetObjectStateEntry(currProduct); string[] modifiedProperties = stateEntry.GetModifiedProperties().ToArray(); Assert.IsTrue(modifiedProperties.Contains("ReorderPoint")); // no RTO so this should be modified Assert.IsTrue(modifiedProperties.Contains("Weight")); // RTO so this is picked up by normal value comparison Assert.IsFalse(modifiedProperties.Contains("SafetyStockLevel")); // excluded member, so shouldn't be marked modified Assert.IsFalse(modifiedProperties.Contains("ProductID")); // key members shouldn't be marked modified }
public void FirstArgMustBeEntity() { ExceptionHelper.ExpectException <InvalidOperationException>(delegate { DomainServiceDescription.GetDescription(typeof(DomainMethod_InvalidProvider_FirstArgNonEntity)); }, string.Format(CultureInfo.CurrentCulture, Resource.InvalidDomainMethod_ParamMustBeEntity, "name", "ProcessCity")); }
public void DefaultRowKeyMetadata() { // Create the DSD to register type descriptors DomainServiceDescription dsd = DomainServiceDescription.GetDescription(typeof(TMPT_DomainService)); PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(typeof(TMPT_MockEntity1)); PropertyDescriptor descriptor = properties["RowKey"]; Assert.IsNotNull(descriptor, "There should be a property descriptor for RowKey."); Assert.AreEqual(typeof(string), descriptor.PropertyType, "The RowKey type should be a string."); KeyAttribute keyAttribute = (KeyAttribute)descriptor.Attributes[typeof(KeyAttribute)]; Assert.IsNotNull(keyAttribute, "The RowKey should have a KeyAttribute."); EditableAttribute editableAttribute = (EditableAttribute)descriptor.Attributes[typeof(EditableAttribute)]; Assert.IsNotNull(editableAttribute, "The RowKey should have an EditableAttribute."); Assert.IsFalse(editableAttribute.AllowEdit, "The RowKey should not allow editing."); Assert.IsTrue(editableAttribute.AllowInitialValue, "The RowKey should allow an initial value."); DisplayAttribute displayAttribute = (DisplayAttribute)descriptor.Attributes[typeof(DisplayAttribute)]; Assert.IsNotNull(displayAttribute, "The RowKey should have an DisplayAttribute."); Assert.IsFalse(displayAttribute.AutoGenerateField, "The RowKey should not be included in autogeneration."); }
public override IEnumerable<ServiceEndpoint> CreateEndpoints(DomainServiceDescription description, DomainServiceHost serviceHost) { List<ServiceEndpoint> endpoints = base.CreateEndpoints(description, serviceHost).ToList(); foreach (ServiceEndpoint endpoint in endpoints) { WebHttpBehavior behavior = endpoint.Behaviors.Find<WebHttpBehavior>(); if (behavior != null) { behavior.HelpEnabled = true; } } return endpoints; }