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

一.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 跨域访问的问题和解决过程
  在<configuration></configuration>节点中添加子节点:

<system.webServer>
    <httpProtocol>
      <customHeaders>
        <add name="Access-Control-Allow-Methods" value="OPTIONS,POST,GET"/>
        <add name="Access-Control-Allow-Headers" value="x-requested-with,content-type"/>
        <add name="Access-Control-Allow-Origin" value="*"/>
      </customHeaders>
    </httpProtocol>
</system.webServer>
5、自定义配置文件config.xml(可选)

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

<config>
  <project_path>
    <value>E:\WebApplication1</value>
  </project_path>
</config>

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

using System.Xml;
using System.IO;

protected void Application_Start(object sender, EventArgs e)
{
       XmlDocument configXml = new XmlDocument();
       string strPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin", "Config.xml");// 上面新建的"config.xml";
       if (File.Exists(strPath))
       {
           //加载xml文件并且读取文件根节点(每个xml文件有且仅有一个根节点)
           configXml.Load(strPath);
           XmlNode root = configXml.SelectSingleNode("config");
           //project_path
           XmlNodeList project_path = root.SelectNodes("project_path");
           string abc = ((XmlElement)project_path.Item(0)).ChildNodes.Item(0).InnerText;
       }
}

  (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里写:

public static string project_path;

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

//把string abc 改为已经定义好的变量Config.project_path
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()方法,那么:

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

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

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

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

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

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

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

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

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

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

{"jsonwebtest": "{'functionname':'test','a':'a','b':'b','c':'v'}"} //正确的json
//解析后的json
{
    "jsonwebtest": "{'functionname':'test','a':'a','b':'b','c':'c'}"
}

{'jsonwebtest': '{"functionname":"test","a":"a","b":"b","c":"c"}'} //错误的格式,外部必须是双引号

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

//引用json,其实只需要第二个引用
using Newtonsoft.Json;  
using Newtonsoft.Json.Linq;  
  
namespace WebApplication2
{
    public class Class1
    {
        public string Add(JObject jo)
        {
            string a = jo["a"].ToString();
            string b = jo["b"].ToString();
            string array = jo["c"].ToString();
            string[] c = array.Split(',');
            string retxt = a + b + c[0] + c[1]; //a1b2 
            //这里返回的是什么,前端的data就是什么
            //如果是字符串a1b2,前端data就是a1b2,如果是数组[a,b],那么data就是[a,b]
            return retxt;
        }
    }
}

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

//引用json
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

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

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

  • 7
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值