不管是asp.net webform 还是asp.net mvc 中处理ajax都是一个道理,如下:
- 首先在代码文件类(.cs)中定义一个类 RetResult 用于返回结果
public class RetResult { //返回代码,此处暂定义3类 //分别 :-1表示需要登录; 0表示请求失败; 1表示请求成功) public int Code {get;set;} //返回的文本信息,比如,xxx成功/xxx失败; 如果Code为-1时返回的URL public string Msg {get;set;} //数据体 public dynamic Data {get;set;} }
当然也可以不定义直接使用隐名类:(不建议,弱类型的太随意容易不注意将字段名写错)
new { Code=1 , Msg="登录成功" , Data=null};
-
在一般处理程序(.ashx)或控制器(.cs)的action方法中处理 ajax 请求时返回即可
//mvc public ActionResult Index() { DataModel model=new DataModel(); //....赋值或查库 DataModel //隐名返回json //return Json(new { Code = -1, Msg= "/login" , Data=null}); //return Json(new { Code = 0, Msg= "参数不正确" , Data=null}); //return Json(new { Code = 1, Msg= "" , Data=model}); //RetResult 类型返回 json return Json(new RetResult(){Code = -1, Msg= "/login" , Data=null}); }
//一般处理程序 public override void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain"; //context.Response.ContentType = "application/json"; context.Response.Charset = "UTF-8"; ctx = context; Request = ctx.Request; Response = ctx.Response; { DataModel model=new DataModel(); //....赋值或查库 DataModel //隐名返回json //return JsonConvert.SerializeObject(new { Code = -1, Msg= "/login" , Data=null}); //return JsonConvert.SerializeObject(new { Code = 0, Msg= "失败" , Data=null}); //return JsonConvert.SerializeObject(new { Code = 1, Msg= "" , Data=model}); //RetResult 类型返回 json return JsonConvert.SerializeObject(new RetResult() { Code = -1, Msg= "/login" , Data=null }); } Response.End(); }
3.js请求
function getdata() {
$.post("/controller/action", {dat="请求json对象"}, function (res) {
if (res.Code == -1)
top.location = '/login';
else if (res.Code == 1) {
//正确数据处理
var d=res.Data;
//...
}else{
alert(res.Msg);
}
}
});
}
以上是正常的请求流程,但当有权限验证,并且打开页长时间没操作使登录过期后再操作就会无反应;
但实际,不是无反应,而是需要验证或返回了处理不了的东东,比如返回给ajax一个登录的html文本,此时怎么也处理不了,可能俺是菜吧,不过时间战胜了这个问题,最终找到了解决方法
解决方法如下,估计写asp.net webform的人少了,这里仅以mvc为例,webform同理
问题起因是ajax 所以就在源头解决
上面 $.post 是jq ajax异步请求,在成功的回调函数中如上面写了个res参数,实际这函数有三个参数,分别function(data,stutas,xhr) 上面res仅仅是data占位,只接收返回数据,不过一般也就只关心返回的数据,但时间一长就会忽略甚至忘记还有另外二个,解决这个问题就是需要最后一个参数xhr 是个jqXHR类型的,也就是XMLHTTPRequest对象
返回的XMLHTTPRequest对象,可以获取到Response的数据,所以只需要改造你常用ajax方法就行,把xhr参数放出来
$.post("/controller/action", {dat="请求json对象"}, function (res,state,xhr) {
//与上面js请求对比,多获取了个flag的response Header集合的一个值
var flag = xhr.getResponseHeader('LgFlag');
if (res.Code == -1||flag=="ReNew")
top.location = '/login';
else if (res.Code == 1) {
//正确数据处理
var d=res.Data;
//...
}else{
alert(res.Msg);
}
}
});
页面点击 a 标签或提交按钮之类用户主动行为只要不是ajax都会跳转,所以只需要加上ajax不跳转的特殊处理就可以
重新编辑----忘说了,不用管其它控制器中的处理,只要在显示登录页action方法中加上是否ajax的判断并且加个识别标志到response.header中就可以,那明明我请求的/AdmArea/home/index为什么要加在显示登录面的action呢? (/auth/Login)
因为FormsAuthentication验证,只要Request.IsAuthenticated=false,就会跳转到根目录下web.config配置的LoginUrl路径,所以仅在展示登录页的action中处理,不然ajax就会接收到整个登录页的html文本
那为什么要加标志到response.header中呢,因为request的属性只读,数据体又是整页的文本html,所以可操作的只有response.header,使得ajax接收到这个标志来区分并跳转
<!--根目录web.config配置权限FormsAuthentication-->
<system.web>
<compilation debug="true" targetFramework="4.8" />
<httpRuntime targetFramework="4.8" />
<authentication mode="Forms">
<forms name=".ASPXMVC" loginUrl="~/Auth/Login" protection="All" slidingExpiration="true"
defaultUrl="/AdmArea/Home/Index"></forms>
</authentication>
<authorization>
<allow users="*" />
</authorization>
</system.web>
<location path="AdmArea">
<system.web>
<authorization>
<deny users="?" />
</authorization>
</system.web>
</location>
//mvc 登录页显示 action
public ActionResult Login()
{
//如果没有登录且请求类型为ajax,重定向,(非ajax会自动跳转,不需要处理
if (!Request.IsAuthenticated &&//验证是否登录
(Request.Headers["X-Requested-With"] == "XMLHttpRequest" ||//一般ajax请求
Request.Headers["x-microsoftajax"] == "Delta-true"))//微软ajax请求
{
//return Redirect(FormsAuthentication.LoginUrl);*///直接重定向到此方法会死循环
//增加一个标志,使ajax检索header判断是否跳转
Response.Headers.Add("LgFlag", "ReNew");//ajax判断flag
}
return View();
}
//登录ing action
public ActionResult Logining(string account,strng password,string vcode)
{
//查库验证用户
if(验证用户()==true)
return Redirect("/AdmArea/home/index");
else return Json(new { code = 0, msg= "帐号/密码无效" });
}
好了,废话说的有点多,实际 只是把ajax 的 success 回调函数 xhr 参数放出来就能处理
完毕!!!