// This constructor is only used by WCF. Owener, MethodName, ParameterDataDictionary, ParamterData // are the only valid properties in WCF case. internal WebServiceMethodData(WebServiceData owner, string methodName, Dictionary <string, WebServiceParameterData> parameterData, bool useHttpGet) { _owner = owner; _methodName = methodName; _parameterData = parameterData; _useHttpGet = useHttpGet; }
// Called by ScriptManager to generate the proxy inline internal static string GetInlineClientProxyScript(string path, HttpContext context, bool debug) { WebServiceData webServiceData = WebServiceData.GetWebServiceData(context, path, true, false, true); WebServiceClientProxyGenerator proxyGenerator = new WebServiceClientProxyGenerator(path, debug); return(proxyGenerator.GetClientProxyScript(webServiceData)); }
protected void GenerateRegisterClass(WebServiceData webServiceData) { // Generate registerClass: Foo.NS.WebService.registerClass('Foo.NS.WebService', Sys.Net.WebServiceProxy); string typeName = GetProxyTypeName(webServiceData); _builder.Append(typeName).Append(".registerClass('").Append(typeName).Append("',Sys.Net.WebServiceProxy);\r\n"); }
protected virtual void GenerateConstructor(WebServiceData webServiceData) { GenerateTypeDeclaration(webServiceData, false); _builder.Append("function() {\r\n"); _builder.Append(GetProxyTypeName(webServiceData)).Append(".initializeBase(this);\r\n"); GenerateFields(); _builder.Append("}\r\n"); }
/* e.g * var Qqq = function() { this.__type = "Qqq"; } */ private void GenerateClientTypeProxies(WebServiceData data) { bool first = true; foreach (WebServiceTypeData t in data.ClientTypes) { if (first) { _builder.Append("var gtc = Sys.Net.WebServiceProxy._generateTypedConstructor;\r\n"); first = false; } string typeID = data.GetTypeStringRepresentation(t); string typeNameWithClientNamespace = GetClientTypeNamespace(t.TypeName); string typeName = ServicesUtilities.GetClientTypeName(typeNameWithClientNamespace); string clientTypeNamespace = GetClientTypeNamespace(t.TypeNamespace); EnsureNamespace(t.TypeNamespace); EnsureObjectGraph(clientTypeNamespace, typeName); _builder.Append("if (typeof(").Append(typeName).Append(") === 'undefined') {\r\n"); AppendClientTypeDeclaration(clientTypeNamespace, typeNameWithClientNamespace, false, false); // Need to use the _type id, which isn't necessarly the real name _builder.Append("gtc(\""); _builder.Append(typeID); _builder.Append("\");\r\n"); _builder.Append(typeName).Append(".registerClass('").Append(typeName).Append("');\r\n}\r\n"); } }
internal string GetClientProxyScript(WebServiceData webServiceData) { if (webServiceData.MethodDatas.Count == 0) { return(null); } _builder = new StringBuilder(); if (_debugMode) { _docCommentCache = new Dictionary <string, string>(); } // Constructor GenerateConstructor(webServiceData); // Prototype functions GeneratePrototype(webServiceData); GenerateRegisterClass(webServiceData); GenerateStaticInstance(webServiceData); GenerateStaticMethods(webServiceData); // Generate some client proxy to make some types instantiatable on the client GenerateClientTypeProxies(webServiceData); GenerateEnumTypeProxies(webServiceData.EnumTypes); return(_builder.ToString()); }
protected virtual void GenerateConstructor(WebServiceData webServiceData) { GenerateTypeDeclaration(webServiceData, false); _builder.Append("function() {\r\n"); _builder.Append(GetProxyTypeName(webServiceData)).Append(".initializeBase(this);\r\n"); GenerateFields(); _builder.Append("}\r\n"); }
protected override void GenerateTypeDeclaration(WebServiceData webServiceData, bool genClass) { if (genClass) { _builder.Append("PageMethods.prototype = "); } else { _builder.Append("var PageMethods = "); } }
internal WebServiceMethodData(WebServiceData owner, MethodInfo methodInfo, WebMethodAttribute webMethodAttribute, ScriptMethodAttribute scriptMethodAttribute) { _owner = owner; _methodInfo = methodInfo; _webMethodAttribute = webMethodAttribute; _methodName = _webMethodAttribute.MessageName; _scriptMethodAttribute = scriptMethodAttribute; if (String.IsNullOrEmpty(_methodName)) { _methodName = methodInfo.Name; } }
protected override void GenerateTypeDeclaration(WebServiceData webServiceData, bool genClass) { if (genClass) { _builder.Append("PageMethods.prototype = "); } else { _builder.Append("var PageMethods = "); } }
internal WebServiceMethodData(WebServiceData owner, MethodInfo methodInfo, WebMethodAttribute webMethodAttribute, ScriptMethodAttribute scriptMethodAttribute) { _owner = owner; _methodInfo = methodInfo; _webMethodAttribute = webMethodAttribute; _methodName = _webMethodAttribute.MessageName; _scriptMethodAttribute = scriptMethodAttribute; if (String.IsNullOrEmpty(_methodName)) { _methodName = methodInfo.Name; } }
public static string GetClientProxyScript(Type type, string path, bool debug, ServiceEndpoint serviceEndpoint) { if (type == null) { throw new ArgumentNullException("type"); } if (path == null) { throw new ArgumentNullException("path"); } WebServiceData webServiceData = null; ClientProxyGenerator proxyGenerator = null; if (IsWebServiceType(type)) { proxyGenerator = new WebServiceClientProxyGenerator(path, debug); webServiceData = new WebServiceData(type, false); } else if (IsPageType(type)) { proxyGenerator = new PageClientProxyGenerator(path, debug); webServiceData = new WebServiceData(type, true); } else if (IsWCFServiceType(type)) { // invoke the WCFServiceClientProxyGenerator.GetClientProxyScript method using reflection Assembly wcfWebAssembly = Assembly.Load(AssemblyRef.SystemServiceModelWeb); if (wcfWebAssembly != null) { Type wcfProxyType = wcfWebAssembly.GetType(WCFProxyTypeName); if (wcfProxyType != null) { MethodInfo getClientProxyMethod = wcfProxyType.GetMethod(WCFProxyMethodName, BindingFlags.Static | BindingFlags.NonPublic); if (getClientProxyMethod != null) { return(getClientProxyMethod.Invoke(null, new object[] { type, path, debug, serviceEndpoint }) as string); } } } // in case the reflection fails, we should throw unsupported exception throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.ProxyGenerator_UnsupportedType, type.FullName)); } else { throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.ProxyGenerator_UnsupportedType, type.FullName)); } return(proxyGenerator.GetClientProxyScript(webServiceData)); }
internal static IHttpHandler CreateHandler(HttpContext context) { // Expectation is that we got a PathInfo of form /MethodName if (context.Request.PathInfo.Length < 2 || context.Request.PathInfo[0] != '/') { throw new InvalidOperationException(AtlasWeb.WebService_InvalidWebServiceCall); } // Get the data about the web service being invoked WebServiceData webServiceData = WebServiceData.GetWebServiceData(context, context.Request.FilePath); string methodName = context.Request.PathInfo.Substring(1); return(CreateHandler(webServiceData, methodName)); }
protected virtual void GeneratePrototype(WebServiceData webServiceData) { GenerateTypeDeclaration(webServiceData, true); _builder.Append("{\r\n"); // private method to return the path to be used , returns _path from current instance if set, otherwise returns _path from static instance. _builder.Append("_get_path:function() {\r\n var p = this.get_path();\r\n if (p) return p;\r\n else return "); _builder.Append(GetProxyTypeName(webServiceData)).Append("._staticInstance.get_path();},\r\n"); bool first = true; foreach (WebServiceMethodData methodData in webServiceData.MethodDatas) { if (!first) { _builder.Append(",\r\n"); } first = false; GenerateWebMethodProxy(methodData); } _builder.Append("}\r\n"); }
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; }
internal static string GetClientProxyScript(HttpContext context) { WebServiceData webServiceData = WebServiceData.GetWebServiceData(context, context.Request.FilePath); DateTime lastModifiedDate = GetAssemblyModifiedTime(webServiceData.TypeData.Type.Assembly); // If the browser sent this header, we can check if we need to resend string modifiedSince = context.Request.Headers["If-Modified-Since"]; if (modifiedSince != null) { DateTime header; if (DateTime.TryParse(modifiedSince, out header)) { // We are done if the assembly hasn't been modified if (header >= lastModifiedDate) { context.Response.StatusCode = 304; return(null); } } } bool debug = RestHandlerFactory.IsClientProxyDebugRequest(context.Request.PathInfo); // Only cache for release proxy script (/js) if (!debug) { // Only cache if we get a reasonable last modified date if (lastModifiedDate.ToUniversalTime() < DateTime.UtcNow) { // Cache the resource so we don't keep processing the same requests HttpCachePolicy cachePolicy = context.Response.Cache; cachePolicy.SetCacheability(HttpCacheability.Public); cachePolicy.SetLastModified(lastModifiedDate); // expires is necessary so that the browser at least does an If-Modified-Since request on every request. // without that, the browser wouldn't request a new proxy until the user hits refresh. // Use one year ago to reasonably ensure "past" interpretation cachePolicy.SetExpires(lastModifiedDate.AddYears(-1)); } } WebServiceClientProxyGenerator proxyGenerator = new WebServiceClientProxyGenerator(context.Request.FilePath, debug); return(proxyGenerator.GetClientProxyScript(webServiceData)); }
public static string GetClientProxyScript(Type type, string path, bool debug, ServiceEndpoint serviceEndpoint) { if (type == null) { throw new ArgumentNullException("type"); } if (path == null) { throw new ArgumentNullException("path"); } WebServiceData webServiceData = null; ClientProxyGenerator proxyGenerator = null; if (IsWebServiceType(type)) { proxyGenerator = new WebServiceClientProxyGenerator(path, debug); webServiceData = new WebServiceData(type, false); } else if (IsPageType(type)) { proxyGenerator = new PageClientProxyGenerator(path, debug); webServiceData = new WebServiceData(type, true); } else if(IsWCFServiceType(type)) { // invoke the WCFServiceClientProxyGenerator.GetClientProxyScript method using reflection Assembly wcfWebAssembly = Assembly.Load(AssemblyRef.SystemServiceModelWeb); if (wcfWebAssembly != null) { Type wcfProxyType = wcfWebAssembly.GetType(WCFProxyTypeName); if (wcfProxyType != null) { MethodInfo getClientProxyMethod = wcfProxyType.GetMethod(WCFProxyMethodName, BindingFlags.Static | BindingFlags.NonPublic); if (getClientProxyMethod != null) { return getClientProxyMethod.Invoke(null, new object[] { type, path, debug, serviceEndpoint }) as string; } } } // in case the reflection fails, we should throw unsupported exception throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.ProxyGenerator_UnsupportedType, type.FullName)); } else { throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.ProxyGenerator_UnsupportedType, type.FullName)); } return proxyGenerator.GetClientProxyScript(webServiceData); }
protected void GenerateStaticMethods(WebServiceData webServiceData) { string className = GetProxyTypeName(webServiceData); // Now generate static methods NS.Service.MyMethod = function() foreach (WebServiceMethodData methodData in webServiceData.MethodDatas) { string methodName = methodData.MethodName; _builder.Append(className).Append('.').Append(methodName).Append("= function("); StringBuilder argBuilder = new StringBuilder(); bool first = true; foreach (WebServiceParameterData paramData in methodData.ParameterDatas) { if (!first) { argBuilder.Append(','); } else { first = false; } argBuilder.Append(paramData.ParameterName); } if (!first) { argBuilder.Append(','); } argBuilder.Append("onSuccess,onFailed,userContext"); _builder.Append(argBuilder.ToString()).Append(") {"); if (_debugMode) { // doc comments should have been computed already _builder.Append("\r\n"); _builder.Append(_docCommentCache[methodName]); } _builder.Append(className).Append("._staticInstance.").Append(methodName).Append('('); _builder.Append(argBuilder.ToString()).Append("); }\r\n"); } }
protected virtual void GeneratePrototype(WebServiceData webServiceData) { GenerateTypeDeclaration(webServiceData, true); _builder.Append("{\r\n"); // private method to return the path to be used , returns _path from current instance if set, otherwise returns _path from static instance. _builder.Append("_get_path:function() {\r\n var p = this.get_path();\r\n if (p) return p;\r\n else return "); _builder.Append(GetProxyTypeName(webServiceData)).Append("._staticInstance.get_path();},\r\n"); bool first = true; foreach (WebServiceMethodData methodData in webServiceData.MethodDatas) { if (!first) { _builder.Append(",\r\n"); } first = false; GenerateWebMethodProxy(methodData); } _builder.Append("}\r\n"); }
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); }
internal static string GetClientProxyScript(HttpContext context, IPage page, bool debug) { // Do nothing during unit tests which have no context or page if (context == null || page == null) { return(null); } WebServiceData webServiceData = WebServiceData.GetWebServiceData(context, page.AppRelativeVirtualPath, false /*failIfNoData*/, true /*pageMethods */); if (webServiceData == null) { return(null); } PageClientProxyGenerator proxyGenerator = new PageClientProxyGenerator(page, debug); return(proxyGenerator.GetClientProxyScript(webServiceData)); }
internal string GetClientProxyScript(WebServiceData webServiceData) { if (webServiceData.MethodDatas.Count == 0) return null; _builder = new StringBuilder(); if (_debugMode) { _docCommentCache = new Dictionary<string, string>(); } // Constructor GenerateConstructor(webServiceData); // Prototype functions GeneratePrototype(webServiceData); GenerateRegisterClass(webServiceData); GenerateStaticInstance(webServiceData); GenerateStaticMethods(webServiceData); // Generate some client proxy to make some types instantiatable on the client GenerateClientTypeProxies(webServiceData); GenerateEnumTypeProxies(webServiceData.EnumTypes); return _builder.ToString(); }
// This constructor is only used by WCF. Owener, MethodName, ParameterDataDictionary, ParamterData // are the only valid properties in WCF case. internal WebServiceMethodData(WebServiceData owner, string methodName, Dictionary<string, WebServiceParameterData> parameterData, bool useHttpGet) { _owner = owner; _methodName = methodName; _parameterData = parameterData; _useHttpGet = useHttpGet; }
protected override string GetProxyTypeName(WebServiceData data) { return "PageMethods"; }
protected void GenerateStaticInstance(WebServiceData data) { string typeName = GetProxyTypeName(data); _builder.Append(typeName).Append("._staticInstance = new ").Append(typeName).Append("();\r\n"); // Generate the static properties if (_debugMode) { _builder.Append(typeName).Append(".set_path = function(value) {\r\n"); _builder.Append(typeName).Append("._staticInstance.set_path(value); }\r\n"); _builder.Append(typeName).Append(".get_path = function() { \r\n/// <value type=\"String\" mayBeNull=\"true\">The service url.</value>\r\nreturn "); _builder.Append(typeName).Append("._staticInstance.get_path();}\r\n"); _builder.Append(typeName).Append(".set_timeout = function(value) {\r\n"); _builder.Append(typeName).Append("._staticInstance.set_timeout(value); }\r\n"); _builder.Append(typeName).Append(".get_timeout = function() { \r\n/// <value type=\"Number\">The service timeout.</value>\r\nreturn "); _builder.Append(typeName).Append("._staticInstance.get_timeout(); }\r\n"); _builder.Append(typeName).Append(".set_defaultUserContext = function(value) { \r\n"); _builder.Append(typeName).Append("._staticInstance.set_defaultUserContext(value); }\r\n"); _builder.Append(typeName).Append(".get_defaultUserContext = function() { \r\n/// <value mayBeNull=\"true\">The service default user context.</value>\r\nreturn "); _builder.Append(typeName).Append("._staticInstance.get_defaultUserContext(); }\r\n"); _builder.Append(typeName).Append(".set_defaultSucceededCallback = function(value) { \r\n "); _builder.Append(typeName).Append("._staticInstance.set_defaultSucceededCallback(value); }\r\n"); _builder.Append(typeName).Append(".get_defaultSucceededCallback = function() { \r\n/// <value type=\"Function\" mayBeNull=\"true\">The service default succeeded callback.</value>\r\nreturn "); _builder.Append(typeName).Append("._staticInstance.get_defaultSucceededCallback(); }\r\n"); _builder.Append(typeName).Append(".set_defaultFailedCallback = function(value) { \r\n"); _builder.Append(typeName).Append("._staticInstance.set_defaultFailedCallback(value); }\r\n"); _builder.Append(typeName).Append(".get_defaultFailedCallback = function() { \r\n/// <value type=\"Function\" mayBeNull=\"true\">The service default failed callback.</value>\r\nreturn "); _builder.Append(typeName).Append("._staticInstance.get_defaultFailedCallback(); }\r\n"); _builder.Append(typeName).Append(".set_enableJsonp = function(value) { "); _builder.Append(typeName).Append("._staticInstance.set_enableJsonp(value); }\r\n"); _builder.Append(typeName).Append(".get_enableJsonp = function() { \r\n/// <value type=\"Boolean\">Specifies whether the service supports JSONP for cross domain calling.</value>\r\nreturn "); _builder.Append(typeName).Append("._staticInstance.get_enableJsonp(); }\r\n"); _builder.Append(typeName).Append(".set_jsonpCallbackParameter = function(value) { "); _builder.Append(typeName).Append("._staticInstance.set_jsonpCallbackParameter(value); }\r\n"); _builder.Append(typeName).Append(".get_jsonpCallbackParameter = function() { \r\n/// <value type=\"String\">Specifies the parameter name that contains the callback function name for a JSONP request.</value>\r\nreturn "); _builder.Append(typeName).Append("._staticInstance.get_jsonpCallbackParameter(); }\r\n"); } else { _builder.Append(typeName).Append(".set_path = function(value) { "); _builder.Append(typeName).Append("._staticInstance.set_path(value); }\r\n"); _builder.Append(typeName).Append(".get_path = function() { return "); _builder.Append(typeName).Append("._staticInstance.get_path(); }\r\n"); _builder.Append(typeName).Append(".set_timeout = function(value) { "); _builder.Append(typeName).Append("._staticInstance.set_timeout(value); }\r\n"); _builder.Append(typeName).Append(".get_timeout = function() { return "); _builder.Append(typeName).Append("._staticInstance.get_timeout(); }\r\n"); _builder.Append(typeName).Append(".set_defaultUserContext = function(value) { "); _builder.Append(typeName).Append("._staticInstance.set_defaultUserContext(value); }\r\n"); _builder.Append(typeName).Append(".get_defaultUserContext = function() { return "); _builder.Append(typeName).Append("._staticInstance.get_defaultUserContext(); }\r\n"); _builder.Append(typeName).Append(".set_defaultSucceededCallback = function(value) { "); _builder.Append(typeName).Append("._staticInstance.set_defaultSucceededCallback(value); }\r\n"); _builder.Append(typeName).Append(".get_defaultSucceededCallback = function() { return "); _builder.Append(typeName).Append("._staticInstance.get_defaultSucceededCallback(); }\r\n"); _builder.Append(typeName).Append(".set_defaultFailedCallback = function(value) { "); _builder.Append(typeName).Append("._staticInstance.set_defaultFailedCallback(value); }\r\n"); _builder.Append(typeName).Append(".get_defaultFailedCallback = function() { return "); _builder.Append(typeName).Append("._staticInstance.get_defaultFailedCallback(); }\r\n"); _builder.Append(typeName).Append(".set_enableJsonp = function(value) { "); _builder.Append(typeName).Append("._staticInstance.set_enableJsonp(value); }\r\n"); _builder.Append(typeName).Append(".get_enableJsonp = function() { return "); _builder.Append(typeName).Append("._staticInstance.get_enableJsonp(); }\r\n"); _builder.Append(typeName).Append(".set_jsonpCallbackParameter = function(value) { "); _builder.Append(typeName).Append("._staticInstance.set_jsonpCallbackParameter(value); }\r\n"); _builder.Append(typeName).Append(".get_jsonpCallbackParameter = function() { return "); _builder.Append(typeName).Append("._staticInstance.get_jsonpCallbackParameter(); }\r\n"); } // the path has to be the full absolete path if this is a JSONP enabled service. But it is the responsibility // of the caller to GetClientProxyScript to pass the full path if appropriate since determining it may be // dependant on the specific technology. string proxyPath = GetProxyPath(); if (!String.IsNullOrEmpty(proxyPath) && (proxyPath.StartsWith("http://", StringComparison.OrdinalIgnoreCase) || proxyPath.StartsWith("https://", StringComparison.OrdinalIgnoreCase))) { // DevDiv 91322: avoid url encoding the domain portion of an IDN url // find the first "/" after the scheme, and only encode after that. int domainStart = proxyPath.IndexOf("://", StringComparison.OrdinalIgnoreCase) + "://".Length; int domainEnd = proxyPath.IndexOf("/", domainStart, StringComparison.OrdinalIgnoreCase); // if no slash after :// was found, it could be a domain only url, http://[some service].com, don't encode any of it if (domainEnd != -1) { proxyPath = proxyPath.Substring(0, domainEnd) + HttpUtility.UrlPathEncode(proxyPath.Substring(domainEnd)); } } else { // it doesn't appear to be an absolute url, at least not an http or https one. All relative paths // and other oddities are safely encoded with UrlPathEncode. proxyPath = HttpUtility.UrlPathEncode(proxyPath); } _builder.Append(typeName).Append(".set_path(\"").Append(proxyPath).Append("\");\r\n"); if (GetSupportsJsonp()) { _builder.Append(typeName).Append(".set_enableJsonp(true);\r\n"); string jsonpParameterName = GetJsonpCallbackParameterName(); if (!String.IsNullOrEmpty(jsonpParameterName) && !jsonpParameterName.Equals("callback", StringComparison.Ordinal)) { _builder.Append(typeName).Append(".set_jsonpCallbackParameter(").Append(JavaScriptSerializer.SerializeInternal(jsonpParameterName)).Append(");\r\n"); } } }
internal static string GetClientTypeFromServerType(WebServiceData webServiceData, Type type) { // For intellisense purposes, returns a best estimate of what the appropriate client-side type is for a given server type. // Takes generated client proxies and enum proxies into consideration. // The rest is a best guess. // If all else fails we use "", to indicate "any" client side type. "Object" is not the same as any type on the client since // string, for example, is not considered an object. "Object" is equiv to a .net dictionary. if (webServiceData.ClientTypeNameDictionary.ContainsKey(type)) { // if it exists in the client type dictionary, it will have a proxy generated for it //get the client based on type.FullName for ASMX, and schema qualified name and namespace for WCF return(webServiceData.ClientTypeNameDictionary[type]); } if (type.IsEnum) { // there will be a proxy for this enum return(GetClientTypeName(type.FullName)); } // there is no client proxy for it, so it either maps to a built-in js type or it could be "anything" // take care of the most common types if (type == typeof(string) || type == typeof(char)) { return("String"); } else if (type.IsPrimitive) { // The primitive types are Boolean, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64 (long), UInt64, IntPtr, Char, Double, and Single (float). if (type == typeof(bool)) { // bool is the only primitive we shouldnt treat as a number return("Boolean"); } else { // takes care of all ints, float, double, but not decimal since it isnt a primitive // we also consider byte, sbyte, and intptr to be numbers return("Number"); } } if (type.IsValueType) { if (type == typeof(DateTime)) { return("Date"); } else if (type == typeof(Guid)) { return("String"); } else if (type == typeof(Decimal)) { return("Number"); } } if (typeof(IDictionary).IsAssignableFrom(type)) { return("Object"); } // might still be IDictionary<K,T> if (type.IsGenericType) { Type gtd = type; if (!type.IsGenericTypeDefinition) { gtd = type.GetGenericTypeDefinition(); } if (gtd == typeof(IDictionary <,>)) { return("Object"); } } if (type.IsArray || typeof(IEnumerable).IsAssignableFrom(type)) { return("Array"); } // dont know what it is (e.g., TimeSpan), or it is type Object, so allow any client type. return(""); }
protected virtual void GenerateTypeDeclaration(WebServiceData webServiceData, bool genClass) { AppendClientTypeDeclaration(webServiceData.TypeData.TypeNamespace, webServiceData.TypeData.TypeName, genClass, true); }
// Normally returns MyNS.MySubNS.MyWebService OR var MyWebService, PageMethods will return PageMethods protected virtual string GetProxyTypeName(WebServiceData data) { return ServicesUtilities.GetClientTypeName(data.TypeData.TypeName); }
internal static WebServiceData GetWebServiceData(HttpContext context, string virtualPath, bool failIfNoData, bool pageMethods, bool inlineScript) { // Make sure the path is cannonical to avoid doing more work than necessary virtualPath = VirtualPathUtility.ToAbsolute(virtualPath); string cacheKey = GetCacheKey(virtualPath); WebServiceData data = context.Cache[cacheKey] as WebServiceData; // Handle the case where the virtualPath exists, for example a real asmx page. if (data == null) { if (HostingEnvironment.VirtualPathProvider.FileExists(virtualPath)) { Type compiledType = null; try { compiledType = BuildManager.GetCompiledType(virtualPath); // If we can't get the compiled type, try creating an instance (i.e. for no compile pages) if (compiledType == null) { object page = BuildManager.CreateInstanceFromVirtualPath(virtualPath, typeof(System.Web.UI.Page)); if (page != null) { compiledType = page.GetType(); } } } catch (SecurityException) { // DevDiv 33708: BuildManager requires Medium trust, so we need to no-op rather than // destroying the page. } if (compiledType != null) { data = new WebServiceData(compiledType, pageMethods); BuildDependencySet deps = BuildManager.GetCachedBuildDependencySet(context, virtualPath); if (deps != null) { // Dev10 718863: It's possible 'deps' is null if the service is modified between GetCompiledType and here. // in that case simply do not cache the result so it is re-established next time it is required. CacheDependency cd = HostingEnvironment.VirtualPathProvider.GetCacheDependency(virtualPath, deps.VirtualPaths, DateTime.Now); context.Cache.Insert(cacheKey, data, cd); } } } else if (virtualPath.EndsWith("_AppService.axd", StringComparison.OrdinalIgnoreCase)) { // File does not exist, but the url may be a request for one of the three built-in services: ProfileService, AuthenticationService, RoleService data = WebServiceData.GetApplicationService(context.Request.AppRelativeCurrentExecutionFilePath); if (data != null) { context.Cache.Insert(cacheKey, data); } } } if (data == null) { if (failIfNoData) { if (inlineScript) { //DevDiv 74432: InlineScript = true fails, for WCF serviceReferences: Need an appropriate error message throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, AtlasWeb.WebService_NoWebServiceDataInlineScript, virtualPath)); } else { throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, AtlasWeb.WebService_NoWebServiceData, virtualPath)); } } else { return null; } } return data; }
protected void GenerateStaticMethods(WebServiceData webServiceData) { string className = GetProxyTypeName(webServiceData); // Now generate static methods NS.Service.MyMethod = function() foreach (WebServiceMethodData methodData in webServiceData.MethodDatas) { string methodName = methodData.MethodName; _builder.Append(className).Append('.').Append(methodName).Append("= function("); StringBuilder argBuilder = new StringBuilder(); bool first = true; foreach (WebServiceParameterData paramData in methodData.ParameterDatas) { if (!first) argBuilder.Append(','); else first = false; argBuilder.Append(paramData.ParameterName); } if (!first) argBuilder.Append(','); argBuilder.Append("onSuccess,onFailed,userContext"); _builder.Append(argBuilder.ToString()).Append(") {"); if (_debugMode) { // doc comments should have been computed already _builder.Append("\r\n"); _builder.Append(_docCommentCache[methodName]); } _builder.Append(className).Append("._staticInstance.").Append(methodName).Append('('); _builder.Append(argBuilder.ToString()).Append("); }\r\n"); } }
protected override string GetProxyTypeName(WebServiceData data) { return("PageMethods"); }
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; }
protected override string GetProxyTypeName(WebServiceData data) { return GetClientTypeNamespace(data.TypeData.TypeName); }
internal static WebServiceData GetWebServiceData(HttpContext context, string virtualPath, bool failIfNoData, bool pageMethods, bool inlineScript) { // Make sure the path is cannonical to avoid doing more work than necessary virtualPath = VirtualPathUtility.ToAbsolute(virtualPath); string cacheKey = GetCacheKey(virtualPath); WebServiceData data = context.Cache[cacheKey] as WebServiceData; // Handle the case where the virtualPath exists, for example a real asmx page. if (data == null) { if (HostingEnvironment.VirtualPathProvider.FileExists(virtualPath)) { Type compiledType = null; try { compiledType = BuildManager.GetCompiledType(virtualPath); // If we can't get the compiled type, try creating an instance (i.e. for no compile pages) if (compiledType == null) { object page = BuildManager.CreateInstanceFromVirtualPath(virtualPath, typeof(System.Web.UI.Page)); if (page != null) { compiledType = page.GetType(); } } } catch (SecurityException) { // DevDiv 33708: BuildManager requires Medium trust, so we need to no-op rather than // destroying the page. } if (compiledType != null) { data = new WebServiceData(compiledType, pageMethods); BuildDependencySet deps = BuildManager.GetCachedBuildDependencySet(context, virtualPath); if (deps != null) { // Dev10 718863: It's possible 'deps' is null if the service is modified between GetCompiledType and here. // in that case simply do not cache the result so it is re-established next time it is required. CacheDependency cd = HostingEnvironment.VirtualPathProvider.GetCacheDependency(virtualPath, deps.VirtualPaths, DateTime.Now); context.Cache.Insert(cacheKey, data, cd); } } } else if (virtualPath.EndsWith("_AppService.axd", StringComparison.OrdinalIgnoreCase)) { // File does not exist, but the url may be a request for one of the three built-in services: ProfileService, AuthenticationService, RoleService data = WebServiceData.GetApplicationService(context.Request.AppRelativeCurrentExecutionFilePath); if (data != null) { context.Cache.Insert(cacheKey, data); } } } if (data == null) { if (failIfNoData) { if (inlineScript) { //DevDiv 74432: InlineScript = true fails, for WCF serviceReferences: Need an appropriate error message throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, AtlasWeb.WebService_NoWebServiceDataInlineScript, virtualPath)); } else { throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, AtlasWeb.WebService_NoWebServiceData, virtualPath)); } } else { return(null); } } return(data); }
internal static string GetClientTypeFromServerType(WebServiceData webServiceData, Type type) { // For intellisense purposes, returns a best estimate of what the appropriate client-side type is for a given server type. // Takes generated client proxies and enum proxies into consideration. // The rest is a best guess. // If all else fails we use "", to indicate "any" client side type. "Object" is not the same as any type on the client since // string, for example, is not considered an object. "Object" is equiv to a .net dictionary. if (webServiceData.ClientTypeNameDictionary.ContainsKey(type)) { // if it exists in the client type dictionary, it will have a proxy generated for it //get the client based on type.FullName for ASMX, and schema qualified name and namespace for WCF return webServiceData.ClientTypeNameDictionary[type]; } if (type.IsEnum) { // there will be a proxy for this enum return GetClientTypeName(type.FullName); } // there is no client proxy for it, so it either maps to a built-in js type or it could be "anything" // take care of the most common types if (type == typeof(string) || type == typeof(char)) { return "String"; } else if (type.IsPrimitive) { // The primitive types are Boolean, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64 (long), UInt64, IntPtr, Char, Double, and Single (float). if (type == typeof(bool)) { // bool is the only primitive we shouldnt treat as a number return "Boolean"; } else { // takes care of all ints, float, double, but not decimal since it isnt a primitive // we also consider byte, sbyte, and intptr to be numbers return "Number"; } } if (type.IsValueType) { if (type == typeof(DateTime)) { return "Date"; } else if (type == typeof(Guid)) { return "String"; } else if (type == typeof(Decimal)) { return "Number"; } } if (typeof(IDictionary).IsAssignableFrom(type)) { return "Object"; } // might still be IDictionary<K,T> if (type.IsGenericType) { Type gtd = type; if (!type.IsGenericTypeDefinition) { gtd = type.GetGenericTypeDefinition(); } if (gtd == typeof(IDictionary<,>)) { return "Object"; } } if (type.IsArray || typeof(IEnumerable).IsAssignableFrom(type)) { return "Array"; } // dont know what it is (e.g., TimeSpan), or it is type Object, so allow any client type. return ""; }
/* e.g var Qqq = function() { this.__type = "Qqq"; } */ private void GenerateClientTypeProxies(WebServiceData data) { bool first = true; foreach (WebServiceTypeData t in data.ClientTypes) { if (first) { _builder.Append("var gtc = Sys.Net.WebServiceProxy._generateTypedConstructor;\r\n"); first = false; } string typeID = data.GetTypeStringRepresentation(t); string typeNameWithClientNamespace = GetClientTypeNamespace(t.TypeName); string typeName = ServicesUtilities.GetClientTypeName(typeNameWithClientNamespace); string clientTypeNamespace = GetClientTypeNamespace(t.TypeNamespace); EnsureNamespace(t.TypeNamespace); EnsureObjectGraph(clientTypeNamespace, typeName); _builder.Append("if (typeof(").Append(typeName).Append(") === 'undefined') {\r\n"); AppendClientTypeDeclaration(clientTypeNamespace, typeNameWithClientNamespace, false, false); // Need to use the _type id, which isn't necessarly the real name _builder.Append("gtc(\""); _builder.Append(typeID); _builder.Append("\");\r\n"); _builder.Append(typeName).Append(".registerClass('").Append(typeName).Append("');\r\n}\r\n"); } }
// Normally returns MyNS.MySubNS.MyWebService OR var MyWebService, PageMethods will return PageMethods protected virtual string GetProxyTypeName(WebServiceData data) { return(ServicesUtilities.GetClientTypeName(data.TypeData.TypeName)); }
protected void GenerateStaticInstance(WebServiceData data) { string typeName = GetProxyTypeName(data); _builder.Append(typeName).Append("._staticInstance = new ").Append(typeName).Append("();\r\n"); // Generate the static properties if (_debugMode) { _builder.Append(typeName).Append(".set_path = function(value) {\r\n"); _builder.Append(typeName).Append("._staticInstance.set_path(value); }\r\n"); _builder.Append(typeName).Append(".get_path = function() { \r\n/// <value type=\"String\" mayBeNull=\"true\">The service url.</value>\r\nreturn "); _builder.Append(typeName).Append("._staticInstance.get_path();}\r\n"); _builder.Append(typeName).Append(".set_timeout = function(value) {\r\n"); _builder.Append(typeName).Append("._staticInstance.set_timeout(value); }\r\n"); _builder.Append(typeName).Append(".get_timeout = function() { \r\n/// <value type=\"Number\">The service timeout.</value>\r\nreturn "); _builder.Append(typeName).Append("._staticInstance.get_timeout(); }\r\n"); _builder.Append(typeName).Append(".set_defaultUserContext = function(value) { \r\n"); _builder.Append(typeName).Append("._staticInstance.set_defaultUserContext(value); }\r\n"); _builder.Append(typeName).Append(".get_defaultUserContext = function() { \r\n/// <value mayBeNull=\"true\">The service default user context.</value>\r\nreturn "); _builder.Append(typeName).Append("._staticInstance.get_defaultUserContext(); }\r\n"); _builder.Append(typeName).Append(".set_defaultSucceededCallback = function(value) { \r\n "); _builder.Append(typeName).Append("._staticInstance.set_defaultSucceededCallback(value); }\r\n"); _builder.Append(typeName).Append(".get_defaultSucceededCallback = function() { \r\n/// <value type=\"Function\" mayBeNull=\"true\">The service default succeeded callback.</value>\r\nreturn "); _builder.Append(typeName).Append("._staticInstance.get_defaultSucceededCallback(); }\r\n"); _builder.Append(typeName).Append(".set_defaultFailedCallback = function(value) { \r\n"); _builder.Append(typeName).Append("._staticInstance.set_defaultFailedCallback(value); }\r\n"); _builder.Append(typeName).Append(".get_defaultFailedCallback = function() { \r\n/// <value type=\"Function\" mayBeNull=\"true\">The service default failed callback.</value>\r\nreturn "); _builder.Append(typeName).Append("._staticInstance.get_defaultFailedCallback(); }\r\n"); _builder.Append(typeName).Append(".set_enableJsonp = function(value) { "); _builder.Append(typeName).Append("._staticInstance.set_enableJsonp(value); }\r\n"); _builder.Append(typeName).Append(".get_enableJsonp = function() { \r\n/// <value type=\"Boolean\">Specifies whether the service supports JSONP for cross domain calling.</value>\r\nreturn "); _builder.Append(typeName).Append("._staticInstance.get_enableJsonp(); }\r\n"); _builder.Append(typeName).Append(".set_jsonpCallbackParameter = function(value) { "); _builder.Append(typeName).Append("._staticInstance.set_jsonpCallbackParameter(value); }\r\n"); _builder.Append(typeName).Append(".get_jsonpCallbackParameter = function() { \r\n/// <value type=\"String\">Specifies the parameter name that contains the callback function name for a JSONP request.</value>\r\nreturn "); _builder.Append(typeName).Append("._staticInstance.get_jsonpCallbackParameter(); }\r\n"); } else { _builder.Append(typeName).Append(".set_path = function(value) { "); _builder.Append(typeName).Append("._staticInstance.set_path(value); }\r\n"); _builder.Append(typeName).Append(".get_path = function() { return "); _builder.Append(typeName).Append("._staticInstance.get_path(); }\r\n"); _builder.Append(typeName).Append(".set_timeout = function(value) { "); _builder.Append(typeName).Append("._staticInstance.set_timeout(value); }\r\n"); _builder.Append(typeName).Append(".get_timeout = function() { return "); _builder.Append(typeName).Append("._staticInstance.get_timeout(); }\r\n"); _builder.Append(typeName).Append(".set_defaultUserContext = function(value) { "); _builder.Append(typeName).Append("._staticInstance.set_defaultUserContext(value); }\r\n"); _builder.Append(typeName).Append(".get_defaultUserContext = function() { return "); _builder.Append(typeName).Append("._staticInstance.get_defaultUserContext(); }\r\n"); _builder.Append(typeName).Append(".set_defaultSucceededCallback = function(value) { "); _builder.Append(typeName).Append("._staticInstance.set_defaultSucceededCallback(value); }\r\n"); _builder.Append(typeName).Append(".get_defaultSucceededCallback = function() { return "); _builder.Append(typeName).Append("._staticInstance.get_defaultSucceededCallback(); }\r\n"); _builder.Append(typeName).Append(".set_defaultFailedCallback = function(value) { "); _builder.Append(typeName).Append("._staticInstance.set_defaultFailedCallback(value); }\r\n"); _builder.Append(typeName).Append(".get_defaultFailedCallback = function() { return "); _builder.Append(typeName).Append("._staticInstance.get_defaultFailedCallback(); }\r\n"); _builder.Append(typeName).Append(".set_enableJsonp = function(value) { "); _builder.Append(typeName).Append("._staticInstance.set_enableJsonp(value); }\r\n"); _builder.Append(typeName).Append(".get_enableJsonp = function() { return "); _builder.Append(typeName).Append("._staticInstance.get_enableJsonp(); }\r\n"); _builder.Append(typeName).Append(".set_jsonpCallbackParameter = function(value) { "); _builder.Append(typeName).Append("._staticInstance.set_jsonpCallbackParameter(value); }\r\n"); _builder.Append(typeName).Append(".get_jsonpCallbackParameter = function() { return "); _builder.Append(typeName).Append("._staticInstance.get_jsonpCallbackParameter(); }\r\n"); } // the path has to be the full absolete path if this is a JSONP enabled service. But it is the responsibility // of the caller to GetClientProxyScript to pass the full path if appropriate since determining it may be // dependant on the specific technology. string proxyPath = GetProxyPath(); if (!String.IsNullOrEmpty(proxyPath) && (proxyPath.StartsWith("http://", StringComparison.OrdinalIgnoreCase) || proxyPath.StartsWith("https://", StringComparison.OrdinalIgnoreCase))) { // DevDiv 91322: avoid url encoding the domain portion of an IDN url // find the first "/" after the scheme, and only encode after that. int domainStart = proxyPath.IndexOf("://", StringComparison.OrdinalIgnoreCase) + "://".Length; int domainEnd = proxyPath.IndexOf("/", domainStart, StringComparison.OrdinalIgnoreCase); // if no slash after :// was found, it could be a domain only url, http://[some service].com, don't encode any of it if (domainEnd != -1) { proxyPath = proxyPath.Substring(0, domainEnd) + HttpUtility.UrlPathEncode(proxyPath.Substring(domainEnd)); } } else { // it doesn't appear to be an absolute url, at least not an http or https one. All relative paths // and other oddities are safely encoded with UrlPathEncode. proxyPath = HttpUtility.UrlPathEncode(proxyPath); } _builder.Append(typeName).Append(".set_path(\"").Append(proxyPath).Append("\");\r\n"); if (GetSupportsJsonp()) { _builder.Append(typeName).Append(".set_enableJsonp(true);\r\n"); string jsonpParameterName = GetJsonpCallbackParameterName(); if (!String.IsNullOrEmpty(jsonpParameterName) && !jsonpParameterName.Equals("callback", StringComparison.Ordinal)) { _builder.Append(typeName).Append(".set_jsonpCallbackParameter(").Append(JavaScriptSerializer.SerializeInternal(jsonpParameterName)).Append(");\r\n"); } } }
protected virtual void GenerateTypeDeclaration(WebServiceData webServiceData, bool genClass) { AppendClientTypeDeclaration(webServiceData.TypeData.TypeNamespace, webServiceData.TypeData.TypeName, genClass, true); }
protected void GenerateRegisterClass(WebServiceData webServiceData) { // Generate registerClass: Foo.NS.WebService.registerClass('Foo.NS.WebService', Sys.Net.WebServiceProxy); string typeName = GetProxyTypeName(webServiceData); _builder.Append(typeName).Append(".registerClass('").Append(typeName).Append("',Sys.Net.WebServiceProxy);\r\n"); }