예제 #1
0
        private static void InvokeMethod(HttpContext context, WebServiceMethodData methodData, IDictionary <string, object> rawParams)
        {
            // Initialize HttpCachePolicy
            InitializeCachePolicy(methodData, context);

            // Create an new instance of the class
            object target = null;

            if (!methodData.IsStatic)
            {
                target = Activator.CreateInstance(methodData.Owner.TypeData.Type);
            }

            // Make the actual method call on it
            object retVal = methodData.CallMethodFromRawParams(target, rawParams);

            string contentType;
            string responseString = null;

            if (methodData.UseXmlResponse)
            {
                responseString = retVal as string;

                // If it's a string, output it as is unless XmlSerializeString is set
                if (responseString == null || methodData.XmlSerializeString)
                {
                    // Use the Xml Serializer
                    try {
                        responseString = ServicesUtilities.XmlSerializeObjectToString(retVal);
                    }
                    catch (Exception e) {
                        // Throw a better error if Xml serialization fails
                        throw new InvalidOperationException(
                                  String.Format(CultureInfo.CurrentCulture, AtlasWeb.WebService_InvalidXmlReturnType,
                                                methodData.MethodName, retVal.GetType().FullName, e.Message));
                    }
                }

                contentType = "text/xml";
            }
            else
            {
                // Convert the result to a JSON string
                // DevDiv 88409:Change JSON wire format to prevent CSRF attack
                // We wrap the returned value inside an object , and assign the returned value
                // to member "d" of the object. We do so as JSOM for object will never be parsed
                // as valid Javascript , unlike arrays.
                responseString = @"{""d"":" + methodData.Owner.Serializer.Serialize(retVal) + "}";
                contentType    = "application/json";
            }

            // Set the response content-type
            context.Response.ContentType = contentType;

            // Write the string to the response
            if (responseString != null)
            {
                context.Response.Write(responseString);
            }
        }
예제 #2
0
 private static IDictionary <string, object> GetRawParams(WebServiceMethodData methodData, HttpContext context)
 {
     if (methodData.UseGet)
     {
         if (context.Request.HttpMethod == "GET")
         {
             return(GetRawParamsFromGetRequest(context, methodData.Owner.Serializer, methodData));
         }
         else
         {
             throw new InvalidOperationException(
                       String.Format(CultureInfo.CurrentCulture, AtlasWeb.WebService_InvalidVerbRequest,
                                     methodData.MethodName, "POST"));
         }
     }
     else if (context.Request.HttpMethod == "POST")
     {
         return(GetRawParamsFromPostRequest(context, methodData.Owner.Serializer));
     }
     else
     {
         throw new InvalidOperationException(
                   String.Format(CultureInfo.CurrentCulture, AtlasWeb.WebService_InvalidVerbRequest,
                                 methodData.MethodName, "GET"));
     }
 }
예제 #3
0
        // This is very similar to WebService caching, the differences are
        // 1) Here we explicitely SetValidUntilExpires(true) because in an XmlHttp there is
        //    "pragma:no-cache" in header which would result in cache miss on the server.
        // 2) Here we don't vary on header "Content-type" or "SOAPAction" because the former
        //    is specific to soap 1.2, which puts action in the content-type param; and the
        //    later is used by soap calls.
        private static void InitializeCachePolicy(WebServiceMethodData methodData, HttpContext context)
        {
            int cacheDuration = methodData.CacheDuration;

            if (cacheDuration > 0)
            {
                context.Response.Cache.SetCacheability(HttpCacheability.Server);
                context.Response.Cache.SetExpires(DateTime.Now.AddSeconds(cacheDuration));
                context.Response.Cache.SetSlidingExpiration(false);
                context.Response.Cache.SetValidUntilExpires(true);

                // DevDiv 23596: Don't set VaryBy* if the method takes no parameters
                if (methodData.ParameterDatas.Count > 0)
                {
                    context.Response.Cache.VaryByParams["*"] = true;
                }
                else
                {
                    context.Response.Cache.VaryByParams.IgnoreParams = true;
                }
            }
            else
            {
                context.Response.Cache.SetNoServerCaching();
                context.Response.Cache.SetMaxAge(TimeSpan.Zero);
            }
        }
예제 #4
0
 private static IDictionary<string, object> GetRawParamsFromGetRequest(HttpContext context, JavaScriptSerializer serializer, WebServiceMethodData methodData) {
     // Get all the parameters from the query string
     NameValueCollection queryString = context.Request.QueryString;
     Dictionary<string, object> rawParams = new Dictionary<string, object>();
     foreach (WebServiceParameterData param in methodData.ParameterDatas) {
         string name = param.ParameterInfo.Name;
         string val = queryString[name];
         if (val != null) {
             rawParams.Add(name, serializer.DeserializeObject(val));
         }
     }
     return rawParams;
 }
예제 #5
0
        internal WebServiceMethodData GetMethodData(string methodName)
        {
            EnsureMethods();

            // Fail if the web method doesn't exist
            WebServiceMethodData methodData = null;

            if (!_methods.TryGetValue(methodName, out methodData))
            {
                throw new ArgumentException(
                          String.Format(CultureInfo.CurrentCulture, AtlasWeb.WebService_UnknownWebMethod, methodName), "methodName");
            }

            EnsureClientTypesProcessed();
            return(methodData);
        }
예제 #6
0
        internal static void ExecuteWebServiceCall(HttpContext context, WebServiceMethodData methodData)
        {
            try {
                NamedPermissionSet s_permissionSet = HttpRuntime.NamedPermissionSet;
                if (s_permissionSet != null)
                {
                    s_permissionSet.PermitOnly();
                }

                // Deserialize the javascript request body
                IDictionary <string, object> rawParams = GetRawParams(methodData, context);
                InvokeMethod(context, methodData, rawParams);
            }
            catch (Exception ex) {
                WriteExceptionJsonString(context, ex);
            }
        }
예제 #7
0
        private static IHttpHandler CreateHandler(WebServiceData webServiceData, string methodName)
        {
            // Get the data about the method being called
            WebServiceMethodData methodData = webServiceData.GetMethodData(methodName);

            // Create the proper handler, depending on whether we need session state
            RestHandler handler;

            if (methodData.RequiresSession)
            {
                handler = new RestHandlerWithSession();
            }
            else
            {
                handler = new RestHandler();
            }

            // Save the method data in the handler
            handler._webServiceMethodData = methodData;
            return(handler);
        }
예제 #8
0
        // This is very similar to WebService caching, the differences are
        // 1) Here we explicitely SetValidUntilExpires(true) because in an XmlHttp there is
        //    "pragma:no-cache" in header which would result in cache miss on the server.
        // 2) Here we don't vary on header "Content-type" or "SOAPAction" because the former
        //    is specific to soap 1.2, which puts action in the content-type param; and the
        //    later is used by soap calls.
        private static void InitializeCachePolicy(WebServiceMethodData methodData, HttpContext context) {
            int cacheDuration = methodData.CacheDuration;
            if (cacheDuration > 0) {
                context.Response.Cache.SetCacheability(HttpCacheability.Server);
                context.Response.Cache.SetExpires(DateTime.Now.AddSeconds(cacheDuration));
                context.Response.Cache.SetSlidingExpiration(false);
                context.Response.Cache.SetValidUntilExpires(true);

                // DevDiv 23596: Don't set VaryBy* if the method takes no parameters
                if (methodData.ParameterDatas.Count > 0) {
                    context.Response.Cache.VaryByParams["*"] = true;
                }
                else {
                    context.Response.Cache.VaryByParams.IgnoreParams = true;
                }
            }
            else {
                context.Response.Cache.SetNoServerCaching();
                context.Response.Cache.SetMaxAge(TimeSpan.Zero);
            }
        }
예제 #9
0
 private void BuildArgsDictionary(WebServiceMethodData methodData, StringBuilder args, StringBuilder argsDict, StringBuilder docComments)
 {
     argsDict.Append('{');
     foreach (WebServiceParameterData paramData in methodData.ParameterDatas)
     {
         string name = paramData.ParameterName;
         if (docComments != null)
         {
             // looks like: /// <param name="foo" type="ClientType">Namespace.ServerType</param>
             // client type may not match server type for built in js types like date, number, etc.
             // client type may be omitted for type Object.
             docComments.Append("/// <param name=\"").Append(name).Append("\"");
             Type   serverType = ServicesUtilities.UnwrapNullableType(paramData.ParameterType);
             string clientType = GetClientTypeNamespace(ServicesUtilities.GetClientTypeFromServerType(methodData.Owner, serverType));
             if (!String.IsNullOrEmpty(clientType))
             {
                 docComments.Append(" type=\"").Append(clientType).Append("\"");
             }
             docComments.Append(">").Append(serverType.FullName).Append("</param>\r\n");
         }
         if (args.Length > 0)
         {
             args.Append(',');
             argsDict.Append(',');
         }
         args.Append(name);
         argsDict.Append(name).Append(':').Append(name);
     }
     if (docComments != null)
     {
         // append the built-in comments that all methods have (success, failed, usercontext parameters)
         docComments.Append(DebugXmlComments);
     }
     argsDict.Append("}");
     if (args.Length > 0)
     {
         args.Append(',');
     }
     args.Append("succeededCallback, failedCallback, userContext");
 }
예제 #10
0
        private void GenerateWebMethodProxy(WebServiceMethodData methodData)
        {
            string methodName = methodData.MethodName;
            string typeName   = GetProxyTypeName(methodData.Owner);
            string useGet     = methodData.UseGet ? "true" : "false";

            _builder.Append(methodName).Append(':');
            // e.g. MyMethod : function(param1, param2, ..., OnSuccess, OnFailure)
            StringBuilder args              = new StringBuilder();
            StringBuilder argsDict          = new StringBuilder();
            StringBuilder docComments       = null;
            string        docCommentsString = null;

            if (_debugMode)
            {
                docComments = new StringBuilder();
            }
            BuildArgsDictionary(methodData, args, argsDict, docComments);

            if (_debugMode)
            {
                // Remember the doc comments for the static instance case
                docCommentsString            = docComments.ToString();
                _docCommentCache[methodName] = docCommentsString;
            }

            // Method calls look like this.invoke(FooNS.Sub.Method.get_path(), 'MethodName', true[useGet], {'arg1':'val1', 'arg2':'val2' }, onComplete, onError, userContext, 'FooNS.Sub.Method')
            _builder.Append("function(").Append(args.ToString()).Append(") {\r\n");
            if (_debugMode)
            {
                // docCommentsString always end in \r\n
                _builder.Append(docCommentsString);
            }
            _builder.Append("return this._invoke(this._get_path(), ");
            _builder.Append("'").Append(methodName).Append("',");
            _builder.Append(useGet).Append(',');
            _builder.Append(argsDict.ToString()).Append(",succeededCallback,failedCallback,userContext); }");
        }
예제 #11
0
        private void AddMethod(Dictionary <string, WebServiceMethodData> methods, MethodInfo method)
        {
            object[] wmAttribs = method.GetCustomAttributes(typeof(WebMethodAttribute), true);

            // Skip it if it doesn't have the WebMethod attribute
            if (wmAttribs.Length == 0)
            {
                return;
            }

            ScriptMethodAttribute sm = null;

            object[] responseAttribs = method.GetCustomAttributes(typeof(ScriptMethodAttribute), true);
            if (responseAttribs.Length > 0)
            {
                sm = (ScriptMethodAttribute)responseAttribs[0];
            }

            // Create an object to keep track of this method's data
            WebServiceMethodData wmd = new WebServiceMethodData(this, method, (WebMethodAttribute)wmAttribs[0], sm);

            methods[wmd.MethodName] = wmd;
        }
예제 #12
0
        private static IDictionary <string, object> GetRawParamsFromGetRequest(HttpContext context, JavaScriptSerializer serializer, WebServiceMethodData methodData)
        {
            // Get all the parameters from the query string
            NameValueCollection         queryString = context.Request.QueryString;
            Dictionary <string, object> rawParams   = new Dictionary <string, object>();

            foreach (WebServiceParameterData param in methodData.ParameterDatas)
            {
                string name = param.ParameterInfo.Name;
                string val  = queryString[name];
                if (val != null)
                {
                    rawParams.Add(name, serializer.DeserializeObject(val));
                }
            }
            return(rawParams);
        }
예제 #13
0
        private void AddMethod(Dictionary<string, WebServiceMethodData> methods, MethodInfo method) {
            object[] wmAttribs = method.GetCustomAttributes(typeof(WebMethodAttribute), true);

            // Skip it if it doesn't have the WebMethod attribute
            if (wmAttribs.Length == 0)
                return;

            ScriptMethodAttribute sm = null;
            object[] responseAttribs = method.GetCustomAttributes(typeof(ScriptMethodAttribute), true);
            if (responseAttribs.Length > 0) {
                sm = (ScriptMethodAttribute)responseAttribs[0];
            }

            // Create an object to keep track of this method's data
            WebServiceMethodData wmd = new WebServiceMethodData(this, method, (WebMethodAttribute)wmAttribs[0], sm);
            methods[wmd.MethodName] = wmd;
        }
 private  void BuildArgsDictionary(WebServiceMethodData methodData, StringBuilder args, StringBuilder argsDict, StringBuilder docComments) {
     argsDict.Append('{');
     foreach (WebServiceParameterData paramData in methodData.ParameterDatas) {
         string name = paramData.ParameterName;
         if (docComments != null) {
             // looks like: /// <param name="foo" type="ClientType">Namespace.ServerType</param>
             // client type may not match server type for built in js types like date, number, etc.
             // client type may be omitted for type Object.
             docComments.Append("/// <param name=\"").Append(name).Append("\"");
             Type serverType = ServicesUtilities.UnwrapNullableType(paramData.ParameterType);
             string clientType = GetClientTypeNamespace(ServicesUtilities.GetClientTypeFromServerType(methodData.Owner, serverType));
             if (!String.IsNullOrEmpty(clientType)) {
                 docComments.Append(" type=\"").Append(clientType).Append("\"");
             }
             docComments.Append(">").Append(serverType.FullName).Append("</param>\r\n");
         }
         if (args.Length > 0) {
             args.Append(',');
             argsDict.Append(',');
         }
         args.Append(name);
         argsDict.Append(name).Append(':').Append(name);
     }
     if (docComments != null) {
         // append the built-in comments that all methods have (success, failed, usercontext parameters)
         docComments.Append(DebugXmlComments);
     }
     argsDict.Append("}");
     if (args.Length > 0) {
         args.Append(',');
     }
     args.Append("succeededCallback, failedCallback, userContext");
 }
        private void GenerateWebMethodProxy(WebServiceMethodData methodData) {
            string methodName = methodData.MethodName;
            string typeName = GetProxyTypeName(methodData.Owner);
            string useGet = methodData.UseGet ? "true" : "false";

            _builder.Append(methodName).Append(':');
            // e.g. MyMethod : function(param1, param2, ..., OnSuccess, OnFailure)
            StringBuilder args = new StringBuilder();
            StringBuilder argsDict = new StringBuilder();
            StringBuilder docComments = null;
            string docCommentsString = null;
            if (_debugMode) {
                docComments = new StringBuilder();
            }
            BuildArgsDictionary(methodData, args, argsDict, docComments);

            if (_debugMode) {
                // Remember the doc comments for the static instance case
                docCommentsString = docComments.ToString();
                _docCommentCache[methodName] = docCommentsString;
            }

            // Method calls look like this.invoke(FooNS.Sub.Method.get_path(), 'MethodName', true[useGet], {'arg1':'val1', 'arg2':'val2' }, onComplete, onError, userContext, 'FooNS.Sub.Method')
            _builder.Append("function(").Append(args.ToString()).Append(") {\r\n");
            if (_debugMode) {
                // docCommentsString always end in \r\n
                _builder.Append(docCommentsString);
            }
            _builder.Append("return this._invoke(this._get_path(), ");
            _builder.Append("'").Append(methodName).Append("',");
            _builder.Append(useGet).Append(',');
            _builder.Append(argsDict.ToString()).Append(",succeededCallback,failedCallback,userContext); }");
        }
예제 #16
0
 private static IDictionary<string, object> GetRawParams(WebServiceMethodData methodData, HttpContext context) {
     if (methodData.UseGet) {
         if (context.Request.HttpMethod == "GET") {
             return GetRawParamsFromGetRequest(context, methodData.Owner.Serializer, methodData);
         }
         else {
             throw new InvalidOperationException(
                 String.Format(CultureInfo.CurrentCulture, AtlasWeb.WebService_InvalidVerbRequest,
                     methodData.MethodName, "POST"));
         }
     }
     else if (context.Request.HttpMethod == "POST") {
         return GetRawParamsFromPostRequest(context, methodData.Owner.Serializer);
     } else {
         throw new InvalidOperationException(
             String.Format(CultureInfo.CurrentCulture, AtlasWeb.WebService_InvalidVerbRequest,
                 methodData.MethodName, "GET"));
     }
 }
예제 #17
0
        private static void InvokeMethod(HttpContext context, WebServiceMethodData methodData, IDictionary<string, object> rawParams) {
            // Initialize HttpCachePolicy
            InitializeCachePolicy(methodData, context);

            // Create an new instance of the class
            object target = null;
            if (!methodData.IsStatic) target = Activator.CreateInstance(methodData.Owner.TypeData.Type);

            // Make the actual method call on it
            object retVal = methodData.CallMethodFromRawParams(target, rawParams);

            string contentType;
            string responseString = null;
            if (methodData.UseXmlResponse) {
                responseString = retVal as string;

                // If it's a string, output it as is unless XmlSerializeString is set
                if (responseString == null || methodData.XmlSerializeString) {
                    // Use the Xml Serializer
                    try {
                        responseString = ServicesUtilities.XmlSerializeObjectToString(retVal);
                    }
                    catch (Exception e) {
                        // Throw a better error if Xml serialization fails
                        throw new InvalidOperationException(
                            String.Format(CultureInfo.CurrentCulture, AtlasWeb.WebService_InvalidXmlReturnType,
                                methodData.MethodName, retVal.GetType().FullName, e.Message));
                    }
                }

                contentType = "text/xml";
            }
            else {

                // Convert the result to a JSON string
                // DevDiv 88409:Change JSON wire format to prevent CSRF attack 
                // We wrap the returned value inside an object , and assign the returned value
                // to member "d" of the object. We do so as JSOM for object will never be parsed
                // as valid Javascript , unlike arrays.
                responseString =@"{""d"":" + methodData.Owner.Serializer.Serialize(retVal) + "}";
                contentType = "application/json";
            }

            // Set the response content-type
            context.Response.ContentType = contentType;

            // Write the string to the response
            if (responseString != null)
                context.Response.Write(responseString);
        }
        static WebServiceData GetWebServiceData(ContractDescription contract) 
        {
            WebServiceData serviceData = new WebServiceData();

            //build method dictionary
            Dictionary<string, WebServiceMethodData> methodDataDictionary = new Dictionary<string, WebServiceMethodData>();
            
            // set service type
            serviceData.Initialize(new WebServiceTypeData(XmlConvert.DecodeName(contract.Name), XmlConvert.DecodeName(contract.Namespace), contract.ContractType),
                methodDataDictionary);

            foreach (OperationDescription operation in contract.Operations) 
            {
                Dictionary<string, WebServiceParameterData> parameterDataDictionary = new Dictionary<string, WebServiceParameterData>();
                bool useHttpGet = operation.Behaviors.Find<WebGetAttribute>() != null;
                WebServiceMethodData methodData = new WebServiceMethodData(serviceData, XmlConvert.DecodeName(operation.Name), parameterDataDictionary, useHttpGet);
                // build parameter dictionary
                MessageDescription requestMessage = operation.Messages[0];
                if (requestMessage != null) 
                {
                    int numMessageParts = requestMessage.Body.Parts.Count;
                    for (int p = 0; p < numMessageParts; p++) 
                    {
                        MessagePartDescription messagePart = requestMessage.Body.Parts[p];
                        // DevDiv 129964:JS proxy generation fails for a WCF service that uses an untyped message
                        // Message or its derived class are special, used for untyped operation contracts. 
                        // As per the WCF team proxy generated for them should treat Message equivalent to Object type.
                        Type paramType = ReplaceMessageWithObject(messagePart.Type);
                        WebServiceParameterData parameterData = new WebServiceParameterData(XmlConvert.DecodeName(messagePart.Name), paramType, p);
                        parameterDataDictionary[parameterData.ParameterName] = parameterData;
                        serviceData.ProcessClientType(paramType, false, true);
                    }
                }
                if (operation.Messages.Count > 1) 
                {
                    // its a two way operation, get type information from return message
                    MessageDescription responseMessage = operation.Messages[1];
                    if (responseMessage != null) 
                    {
                        if (responseMessage.Body.ReturnValue != null && responseMessage.Body.ReturnValue.Type != null) 
                        {
                            // operation has a return type, add type to list of type proxy to generate
                            serviceData.ProcessClientType(ReplaceMessageWithObject(responseMessage.Body.ReturnValue.Type), false, true);
                        }
                    }
                }

                //add known types at operation level
                for (int t = 0; t < operation.KnownTypes.Count; t++) 
                {
                    serviceData.ProcessClientType(operation.KnownTypes[t], false, true);
                }

                methodDataDictionary[methodData.MethodName] = methodData;
            }
            serviceData.ClearProcessedTypes();
            return serviceData;

        }
예제 #19
0
        internal static void ExecuteWebServiceCall(HttpContext context, WebServiceMethodData methodData) {
            try {
                NamedPermissionSet s_permissionSet = HttpRuntime.NamedPermissionSet;
                if (s_permissionSet != null) {
                    s_permissionSet.PermitOnly();
                }

                // Deserialize the javascript request body
                IDictionary<string, object> rawParams = GetRawParams(methodData, context);
                InvokeMethod(context, methodData, rawParams);
            }
            catch (Exception ex) {
                WriteExceptionJsonString(context, ex);
            }
        }