基于SOAPClient将WebService转为TypeScript脚本

static void GenTsApi()
{
	string dir = "\\Storage Card";
	//string apiTypeFileName = root+Path.DirectorySeparatorChar+"api.d.ts";
	string apiFileName = dir + Path.DirectorySeparatorChar + "api.ts";
	Type webService = typeof(MES.PDA.WebService);
	//获取WebService方法
	MethodInfo[] methods = webService.GetMethods(BindingFlags.Instance 
		| BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.DeclaredOnly);
	Type asyncType = typeof(IAsyncResult);
	StringBuilder api = new StringBuilder();
	api.Append("namespace webService{\r\n");
	api.Append("    /**\r\n");
	api.Append("     * @constant\r\n");
	api.Append("     * @type {string}\r\n");
	api.Append("     * @default\r\n");
	api.Append("     */\r\n");
	api.Append("     const url = \"http://localhost:11062/WebService.asmx\";\r\n");
	api.Append("    /**\r\n");
	api.Append("     * @class\r\n");
	api.Append("     * @classdesc 服务响应\r\n");
	api.Append("     */\r\n");
	api.Append("    export class webServiceResponse{\r\n");
	api.Append("        /**\r\n");
	api.Append("         * @description 错误\r\n");
	api.Append("         */\r\n");
	api.Append("        error:string;\r\n");
	api.Append("        /**\r\n");
	api.Append("         * @description 请求响应结果\r\n");
	api.Append("         */\r\n");
	api.Append("        result:object;\r\n");
	api.Append("    }\r\n");
	api.Append("\r\n");
	api.Append("    /**\r\n");
	api.Append("     * @callback 请求回调\r\n");
	api.Append("     * @param {webServiceResponse} 响应结果\r\n");
	api.Append("     */\r\n");
	api.Append("    export interface requestCallback\r\n");
	api.Append("    {\r\n");
	api.Append("        (rsp:webServiceResponse):void;\r\n");
	api.Append("    }\r\n");
	api.Append("\r\n");
	api.Append("    class SOAPClientWrapper{\r\n");
	api.Append("        client:SOAPClient = null;\r\n");
	api.Append("        constructor(client:SOAPClient)\r\n");
	api.Append("        {\r\n");
	api.Append("            this.client = client;\r\n");
	api.Append("        }\r\n");
	api.Append("        public invoke(method:string,paras:object,rsp:requestCallback):void{\r\n");
	api.Append("            let para = new SOAPClientParameters();\r\n");
	api.Append("            if(paras)\r\n");
	api.Append("            {\r\n");
	api.Append("                Object.keys(paras).forEach(p=>para.add(p,paras[p]));\r\n");
	api.Append("            }\r\n");
	api.Append("            this.client.invoke(method,para,true,(r)=>{\r\n");
	api.Append("                if(r.result)\r\n");
	api.Append("                {\r\n");
	api.Append("                    var model = new webService[method+\"Response\"]\r\n");
	api.Append("                    r.result = Object.assign(model,r.result);\r\n");
	api.Append("                }\r\n");
	api.Append("                rsp(r);\r\n");
	api.Append("            });\r\n");
	api.Append("        }\r\n");
	api.Append("        static New():SOAPClientWrapper\r\n");
	api.Append("        {\r\n");
	api.Append("            return new SOAPClientWrapper(new SOAPClient(url));\r\n");
	api.Append("        }\r\n");
	api.Append("    }\r\n");
	api.Append("    export const client = SOAPClientWrapper.New();\r\n");
	Dictionary<string, string> req = null;
	Dictionary<string, string> rsp = null;
    Type xmlElemType = typeof(XmlElementAttribute);
	foreach (MethodInfo method in methods)
	{
		if (method.IsConstructor
		    //排除异步方法
			|| (method.Name.StartsWith("Begin")
			&& method.ReturnType == asyncType)) continue;

		ParameterInfo[] paras = method.GetParameters();
		if (method.Name.StartsWith("End") && paras.Length > 0 && paras[0].ParameterType == asyncType)
			continue;

		req = new Dictionary<string, string>();
		rsp = new Dictionary<string, string>();

		api.AppendFormat("    export const {0} = \"{0}\";\r\n", method.Name);
		if (method.ReturnType != null && method.ReturnType != typeof(void))
		{
            
              string resultName = string.Format("{0}Result", method.Name);
              if (method.ReturnTypeCustomAttributes.IsDefined(xmlElemType,false))
              {
                    resultName = (method.ReturnTypeCustomAttributes.GetCustomAttributes(xmlElemType, false)[0] as XmlElementAttribute).ElementName;
              }
              rsp.Add(resultName, GetTsType(method.ReturnType));
		}

		foreach (ParameterInfo p in paras)
		{
			if (p.Attributes == ParameterAttributes.None || (p.Attributes & ParameterAttributes.In) == ParameterAttributes.In)
			{
				req.Add(p.Name, GetTsType(p.ParameterType));
			}

			if ((p.Attributes & ParameterAttributes.Out) == ParameterAttributes.Out)
			{
				rsp.Add(p.Name, GetTsType(p.ParameterType));
			}
		}

		api.AppendFormat("    export class {0}_Request\r\n",method.Name);
		api.Append("    {\r\n");
		if(req.Count > 0)
		{
			api.Append(string.Join("", req.Select(kv => string.Format("        {0}:{1};\r\n", kv.Key, kv.Value)).ToArray()));
		}
		api.Append("        constructor(\r\n");
		if (req.Count > 0)
		{
			api.Append(string.Join("", req.Select(kv => string.Format("            {0}:{1},\r\n", kv.Key, kv.Value)).ToArray()));
		}
		api.Append("        ){\r\n");
		if (req.Count > 0)
		{
			api.Append(string.Join("", req.Select(kv => string.Format("                this.{0} = {0};\r\n", kv.Key)).ToArray()));
		}
		api.Append("    }\r\n");
		api.Append("\r\n");
		api.Append("            public static New(\r\n");
		if (req.Count > 0)
		{
			api.Append(string.Join("", req.Select(kv => string.Format("                {0}:{1},\r\n", kv.Key, kv.Value)).ToArray()));
		}
		api.AppendFormat("            ):{0}_Request{{\r\n", method.Name);
		if (req.Count == 0)
		{
			api.AppendFormat("                    return new {0}_Request;", method.Name);
		}
		else
		{
			api.AppendFormat("                    return new {0}_Request(\r\n", method.Name);
			api.Append(string.Join("", req.Select(kv => string.Format("                        {0},\r\n", kv.Key)).ToArray()));
			api.Append("                        );\r\n");
		}
		api.Append("                }\r\n");
		api.Append("    }\r\n");

		api.AppendFormat("    export class {0}Response\r\n",method.Name);
		api.Append("    {\r\n");
		if (rsp.Count > 0)
		{
			api.Append(string.Join("",rsp.Select(kv=>string.Format("        {0}:{1};\r\n",kv.Key,kv.Value)).ToArray()));
			api.AppendLine();
		}
		api.Append("        constructor(\r\n");
		if (rsp.Count > 0)
		{
			api.Append(string.Join("", rsp.Select(kv => string.Format("            {0}:{1},\r\n", kv.Key, kv.Value)).ToArray()));
		}
		api.Append("            ){\r\n");
		if (rsp.Count > 0)
		{
			api.Append(string.Join("", rsp.Select(kv => string.Format("            this.{0} = {0};\r\n", kv.Key)).ToArray()));
		}
		api.Append("        }\r\n");
		api.Append("    }\r\n");
	}
	api.Append("}");
	using (StreamWriter writer = File.CreateText(apiFileName))
	{
		writer.Write(api);
	}
}

static string GetTsType(Type type)
{
	Type nullType = Nullable.GetUnderlyingType(type);
	if (nullType != null)
	{
		type = nullType;
	}

	if (type == typeof(string) 
		|| type == typeof(long) 
		|| type == typeof(ulong)
		|| type == typeof(double)
		|| type == typeof(Guid))
	{
		return "string";
	}

	if (type == typeof(int) 
		|| type == typeof(uint)
		|| type == typeof(byte)
		|| type == typeof(short) 
		|| type == typeof(ushort)
		|| type == typeof(float)
		|| type == typeof(decimal))
	{
		return "number";
	}

	if (type == typeof(DateTime))
	{
		return "Date";
	}

	if (type == typeof(bool))
	{
		return "boolean";
	}

	if (collectionType.IsAssignableFrom(type))
	{
		if (type.IsGenericType)
		{
			return string.Format("{0}[]", GetTsType(type.GetGenericArguments()[0]));
		}

		//ArrayList,Array
		return "any[]";
	}

	if (dictionaryType.IsAssignableFrom(type))
	{
		return "Map";
	}

	return "object";
}

npm i -g typescript

tsc --version

tsc --init

tsconfig.json

{
  "compilerOptions": {
    /* Basic Options */
    "target": "es5",
    "module": "none",                           /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
    "lib": ["es2015"],                                   /* Specify library files to be included in the compilation. */
    "allowJs": true,                             /* Allow javascript files to be compiled. */
    // "checkJs": true,                             /* Report errors in .js files. */
    "declaration": true,                         /* Generates corresponding '.d.ts' file. */
    "declarationMap": true,                      /* Generates a sourcemap for each corresponding '.d.ts' file. */
    "sourceMap": false,                           /* Generates corresponding '.map' file. */
    // "outFile": "./",                             /* Concatenate and emit output to single file. */
    "outDir": "./js",                              /* Redirect output structure to the directory. */
    "rootDir": "./",                             /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
    // "composite": true,                           /* Enable project compilation */
    // "tsBuildInfoFile": "./",                     /* Specify file to store incremental compilation information */
    "removeComments": false,                      /* Do not emit comments to output. */
    "pretty": true,
    // "isolatedModules": true,                     /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */

    /* Strict Type-Checking Options */
    "strict": false,                                 /* Enable all strict type-checking options. */
    "noImplicitAny": false,                       /* Raise error on expressions and declarations with an implied 'any' type. */
    "noImplicitThis": false,                      /* Raise error on 'this' expressions with an implied 'any' type. */
    // "alwaysStrict": true,                        /* Parse in strict mode and emit "use strict" for each source file. */

    /* Additional Checks */
    "noImplicitReturns": false,                   /* Report error when not all code paths in function return a value. */
    // "baseUrl": "./",                             /* Base directory to resolve non-absolute module names. */
    // "paths": {},                                 /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
    // "rootDirs": [],                              /* List of root folders whose combined content represents the structure of the project at runtime. */
    // "typeRoots": [],                             /* List of folders to include type definitions from. */
    // "types": [],                                 /* Type declaration files to be included in compilation. */
    // "allowSyntheticDefaultImports": true,        /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
    "esModuleInterop": true,                        /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
    // "preserveSymlinks": true,                    /* Do not resolve the real path of symlinks. */
    // "allowUmdGlobalAccess": true,                /* Allow accessing UMD globals from modules. */

    /* Advanced Options */
    "skipLibCheck": true,                           /* Skip type checking of declaration files. */
    "forceConsistentCasingInFileNames": true        /* Disallow inconsistently-cased references to the same file. */
  },
  "include": [
    "./scripts/soapclient.min.js", 
    "api.ts"  
  ],
  "exclude": [
    "node_modules",
    "**/*.spec.ts"
  ]
}

tsc --build

调用实例:

webservice.invoke(webservice.MES_PDA_UserLogin,
	webservice.MES_PDA_UserLogin_Request.New(
		data.field.username,
		data.field.password),(rsp)=>{
		if(rsp.error)
		{
			//错误提示
			global.message(rsp.error, 2);
		}
		else
		{
			if(!rsp.result.MES_PDA_UserLoginResult)
			{
				global.message(rsp.result.msg, 2);
			}
			else
			{
				util.setToken(rsp.result.token);
				window.location.replace("main.html");
			}
		}
	});

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

闪耀星星

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值