Пример #1
0
        /// <summary>
        /// 主入口
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public async Task Invoke(TContext context)
        {
            string requestPath = GetRequestPath(context);

            //路径为"/"时变为类"/Index.html"
            if (requestPath.Length == 1)
            {
                requestPath = defaultUrl;
            }
            string actionKey;
            int    shortActionKeyLength;

            //获取actionKey
            if (debug)
            {
                actionKey = NFinal.Url.ActionKey.GetActionKey(GetRequestMethod(context), requestPath, out shortActionKeyLength);
            }
            else
            {
                actionKey = NFinal.Url.ActionKey.GetActionKey(GetRequestMethod(context), requestPath, out shortActionKeyLength);
            }
            bool hasError = false;

            NFinal.Action.ActionData <TContext, TRequest> actionData;
            if (actionFastDic.TryGetValue(actionKey, actionKey.Length, out actionData))
            {
                TRequest request = default(TRequest);
                try
                {
                    request = GetRequest(context);
                }
                catch
                {
                    hasError = true;
                    if (actionData.plugConfig.customErrors.mode == Config.Plug.CustomErrorsMode.Off)
                    {
                        using (IAction <TContext, TRequest> controller = GetAction(context, actionData.plugConfig))
                        {
                            controller.Initialization(context, actionData.methodName, null, request, CompressMode.GZip, actionData.plugConfig);
                            controller.SetResponseHeader("Content-Type", "text/html; charset=utf-8");
                            //解析出错
                            controller.SetResponseStatusCode(200);
                            controller.Close();
                        }
                    }
                }
                NameValueCollection parameters = GetParameters(request);
                //获取Url中的参数
                if (actionData.actionUrlData != null && !actionData.actionUrlData.hasNoParamsInUrl)
                {
                    if (actionData.actionUrlData.isSimpleUrl)
                    {
                        NFinal.Url.ActionUrlHelper.SimpleParse(requestPath, parameters, actionData.actionUrlData.actionUrlNames, shortActionKeyLength, actionData.actionUrlData.extensionLength);
                    }
                    else
                    {
                        NFinal.Url.ActionUrlHelper.RegexParse(requestPath, parameters, actionData.actionUrlData.actionUrlNames, actionData.actionUrlData.parameterRegex);
                    }
                }
                //生产环境下
                if (!debug)
                {
                    if (!NFinal.Filter.FilterHelper.ParamaterFilter(actionData.IParametersFilters, parameters))
                    {
                        await FinishedTask;
                    }
                    try
                    {
                        actionData.actionExecute(context, actionData, request, parameters);
                    }
                    catch (Exception)
                    {
                        hasError = true;
                        if (actionData.plugConfig.customErrors.mode == Config.Plug.CustomErrorsMode.Off)
                        {
                            using (IAction <TContext, TRequest> controller = GetAction(context, actionData.plugConfig))
                            {
                                controller.Initialization(context, null, null, request, CompressMode.GZip, actionData.plugConfig);
                                controller.SetResponseHeader("Content-Type", "text/html; charset=utf-8");
                                //服务器错误
                                controller.SetResponseStatusCode(500);
                                controller.Close();
                            }
                        }
                    }
                    if (hasError)
                    {
                        using (IAction <TContext, TRequest> controller = GetAction(context, actionData.plugConfig))
                        {
                            controller.Initialization(context, null, null, request, CompressMode.GZip, actionData.plugConfig);
                            controller.Redirect(actionData.plugConfig.customErrors.defaultRedirect);
                        }
                    }
                }
                //测试环境下
                else
                {
                    //actionData.actionExecute(context, actionData, request, parameters);
                    try
                    {
                        actionData.actionExecute(context, actionData, request, parameters);
                    }
                    catch (System.Exception e)
                    {
                        #region 输出错误信息
                        using (
                            IAction <TContext, TRequest> controller = GetAction(context, actionData.plugConfig))
                        {
                            controller.SetResponseHeader("Content-Type", "text/html; charset=utf-8");
                            controller.SetResponseStatusCode(200);

                            controller.Write("错误消息:<br/>");
                            controller.Write(e.Message);
                            controller.Write("<br/>");
                            controller.Write("请求时发生错误:<br>");
                            controller.Write(GetRequestPath(context));
                            controller.Write("<br/>");
                            controller.Write("错误跟踪:</br>");
                            string[] stackTraces = e.StackTrace.Split('\n');
                            System.Text.RegularExpressions.Regex reg = new System.Text.RegularExpressions.Regex(@"\s+at\s([\S\s]+)(\sin\s([\S\s]+):line\s([0-9]+))+?\s*");
                            System.Text.RegularExpressions.Match mat;
                            string atfunctionName;
                            string infilePostion;
                            string fileName;
                            int    lineNum;
                            string fileText;
                            int    currentLineNum;
                            controller.Write("<html>");
                            controller.Write("<head></head>");
                            controller.Write("<body>");
                            controller.Write("<div id=\"traces\">");
                            for (int i = 0; i < stackTraces.Length; i++)
                            {
                                controller.Write("<dl>");
                                mat = reg.Match(stackTraces[i]);
                                controller.Write("<dt style=\"background:grey;cursor:pointer;\">");
                                controller.Write(stackTraces[i]);
                                controller.Write("</dt>");
                                if (i == 0)
                                {
                                    controller.Write("<dd style=\"display: block;\">");
                                }
                                else
                                {
                                    controller.Write("<dd style=\"display: none;\">");
                                }
                                if (mat.Success)
                                {
                                    atfunctionName = mat.Groups[1].Value;
                                    //controller.Write(atfunctionName);

                                    if (mat.Groups[2].Success)
                                    {
                                        infilePostion = mat.Groups[2].Value;
                                        fileName      = mat.Groups[3].Value;
                                        int.TryParse(mat.Groups[4].Value, out lineNum);
                                        controller.Write(fileName);
                                        controller.Write("<br/>");
                                        using (StreamReader reader = File.OpenText(fileName))
                                        {
                                            currentLineNum = 0;
                                            controller.Write("<ul style=\"list-style:none;\">");
                                            while (!reader.EndOfStream)
                                            {
                                                currentLineNum++;
                                                fileText = reader.ReadLine();
                                                if (currentLineNum == lineNum)
                                                {
                                                    controller.Write("<li style=\"background:red;min-width:500px;\">");
                                                }
                                                else
                                                {
                                                    controller.Write("<li>");
                                                }
                                                controller.Write(string.Format("{0:0000}", currentLineNum));
                                                controller.Write(":");
                                                if (currentLineNum == lineNum)
                                                {
                                                    controller.Write(fileText.Replace("<", "&lt")
                                                                     .Replace(">", "&gt;")
                                                                     .Replace("\t", "&nbsp&nbsp&nbsp&nbsp").Replace(" ", "&nbsp"));
                                                }
                                                else
                                                {
                                                    controller.Write(fileText.Replace("<", "&lt")
                                                                     .Replace(">", "&gt;")
                                                                     .Replace("\t", "&nbsp&nbsp&nbsp&nbsp").Replace(" ", "&nbsp"));
                                                }
                                                controller.Write("</li>");
                                                //controller.Write("<br/>");
                                            }
                                            controller.Write("</ul>");
                                        }
                                    }
                                    else
                                    {
                                        controller.Write(atfunctionName);
                                    }
                                }
                                controller.Write("</dd>");
                                controller.Write("</dl>");
                            }
                            controller.Write("</div>");
                            controller.Write("</body>");
                            controller.Write("</html>");
                            controller.Write(@"<script>
                                var tracesDiv = document.getElementById('traces');
                                var traceTitles = tracesDiv.getElementsByTagName('dt');
                                for (var i = 0; i < traceTitles.length; i++)
                                {
                                    traceTitles[i].addEventListener('click',function() {
                                        if (this.nextSibling.style.display == 'none')
                                        {
                                            this.nextSibling.style.display = 'block';
                                        }
                                        else
                                        {
                                            this.nextSibling.style.display = 'none';
                                        }
                                    });
                                }
                            </script>");
                            controller.Close();
                        }
                        #endregion
                        await FinishedTask;
                    }
                }
                await FinishedTask;
            }
            else
            {
                await _next.Invoke(context);
            }
        }