需求:
    在默认创建的Asp.Net MVC项目中(这里使用VS2013),需要手动返回一个401响应码给浏览器。我们的代码可能是下面这样子的。
 
  1.          public ActionResult UnauthorizedAccess()
    {
    return new HttpStatusCodeResult((int)HttpStatusCode.Unauthorized);
    }
 
实际的效果却和预期的不太一样,如果我们是通过地址栏直接访问这个Action,可以看到请求被重定向到登录页面了
 
 
如果通过Ajax的方式进行访问,可以看到直接返回了一个200的响应码
 
因为当前创建的MVC项目默认使用的是一个叫CookieAuthentication的OWIN中间件来实现身份认证的功能的,该中间件中会将401响应码进行特殊处理,所以导致我们无法手动返回401响应码。
 
Startup类中的代码: 
  1.              // 使应用程序可以使用 Cookie 来存储已登录用户的信息
    // 并使用 Cookie 来临时存储有关使用第三方登录提供程序登录的用户的信息
    // 配置登录 Cookie
    app.UseCookieAuthentication(new CookieAuthenticationOptions
    {
    AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
    LoginPath = new PathString("/Account/Login"),
    Provider = new CookieAuthenticationProvider
    {
    // 当用户登录时使应用程序可以验证安全戳。
    // 这是一项安全功能,当你更改密码或者向帐户添加外部登录名时,将使用此功能。
    OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
    validateInterval: TimeSpan.FromMinutes(),
    regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
    }
    });
 
 
 
所以如果你使用上述的中间件(使用其他的身份认证的组件也可能会存在重写401响应码的行为),那么就无法手动返回401响应码
 
如果需要手动返回401响应码,那么就需要在Asp.Net的生命周期中对相应做一些修改,查阅MSDN的资料可以看到PreSendRequestHeaders事件中比较适合做这个操作。
 
 
在Global中我们添加如下方法,在PreSendRequestHeaders事件中插入我们自己的代码,将响应码设置为我们预期想要的值
  1.          public void Application_PreSendRequestHeaders(object sender, EventArgs e)
    {
    //处理401响应被多个框架重写的问题
    var values = Response.Headers.GetValues(ForceHttpStatusCodeResult.ForceHttpUnauthorizedHeaderName);
    if (values != null && values.Contains(ForceHttpStatusCodeResult.ForceHttpUnauthorizedHeaderValue))
    {
    Response.ClearHeaders();
    Response.StatusCode = (int)HttpStatusCode.Unauthorized;
    }
    }
 
 
由于请求到这里的时候,响应码已经被重写,所以我们通过一个自定义的请求头来标识当前请求是一个要被手动发送给客户端的401响应
 
     /// <summary>
/// 强制返回指定的响应码
/// 401响应码会被MVC框架和OWIN授权认证的中间件给重写
/// </summary>
public class ForceHttpStatusCodeResult : HttpStatusCodeResult
{ public const string ForceHttpUnauthorizedHeaderName = "ForceHttpUnauthorizedHeader";
public const string ForceHttpUnauthorizedHeaderValue = "true"; public ForceHttpStatusCodeResult(int state)
: this(state, "")
{ } public ForceHttpStatusCodeResult(int state, string statusDescription)
: base(state, statusDescription)
{
if (state == (int)HttpStatusCode.Unauthorized)
{
SetForceHttpUnauthorizedHeader();
}
} private void SetForceHttpUnauthorizedHeader()
{
System.Web.HttpContext.Current.Response.AddHeader(ForceHttpUnauthorizedHeaderName, ForceHttpUnauthorizedHeaderValue);
}
}
 
 
此时我们在Action中就可以返回我们需要的任意响应码了
  1.          public ActionResult UnauthorizedAccess()
    {
    return new ForceHttpStatusCodeResult((int)HttpStatusCode.Unauthorized);
    }
 
Ajax请求结果:
 
 
 
下载:
   示例代码
 
 
参考资料:
 
 
 

Asp.Net MVC如何返回401响应码的更多相关文章

  1. ASP.NET MVC通用权限管理系统(响应布局)源码更新介绍

    一.asp.net mvc 通用权限管理系统(响应布局)源码主要以下特点: AngelRM(Asp.net MVC)是基于asp.net(C#)MVC+前端bootstrap+ztree+lodash ...

  2. ASP.NET MVC WebApi 返回数据类型序列化控制(json,xml) 用javascript在客户端删除某一个cookie键值对 input点击链接另一个页面,各种操作。 C# 往线程里传参数的方法总结 TCP/IP 协议 用C#+Selenium+ChromeDriver 生成我的咕咚跑步路线地图 (转)值得学习百度开源70+项目

    ASP.NET MVC WebApi 返回数据类型序列化控制(json,xml)   我们都知道在使用WebApi的时候Controller会自动将Action的返回值自动进行各种序列化处理(序列化为 ...

  3. asp.net MVC通用权限管理系统-响应式布局-源码

    一.Angel工作室简单通用权限系统简介 AngelRM(Asp.net MVC Web api)是基于asp.net(C#)MVC+前端bootstrap+ztree+lodash+jquery技术 ...

  4. 17+个ASP.NET MVC扩展点,含源码{转}

    1.自定义一个HttpModule,并将其中的方法添加到HttpApplication相应的事件中!即:创建一个实现了IHttpmodule接口的类,并将配置WebConfig.在自定义的HttpMo ...

  5. ASP.NET MVC Action返回结果类型【转】

    ASP.NET MVC 目前一共提供了以下几种Action返回结果类型: 1.ActionResult(base) 2.ContentResult 3.EmptyResult 4.HttpUnauth ...

  6. WinDBg定位asp.net mvc项目异常崩溃源码位置

    项目介绍:asp.net mvc + angular +iis(windows)+windows server 系统莫名崩溃 最近有个系统默认奇妙崩溃50x,服务整体变成无响应,当运维告知我只有重启应 ...

  7. 基于ASP.NET MVC和Bootstrap搭建响应式个人博客站(一)

    1.0 为什么要做这个博客站? www.zynblog.com   在工作学习中,经常要搜索查找各种各样的资料,每次找到相关资料后都会顺手添加到浏览器书签中,时间一长,书签也就满了.而且下次再点击这个 ...

  8. 让ASP.NET MVC页面返回不同类型的内容

    在ASP.NET MVC的controller中大部分方法返回的都是ActionResult,更确切的是ViewResult.它返回了一个View,一般情况下是一个HTML页面.但是在某些情况下我们可 ...

  9. Asp.net mvc 项目返回Json

    因mvc控制器返回类型JsonResult 在处理对象转JSON的时候,对日期的格式化处理并不太符合要求,所以重新继承抽象类ActionResult使用Newtonsoft.Json来系列化 usin ...

随机推荐

  1. 在java 中,数组与 List<T> 类型的相互转换

    在java中,数组与List<T> 之前进行互相转换,转换方法可总结为以下几种: 一. 将 数组转换成List<T> 1. 使用 Collections 的addAll 方法 ...

  2. 学习记录 Eclipse常用快捷键及其演练

    Eclipse中10个最有用的快捷键组合 1. ctrl+shift+r:打开资源 这可能是所有快捷键组合中最省时间的了.这组快捷键可以让你打开你的工作区中任何一个文件,而你只需要按下文件名或mask ...

  3. 生成Excel直接以流或字节形式发给客户端,无需在服务生成一个实体文件。

    public ActionResult ExportAgentBooking(string Company_Id, string Company_Name)//Altman.Web.BCDAdmin. ...

  4. 华为OJ平台——统计字符串中的大写字母

    题目描述: 统计字符串中的大写字母的个数 输入: 一行字符串 输出: 字符串中大写字母的个数(当空串时输出0) 思路: 这一题很简单,直接判断字符串中的每一个字符即可,唯一要注意的一点是输入的字符串可 ...

  5. 【EF 5】结合项目实战分析EF三大工作模式之—Database First

    导读:所谓的EF的Databasefirst工作模式,是目前我们(不涉及社会领域)用的最广的一种模式,也是本次ITOO开发所采用的工作模式.本篇博客,就分析在项目中通过Database First模式 ...

  6. Bootstrap <第一篇>

    一.使用Bootstrap要引用的文件 要使用Bootstrap,基本架构要引用如下文件: <link href="bootstrap.min.css" rel=" ...

  7. Sql2008 php

    Sql2008支持php的擴展插件 http://www.microsoft.com/download/en/search.aspx?q=SQL+Server+for+PHP  全部 http://w ...

  8. ruby中symbol

    Symbol 是什么 Ruby 是一个强大的面向对象脚本语言(本文所用 Ruby 版本为1.8.6),在 Ruby 中 Symbol 表示“名字”,比如字符串的名字,标识符的名字. 创建一个 Symb ...

  9. hbase查询,scan详解

    一.shell 查询 hbase 查询相当简单,提供了get和scan两种方式,也不存在多表联合查询的问题.复杂查询需通过hive创建相应外部表,用sql语句自动生成mapreduce进行.但是这种简 ...

  10. Linux下运行top命令显示的PR\NI\RES\SHR\S\%MEM TIME+都代表什么

    PID 进程号 USER 用户名 PR 优先级 NI nice值.负值表示高优先级,正值表示低优先级 RES 进程使用的.未被换出的物理内存大小,单位Kb S 进程状态: D 不可中断的睡眠状态 R ...