Nancy之从403到错误处理-创新互联

上篇博客,当没有权限的用户访问一些资源时,返回的是403错误,403对于用户来说是一个莫名其妙的数字,我们当然要处理成友好的提示。

创新互联建站服务项目包括田阳网站建设、田阳网站制作、田阳网页制作以及田阳网络营销策划等。多年来,我们专注于互联网行业,利用自身积累的技术优势、行业经验、深度合作伙伴关系等,向广大中小型企业、政府机构等提供互联网行业的解决方案,田阳网站推广取得了明显的社会效益与经济效益。目前,我们服务的客户以成都为中心已经辐射到田阳省份的部分城市,未来相信会继续扩大服务区域并继续获得客户的支持与信任!

关于错误处理,翻看了一下Nancy的源码,是这样处理的,见下面地址:

https://github.com/NancyFx/Nancy/blob/master/src/Nancy/ErrorHandling/DefaultStatusCodeHandler.cs

其实Nancy是允许我们采用相同的办法处理,现在把DefaultStatusCodeHandler.cs的源码复制下来,改成我们自己的CustomStatusCode.cs如下,关于详细说明,参考Nancy源码DefaultStatusCodeHandler.cs。

using Nancy;
using Nancy.ErrorHandling;
using Nancy.ViewEngines;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Nancy.Responses.Negotiation;
using Nancy.Extensions;
using Nancy.IO;
 
namespace NancySelfHostWeb
{
    public class CustomStatusCode: IStatusCodeHandler
    {
        
        private const string DisableErrorTracesTrueMessage = "Error details are currently disabled. Please set StaticConfiguration.DisableErrorTraces = false; to enable.";
 
        private readonly IDictionary errorMessages;
        private readonly IDictionary errorPages;
        private readonly IResponseNegotiator responseNegotiator;
        private readonly HttpStatusCode[] supportedStatusCodes = { HttpStatusCode.Forbidden, HttpStatusCode.NotFound};
 
        public CustomStatusCode(IResponseNegotiator responseNegotiator)
        {
            this.errorMessages = new Dictionary
            {
                { HttpStatusCode.Forbidden, "查看是否有授权!" },
                { HttpStatusCode.NotFound, "找不到你要的资源!" }
 
            };
            this.errorPages = new Dictionary
            {
                { HttpStatusCode.Forbidden, LoadResource("NancySelfHostWeb.403.html") },
                { HttpStatusCode.NotFound, LoadResource("NancySelfHostWeb.404.html") }
 
            };
            this.responseNegotiator = responseNegotiator;
        }
        
        public bool HandlesStatusCode(HttpStatusCode statusCode, NancyContext context)
        {
            return this.supportedStatusCodes.Any(s => s == statusCode);
        }
 
        public void Handle(HttpStatusCode statusCode, NancyContext context)
        {
            if (context.Response != null && context.Response.Contents != null && !ReferenceEquals(context.Response.Contents, Response.NoBody))
            {
                return;
            }
            if (!this.errorMessages.ContainsKey(statusCode) || !this.errorPages.ContainsKey(statusCode))
            {
                return;
            }
            Response existingResponse = null;
            if (context.Response != null)
            {
                existingResponse = context.Response;
            }
            context.NegotiationContext = new NegotiationContext();
            var result = new DefaultStatusCodeHandlerResult(statusCode, this.errorMessages[statusCode], StaticConfiguration.DisableErrorTraces ? DisableErrorTracesTrueMessage : context.GetExceptionDetails());
            try
            {
                context.Response = this.responseNegotiator.NegotiateResponse(result, context);
                context.Response.StatusCode = statusCode;
 
 
                if (existingResponse != null)
                {
                    context.Response.ReasonPhrase = existingResponse.ReasonPhrase;
                }
                return;
            }
            catch (ViewNotFoundException)
            {
            }
            this.ModifyResponse(statusCode, context, result);
        }
 
 
        private void ModifyResponse(HttpStatusCode statusCode, NancyContext context, DefaultStatusCodeHandlerResult result)
        {
            if (context.Response == null)
            {
                context.Response = new Response { StatusCode = statusCode };
            }
            var contents = this.errorPages[statusCode];
            if (!string.IsNullOrEmpty(contents))
            {
                contents = contents.Replace("[DETAILS]", result.Details);
            }
            context.Response.ContentType = "text/html";
            context.Response.Contents = s =>
            {
                using (var writer = new StreamWriter(new UnclosableStreamWrapper(s), Encoding.UTF8))
                {
                    writer.Write(contents);
                }
            };
        }
        private static string LoadResource(string filename)
        {
 
            // 获取当前资源文件
            var resourceStream = typeof(CustomStatusCode).Assembly.GetManifestResourceStream(string.Format("{0}", filename));
            if (resourceStream == null)
            {
                return string.Empty;
            }
            using (var reader = new StreamReader(resourceStream))
            {
                return reader.ReadToEnd();
            }
        }
        internal class DefaultStatusCodeHandlerResult
        {
            public DefaultStatusCodeHandlerResult(HttpStatusCode statusCode, string message, string details)
            {
                this.StatusCode = statusCode;
                this.Message = message;
                this.Details = details;
            }
            public HttpStatusCode StatusCode { get; private set; }
            public string Message { get; private set; }
            public string Details { get; private set; }
        }
    }
}

这样还可以把Nancy内置的500,404错误改成我们自定义的显示。

有时觉得这样太麻烦,可以自大在Module中去判断登录用户是否具有角色,代码如下

using Nancy;
using Nancy.Security;
using System.Linq;

namespace TestSelfHostWeb.Modules
{
    public class IndexModule : NancyModule
    {
        public IndexModule()
        {
            //开启全局验证
            this.RequiresAuthentication();
            Get["/"] = parameters =>
            {
                //开启角色验证,只有该角色可以访问本路由
                //this.RequiresClaims("admin");

                //自己判断登录角色具有权限
                if (!this.Context.CurrentUser.Claims.Contains("admin"))
                {
                    return View["error"];//定义一个错误页面error.cshtml即可
                }

                return View["index"];
            };
        }
    }
}

附件:http://down.51cto.com/data/2367711

创新互联www.cdcxhl.cn,专业提供香港、美国云服务器,动态BGP最优骨干路由自动选择,持续稳定高效的网络助力业务部署。公司持有工信部办法的idc、isp许可证, 机房独有T级流量清洗系统配攻击溯源,准确进行流量调度,确保服务器高可用性。佳节活动现已开启,新人活动云服务器买多久送多久。


分享标题:Nancy之从403到错误处理-创新互联
标题链接:http://pwwzsj.com/article/dcspij.html