/// <summary> /// Adds the default service and contract behaviors for a domain service. /// </summary> protected virtual void AddDefaultBehaviors() { // Force ASP.NET compat mode. AspNetCompatibilityRequirementsAttribute aspNetCompatModeBehavior = ServiceUtility.EnsureBehavior <AspNetCompatibilityRequirementsAttribute>(this.Description); aspNetCompatModeBehavior.RequirementsMode = AspNetCompatibilityRequirementsMode.Required; // Force default service behavior. ServiceBehaviorAttribute serviceBehavior = ServiceUtility.EnsureBehavior <ServiceBehaviorAttribute>(this.Description); serviceBehavior.InstanceContextMode = InstanceContextMode.PerCall; serviceBehavior.IncludeExceptionDetailInFaults = true; serviceBehavior.AddressFilterMode = AddressFilterMode.Any; // Force metadata to be available through HTTP GET. ServiceMetadataBehavior serviceMetadataBehavior = ServiceUtility.EnsureBehavior <ServiceMetadataBehavior>(this.Description); serviceMetadataBehavior.HttpGetEnabled = this.BaseAddresses.Any(a => a.Scheme.Equals(Uri.UriSchemeHttp)); serviceMetadataBehavior.HttpsGetEnabled = this.BaseAddresses.Any(a => a.Scheme.Equals(Uri.UriSchemeHttps)); }
/// <summary> /// Creates a contract from the specified description. /// </summary> /// <param name="description">The description to create a contract from.</param> /// <returns>A <see cref="ContractDescription"/>.</returns> private ContractDescription CreateContract(DomainServiceDescription description) { Type domainServiceType = description.DomainServiceType; // PERF: We should consider just looking at [ServiceDescription] directly. ServiceDescription serviceDesc = ServiceDescription.GetService(domainServiceType); // Use names from [ServiceContract], if specified. if (TypeDescriptor.GetAttributes(domainServiceType)[typeof(ServiceContractAttribute)] is ServiceContractAttribute sca) { if (!string.IsNullOrEmpty(sca.Name)) { serviceDesc.Name = sca.Name; } if (!string.IsNullOrEmpty(sca.Namespace)) { serviceDesc.Namespace = sca.Namespace; } } ContractDescription contractDesc = new ContractDescription(serviceDesc.Name, serviceDesc.Namespace) { ConfigurationName = serviceDesc.ConfigurationName, ContractType = domainServiceType }; // Add domain service behavior which takes care of instantiating DomainServices. ServiceUtility.EnsureBehavior <DomainServiceBehavior>(contractDesc); // Disable metadata generation by default contractDesc.Behaviors.Add(new ServiceMetadataContractBehavior() { MetadataGenerationDisabled = true }); // Load the ContractDescription from the DomainServiceDescription. ServiceUtility.PopulateContractDescription(contractDesc, description); return(contractDesc); }
/// <summary> /// Creates a contract from the specified description. /// </summary> /// <param name="description">The description to create a contract from.</param> /// <returns>A <see cref="ContractDescription"/>.</returns> private ContractDescription CreateContract(DomainServiceDescription description) { Type domainServiceType = description.DomainServiceType; // PERF: We should consider just looking at [ServiceDescription] directly. ServiceDescription serviceDesc = ServiceDescription.GetService(domainServiceType); // Use names from [ServiceContract], if specified. ServiceContractAttribute sca = TypeDescriptor.GetAttributes(domainServiceType)[typeof(ServiceContractAttribute)] as ServiceContractAttribute; if (sca != null) { if (!String.IsNullOrEmpty(sca.Name)) { serviceDesc.Name = sca.Name; } if (!String.IsNullOrEmpty(sca.Namespace)) { serviceDesc.Name = sca.Namespace; } } ContractDescription contractDesc = new ContractDescription(serviceDesc.Name + this.Name, serviceDesc.Namespace) { ConfigurationName = serviceDesc.ConfigurationName + this.Name, ContractType = domainServiceType }; // Add domain service behavior which takes care of instantiating DomainServices. ServiceUtility.EnsureBehavior <DomainServiceBehavior>(contractDesc); // Load the ContractDescription from the DomainServiceDescription. ServiceUtility.LoadContractDescription(contractDesc, description); return(contractDesc); }
private static OperationDescription CreateOperationDescription(ContractDescription declaringContract, DomainOperationEntry operation) { OperationDescription operationDesc = ServiceUtility.CreateBasicOperationDescription(declaringContract, operation.Name); // Propagate behaviors. foreach (IOperationBehavior behavior in operation.Attributes.OfType <IOperationBehavior>()) { operationDesc.Behaviors.Add(behavior); } // Add standard behaviors. if ((operation.Operation == DomainOperation.Query && ((QueryAttribute)operation.OperationAttribute).HasSideEffects) || (operation.Operation == DomainOperation.Invoke && ((InvokeAttribute)operation.OperationAttribute).HasSideEffects)) { // REVIEW: We should actually be able to remove the following line entirely, since // all operations are [WebInvoke] by default. ServiceUtility.EnsureBehavior <WebInvokeAttribute>(operationDesc); } else if (operation.Operation == DomainOperation.Query && !((QueryAttribute)operation.OperationAttribute).HasSideEffects) { // This is a query with HasSideEffects == false, allow both POST and GET var invoke = ServiceUtility.EnsureBehavior <WebInvokeAttribute>(operationDesc); invoke.Method = "*"; // We need to set URI template in order to allow the normal parameters to be extracted from the Uri if (operation.Parameters.Count > 0) { invoke.UriTemplate = GetDefaultQueryUriTemplate(operation); } } else { ServiceUtility.EnsureBehavior <WebGetAttribute>(operationDesc); } string action = ServiceUtility.GetMessageAction(declaringContract, operationDesc.Name, /* action */ null); // Define operation input. MessageDescription inputMessageDesc = new MessageDescription(action, MessageDirection.Input); inputMessageDesc.Body.WrapperName = operationDesc.Name; inputMessageDesc.Body.WrapperNamespace = ServiceUtility.DefaultNamespace; for (int i = 0; i < operation.Parameters.Count; i++) { DomainOperationParameter parameter = operation.Parameters[i]; MessagePartDescription parameterPartDesc = new MessagePartDescription(parameter.Name, ServiceUtility.DefaultNamespace) { Index = i, Type = SerializationUtility.GetClientType(parameter.ParameterType) }; inputMessageDesc.Body.Parts.Add(parameterPartDesc); } operationDesc.Messages.Add(inputMessageDesc); // Define operation output. string responseAction = ServiceUtility.GetResponseMessageAction(declaringContract, operationDesc.Name, /* action */ null); MessageDescription outputMessageDesc = new MessageDescription(responseAction, MessageDirection.Output); outputMessageDesc.Body.WrapperName = operationDesc.Name + "Response"; outputMessageDesc.Body.WrapperNamespace = ServiceUtility.DefaultNamespace; if (operation.ReturnType != typeof(void)) { outputMessageDesc.Body.ReturnValue = new MessagePartDescription(operationDesc.Name + "Result", ServiceUtility.DefaultNamespace) { Type = SerializationUtility.GetClientType(operation.ReturnType) }; } operationDesc.Messages.Add(outputMessageDesc); return(operationDesc); }