public void RequiresSecureEndpoint()
        {
            EnableClientAccessAttribute attribute = new EnableClientAccessAttribute();

            Assert.IsFalse(attribute.RequiresSecureEndpoint,
                "Default usage should not require a secure endpoint.");

            bool requiresSecureEndpoint = true;
            attribute.RequiresSecureEndpoint = requiresSecureEndpoint;

            Assert.AreEqual(requiresSecureEndpoint, attribute.RequiresSecureEndpoint,
                "States should be equal.");
        }
        public void RequiresSecureEndpoint()
        {
            EnableClientAccessAttribute attribute = new EnableClientAccessAttribute();

            Assert.IsFalse(attribute.RequiresSecureEndpoint,
                           "Default usage should not require a secure endpoint.");

            bool requiresSecureEndpoint = true;

            attribute.RequiresSecureEndpoint = requiresSecureEndpoint;

            Assert.AreEqual(requiresSecureEndpoint, attribute.RequiresSecureEndpoint,
                            "States should be equal.");
        }
        /// <summary>
        /// Validate the current request.
        /// </summary>
        /// <param name="domainService">Domain service instance for which request was sent.</param>
        private static void VerifyRequest(DomainService domainService)
        {
            EnableClientAccessAttribute ecaAttribute = (EnableClientAccessAttribute)TypeDescriptor.GetAttributes(domainService)[typeof(EnableClientAccessAttribute)];

            System.Diagnostics.Debug.Assert(ecaAttribute != null, "The OData Endpoint shouldn't be created if EnableClientAccess attribute is missing on the domain service type.");

            if (ecaAttribute.RequiresSecureEndpoint)
            {
                if (HttpContext.Current != null)
                {
                    if (HttpContext.Current.Request.IsSecureConnection)
                    {
                        return;
                    }
                }
                else if (OperationContext.Current != null)
                {
                    // DEVNOTE(wbasheer): See what the RIA people do here and match.
                }

                throw new DomainDataServiceException((int)HttpStatusCode.Forbidden, Resource.DomainDataService_Enable_Client_Access_Require_Secure_Connection);
            }
        }
        /// <summary>
        /// Generates the client proxy code for a domain service.
        /// </summary>
        public override void Generate()
        {
            // ----------------------------------------------------------------
            // Namespace
            // ----------------------------------------------------------------
            Type                domainServiceType = this._domainServiceDescription.DomainServiceType;
            CodeNamespace       ns         = this.ClientProxyGenerator.GetOrGenNamespace(domainServiceType);
            AttributeCollection attributes = this._domainServiceDescription.Attributes;

            // Missing namespace bails out of code-gen -- error has been logged
            if (ns == null)
            {
                return;
            }

            // ----------------------------------------------------------------
            // public partial sealed class {Name} : DomainContext
            // ----------------------------------------------------------------
            string clientTypeName = DomainContextTypeName(this._domainServiceDescription);

            CodeTypeDeclaration proxyClass = CodeGenUtilities.CreateTypeDeclaration(clientTypeName, domainServiceType.Namespace);

            proxyClass.IsPartial      = true;
            proxyClass.TypeAttributes = TypeAttributes.Public | TypeAttributes.Sealed;
            ns.Types.Add(proxyClass);

            CodeTypeReference domainContextTypeName = CodeGenUtilities.GetTypeReference(TypeConstants.DomainContextTypeFullName, ns.Name, false);

            proxyClass.BaseTypes.Add(domainContextTypeName);

            // Add <summary> xml comment to class
            string comment = string.Format(CultureInfo.CurrentCulture, Resource.CodeGen_DomainContext_Class_Summary_Comment, domainServiceType.Name);

            proxyClass.Comments.AddRange(CodeGenUtilities.GenerateSummaryCodeComment(comment, this.ClientProxyGenerator.IsCSharp));

            // ----------------------------------------------------------------
            // [DomainIdentifier], etc attributes move through metadata pipeline
            // ----------------------------------------------------------------
            CustomAttributeGenerator.GenerateCustomAttributes(
                this.ClientProxyGenerator,
                proxyClass,
                ex => string.Format(CultureInfo.CurrentCulture, Resource.ClientCodeGen_Attribute_ThrewException_CodeType, ex.Message, proxyClass.Name, ex.InnerException.Message),
                attributes.Cast <Attribute>(),
                proxyClass.CustomAttributes,
                proxyClass.Comments);

            // ----------------------------------------------------------------
            // Add default OnCreated partial method
            // ----------------------------------------------------------------
            NotificationMethodGenerator notificationMethodGen = new NotificationMethodGenerator(this.ClientProxyGenerator);

            proxyClass.Members.AddRange(notificationMethodGen.PartialMethodsSnippetBlock);

            // ----------------------------------------------------------------
            // Generate a contract interface for the service.
            // ----------------------------------------------------------------
            CodeTypeDeclaration contractInterface = this.GenerateContract(proxyClass);

            // ----------------------------------------------------------------
            // Generate constructors
            // ----------------------------------------------------------------
            EnableClientAccessAttribute enableClientAccessAttribute = attributes.OfType <EnableClientAccessAttribute>().Single();

            this.GenerateConstructors(proxyClass, contractInterface, enableClientAccessAttribute, notificationMethodGen.OnCreatedMethodInvokeExpression);

            // ----------------------------------------------------------------
            // Separate proxies for each domain operation entry
            // ----------------------------------------------------------------
            DomainOperationEntryProxyGenerator methodProxyGenerator = new DomainOperationEntryProxyGenerator(this.ClientProxyGenerator, proxyClass, this._domainServiceDescription);

            methodProxyGenerator.Generate();

            // ----------------------------------------------------------------
            // Invoke operations
            // ----------------------------------------------------------------
            InvokeOperationProxyGenerator invokeOperationProxyGenerator = new InvokeOperationProxyGenerator(this.ClientProxyGenerator, proxyClass, this._domainServiceDescription);

            invokeOperationProxyGenerator.Generate();

            // ----------------------------------------------------------------
            // EntityContainer instantiation
            // ----------------------------------------------------------------

            // The entity container holds a collection of EntityLists, one per visible entity root type.
            // The derived entity types are stored in their respective root's list and do not get their own.
            this.GenEntityContainer(proxyClass, this._domainServiceDescription.RootEntityTypes, this._domainServiceDescription);

            // Register created CodeTypeDeclaration with mapping
            this._typeMapping[domainServiceType] = proxyClass;
        }
        private void GenerateConstructors(CodeTypeDeclaration proxyClass, CodeTypeDeclaration contractInterface, EnableClientAccessAttribute enableClientAccessAttribute, CodeMethodInvokeExpression onCreatedExpression)
        {
            CodeTypeReference uriTypeRef     = CodeGenUtilities.GetTypeReference(typeof(Uri), this.ClientProxyGenerator, proxyClass);
            CodeTypeReference uriKindTypeRef = CodeGenUtilities.GetTypeReference(typeof(UriKind), this.ClientProxyGenerator, proxyClass);

            string            containingNamespace   = proxyClass.UserData["Namespace"] as string;
            CodeTypeReference contractTypeParameter =
                CodeGenUtilities.GetTypeReference(
                    containingNamespace + "." + proxyClass.Name + "." + contractInterface.Name,
                    containingNamespace,
                    true);

            // construct relative URI
            string         relativeServiceUri    = string.Format(CultureInfo.InvariantCulture, "{0}.svc", this._domainServiceDescription.DomainServiceType.FullName.Replace('.', '-'));
            CodeExpression relativeUriExpression = new CodeObjectCreateExpression(
                uriTypeRef,
                new CodePrimitiveExpression(relativeServiceUri),
                new CodePropertyReferenceExpression(new CodeTypeReferenceExpression(uriKindTypeRef), "Relative"));

            // ----------------------------------------------------------------
            // Default ctor decl (using relative URI)
            // ----------------------------------------------------------------

            // ctor parameters
            List <CodeParameterDeclarationExpression> ctorParams = null;

            // base params
            List <CodeExpression> baseParams = new List <CodeExpression>(1);

            baseParams.Add(relativeUriExpression);

            // add <summary> doc comments
            string comment = string.Format(CultureInfo.CurrentCulture, Resource.CodeGen_Default_Constructor_Summary_Comments, proxyClass.Name);
            CodeCommentStatementCollection comments = CodeGenUtilities.GenerateSummaryCodeComment(comment, this.ClientProxyGenerator.IsCSharp);

            // <comments>...</comments>
            // public .ctor() : this(new Uri("Foo-Bar.svc", UriKind.Relative))
            GenerateConstructor(proxyClass, ctorParams, baseParams, comments, false);

            // ----------------------------------------------------------------
            // DomainContext(System.Uri serviceUri) ctor decl
            // ----------------------------------------------------------------

            // ctor params
            ctorParams = new List <CodeParameterDeclarationExpression>(1);
            ctorParams.Add(new CodeParameterDeclarationExpression(uriTypeRef, "serviceUri"));

            // add <summary> and <param> comments
            comments = CodeGenUtilities.GenerateSummaryCodeComment(string.Format(CultureInfo.CurrentCulture, Resource.EntityCodeGen_ConstructorComments_Summary_ServiceUri, proxyClass.Name), this.ClientProxyGenerator.IsCSharp);
            comments.AddRange(CodeGenUtilities.GenerateParamCodeComment("serviceUri", string.Format(CultureInfo.CurrentCulture, Resource.EntityCodeGen_ConstructorComments_Param_ServiceUri, this._domainServiceDescription.DomainServiceType.Name), this.ClientProxyGenerator.IsCSharp));

            // <comments>...</comments>
            // public .ctor(Uri serviceUri) : this(DomainContext.CreateDomainClient(typeof(TContract), serviceUri, true/false))

            // ctor base parameters
            baseParams = new List <CodeExpression>(1);
            CodeTypeReference domainContextRef = CodeGenUtilities.GetTypeReference(TypeConstants.DomainContextTypeFullName, proxyClass.UserData["Namespace"] as string, false);

            baseParams.Add(new CodeMethodInvokeExpression(
                               new CodeMethodReferenceExpression(new CodeTypeReferenceExpression(domainContextRef), "CreateDomainClient"),
                               new CodeTypeOfExpression(contractTypeParameter),
                               new CodeArgumentReferenceExpression("serviceUri"),
                               new CodePrimitiveExpression(enableClientAccessAttribute.RequiresSecureEndpoint)));

            GenerateConstructor(proxyClass, ctorParams, baseParams, comments, false);

            // -----------------------------------------------------------------------
            // DomainContext(DomainClient domainClient) ctor decl
            // -----------------------------------------------------------------------

            // ctor parameters --[(DomainClient domainClient)]
            ctorParams = new List <CodeParameterDeclarationExpression>(1);
            ctorParams.Add(new CodeParameterDeclarationExpression(CodeGenUtilities.GetTypeReference(TypeConstants.DomainClientTypeFullName, proxyClass.UserData["Namespace"] as string, false), "domainClient"));

            // parameters to invoke on base -- [: base(domainClient)]
            baseParams = new List <CodeExpression>(1);
            baseParams.Add(new CodeArgumentReferenceExpression("domainClient"));

            // add <summary> and <param> comments
            comments = CodeGenUtilities.GenerateSummaryCodeComment(string.Format(CultureInfo.CurrentCulture, Resource.EntityCodeGen_ConstructorComments_Summary_DomainClientAccumulating, proxyClass.Name), this.ClientProxyGenerator.IsCSharp);
            comments.AddRange(CodeGenUtilities.GenerateParamCodeComment("domainClient", string.Format(CultureInfo.CurrentCulture, Resource.EntityCodeGen_ConstructorComments_Param_DomainClient), this.ClientProxyGenerator.IsCSharp));

            // <comments>...</comments>
            // public .ctor(DomainClient domainClient) : base(domainClient)]
            CodeConstructor proxyCtor = GenerateConstructor(proxyClass, ctorParams, baseParams, comments, true);

            proxyCtor.Statements.Add(onCreatedExpression);
        }
예제 #6
0
        internal bool GetRequiresSecureEndpoint()
        {
            EnableClientAccessAttribute enableClientAccessAttribute = this.Attributes.OfType <EnableClientAccessAttribute>().Single();

            return(enableClientAccessAttribute.RequiresSecureEndpoint);
        }