javascript+C# 前后端连接(二)ajax

蔚落 2022-05-28 03:22 395阅读 0赞

一.C#

1、建立web空项目

  文件——新建——项目:Visual C#——Web——ASP.NET Web应用程序——空
这里写图片描述
这里写图片描述

2、添加web服务

  右键项目名称——添加——新建项:web服务
这里写图片描述
这里写图片描述
  看到的界面为:
这里写图片描述

3、调试

  点击工具栏里的浏览器进行调试,可以看到第一个helloword()的运行结果:
  这里写图片描述
  在运行时出现了一个错误:“无法启动程序“http://localhost:13342” 操作在当前状态中是非法的”
  这可能是因为防火墙被修改了,把防火墙改回”使用推荐设置”,再重新打开工程,就运行成功了。参考VS2017 启动调试出现 无法启动程序“http://localhost:15613” 操作在当前状态中是非法的。 同时附加进程也是错误的解决方法

4、修改配置文件web.config

  由于Js设置了跨域限制,因此需要进行配置。具体可参考JavaScript跨域总结与解决办法和JavaScript 跨域访问的问题和解决过程。
  在节点中添加子节点:

  1. <system.webServer>
  2. <httpProtocol>
  3. <customHeaders>
  4. <add name="Access-Control-Allow-Methods" value="OPTIONS,POST,GET"/>
  5. <add name="Access-Control-Allow-Headers" value="x-requested-with,content-type"/>
  6. <add name="Access-Control-Allow-Origin" value="*"/>
  7. </customHeaders>
  8. </httpProtocol>
  9. </system.webServer>

5、自定义配置文件config.xml(可选)

  由于有时候需要访问一些内其他文件,但这些文件名称或存放路径经常修改,因此可以自定义一个配置文件,需要修改这些文件名或路径时,直接修改配置文件即可,就不需要修改程序里其他信息:
  假设工程需要读取工程存放路径project_path,由于每个人存放的位置不一样,因而就需要对这个变量进行修改,工程才能正常运行。
  (1)在bin目录下创建一个config.xml文件(打开文件夹,在文件夹中新建,工程目录会自动显示它),可做如下编写:

  1. <config>
  2. <project_path>
  3. <value>E:\WebApplication1</value>
  4. </project_path>
  5. </config>

  (2)右键项目名称——添加——新建项:全局应用程序类Global.asax:
  这里写图片描述
  (3)双击新建的Global.asax,在Application_Start()中读取配置文件信息:

  1. using System.Xml;
  2. using System.IO;
  3. protected void Application_Start(object sender, EventArgs e)
  4. {
  5. XmlDocument configXml = new XmlDocument();
  6. string strPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin", "Config.xml");// 上面新建的"config.xml";
  7. if (File.Exists(strPath))
  8. {
  9. //加载xml文件并且读取文件根节点(每个xml文件有且仅有一个根节点)
  10. configXml.Load(strPath);
  11. XmlNode root = configXml.SelectSingleNode("config");
  12. //project_path
  13. XmlNodeList project_path = root.SelectNodes("project_path");
  14. string abc = ((XmlElement)project_path.Item(0)).ChildNodes.Item(0).InnerText;
  15. }
  16. }

  (4)对于配置文件config.xml来说,文件的内容是随时可变的,属于动态变量。但是对于C#工程来说,它读取的永远都是config.xml的节点,节点名是不变的,它是静态变量。也即是只要程序运行,Global.asax里读取的值就不会改变,程序里引用的这个对应值不会改变。如果要改变程序里的值,只有停止程序,修改后重新运行才会成功。
  为了使结构清晰,新建一个类,在类中定义静态变量,作为程序在运行时的变量名。这样,读取配置文件的结构就是:config.xml(可随时修改的配置文件)——Global.asax(读取配置文件的值)——类Config.cs定义值对应的变量名,以供程序使用。config.xml和Config.cs的名字可以修改,Global.asax最好不要修改。
  因此根据上面的例子,就需要添加一个类Config.cs替代上面的变量abc:右键项目名称——添加——类:
这里写图片描述
  在Config.cs里写:

  1. public static string project_path;

  然后修改上一步的最后一句为:

  1. //把string abc 改为已经定义好的变量Config.project_path
  2. Config.project_path = ((XmlElement)project_path.Item(0)).ChildNodes.Item(0).InnerText;

  在其他地方需要使用project_path时直接就使用config.project_path即可。
  需要注意的是,引用类时必须是在相同的命名空间下,如果是不同的命名空间,需要使用“using namespace”引用命名空间,或者使用“命名空间.类名.函数名/方法名/变量名”来引用其他命名空间的方法。具体看C++:#include和using namespace

二.JS

  关于ajax,可以看它的内部函数,就是封装的http连接前后端方法,有关http的传值方法,可以看我的上一篇文章 javascript+C# 前后端连接(一)http。

1、不传值,直接调用方法

  例如,id为hello的button需要调用上面的Helloword()方法,那么:

  1. //url为http://localhost:13342/WebService1.asmx+HelloWorld,前一部分为运行后工程的地址,可看第三步图片地址栏里的地址,后一部分为函数名称
  2. $("#hello").click(function () {
  3. $.ajax({
  4. type: "Post",
  5. url: "http://localhost:13342/WebService1.asmx/HelloWorld",
  6. async: false,
  7. //成功后执行 data为返回值
  8. success: function (data) {
  9. alert(data.documentElement.innerHTML);
  10. },
  11. //失败后执行 err为返回值
  12. error: function (err) {
  13. alert(err);
  14. }
  15. });
  16. });

  可以看到返回的data为:
这里写图片描述

2、使用json传值,字符、字符串、数组、对象等

  以一个案例来看如何进行连接:实现一个方法,前端向后端传值test,a,1,[b,2],后端合并值,把结果返回前端。
  首先,在JS中传值:

  1. var a = "a";
  2. var b = "1";
  3. var c = ["b", 2];
  4. $("#hello").click(function () {
  5. $.ajax({
  6. type: "Post",
  7. url: "http://localhost:13342/WebService1.asmx/HelloWorld",
  8. async: false,
  9. //告诉服务器,要发的数据类型
  10. contentType: "application/json; charset=utf-8",
  11. //参数为functionname,a,b,c
  12. data: '{"functionname":"test","a":"' + a + '","b":"' + b + '","c":"' + c.toString() + '"}',
  13. //告诉服务器,想要的数据类型,如果没有指定,那么会自动推断是返回XML,还是JSON,还是script,还是String
  14. dataType: "json",
  15. //成功后执行 data为返回值 data.d为返回的值
  16. success: function (data) {
  17. alert(data.d); //a1b2
  18. },
  19. //失败后执行 err为返回值
  20. error: function (err) {
  21. alert(err);
  22. }
  23. });
  24. });

  然后,把WebService1.asmx.cs里的第16句[System.Web.Script.Services.ScriptService]取消注释,如图:
  这里写图片描述

3、后端使用一个函数执行前端所有方法

  每个方法都写成单独的类或函数,然后用swich case根据前端传来的判定值选择调用的函数方法。依旧是以这个案例来说明:实现一个方法,前端向后端传值a,1,[b,2],后端合并值,把结果返回前端。
  首先,依旧来看JS中的写法:

  1. var a = "a";
  2. var b = "1";
  3. var c = ["b", 2];
  4. $("#hello").click(function () {
  5. $.ajax({
  6. type: "Post",
  7. url: "http://localhost:13342/WebService1.asmx/HelloWorld2",
  8. async: false,
  9. //告诉服务器,要发的数据类型,ajax的json格式不能识别下面的json对象格式,所以需要把contentType注释掉
  10. //contentType: "application/json; charset=utf-8",
  11. //参数为jsonwebtest,后面全是它的值
  12. //这个json不是正确的json,需要把‘’和“”互换以下,json的外层应该是双引号
  13. data: { 'jsonwebtest': '{"functionname":"test","a":"' + a + '","b":"' + b + '","c":"' + c.toString() + '"}'},
  14. //告诉服务器,想要的数据类型,如果没有指定,那么会自动推断是返回XML,还是JSON,还是script,还是String
  15. dataType: "json",
  16. //成功后执行 data为返回值 data.d为返回的值
  17. success: function (data) {
  18. alert(data); //a1b2
  19. },
  20. //失败后执行 err为返回值
  21. error: function (err) {
  22. alert(err);
  23. }
  24. });
  25. });

  可以看到,这里的js中注释了contentType,这时因为在之前的data基础上,外部增加了一层jsonwebtest,它不是json格式,单引号和双引号写反了,如果调换以下就不用注释类型了。还有,在成功后返回的值中,data即为返回值,后端resultjson是什么,前端的data即是什么。因为ajax在传送和接收时都解析过json了。

  1. { "jsonwebtest": "{'functionname':'test','a':'a','b':'b','c':'v'}"} //正确的json
  2. //解析后的json
  3. {
  4. "jsonwebtest": "{'functionname':'test','a':'a','b':'b','c':'c'}"
  5. }
  6. { 'jsonwebtest': '{"functionname":"test","a":"a","b":"b","c":"c"}'} //错误的格式,外部必须是双引号

  然后,新建一个类,在类里写好方法:

  1. //引用json,其实只需要第二个引用
  2. using Newtonsoft.Json;
  3. using Newtonsoft.Json.Linq;
  4. namespace WebApplication2
  5. {
  6. public class Class1
  7. {
  8. public string Add(JObject jo)
  9. {
  10. string a = jo["a"].ToString();
  11. string b = jo["b"].ToString();
  12. string array = jo["c"].ToString();
  13. string[] c = array.Split(',');
  14. string retxt = a + b + c[0] + c[1]; //a1b2
  15. //这里返回的是什么,前端的data就是什么
  16. //如果是字符串a1b2,前端data就是a1b2,如果是数组[a,b],那么data就是[a,b]
  17. return retxt;
  18. }
  19. }
  20. }

  最后,在C#中添加一个[WebMethod],函数设为HelloWorld2。

  1. //引用json
  2. using Newtonsoft.Json;
  3. using Newtonsoft.Json.Linq;
  4. // 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消注释以下行。 不需要取消注释。 //[System.Web.Script.Services.ScriptService]
  5. [WebMethod]
  6. //参数名必须与前端一致
  7. public void HelloWorld2(string jsonwebtest)
  8. {
  9. //jo即是{"functionname":"test","a":"' + a + '","b":"' + b + '","c":"' + c.toString() + '"}
  10. JObject jo = (JObject)JsonConvert.DeserializeObject(jsonwebtest);
  11. //解析出functionname对应的值后,根据这个值来调用相应的函数
  12. string functionname = jo["functionname"].ToString();
  13. //函数的返回值,可以转object的任何类型,需要返回数组也可以返回数组等
  14. string resultjson = "";
  15. switch (functionname)
  16. {
  17. case "test":
  18. Class1 cl = new Class1();
  19. resultjson = cl.Add(jo);
  20. break;
  21. default:
  22. break;
  23. }
  24. //将函数的返回值序列化为json对象,前端自动解json
  25. object JSONObj = JsonConvert.SerializeObject(resultjson);
  26. //将json对象写到http响应流,传到前端
  27. Context.Response.Write(JSONObj);
  28. }

  C#页面显示在WebService1.asmx.cs界面,然后运行,调用这个JS函数再运行html,即可看到弹出的结果。

发表评论

表情:
评论列表 (有 0 条评论,395人围观)

还没有评论,来说两句吧...

相关阅读