/// <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("<", "<") .Replace(">", ">") .Replace("\t", "    ").Replace(" ", " ")); } else { controller.Write(fileText.Replace("<", "<") .Replace(">", ">") .Replace("\t", "    ").Replace(" ", " ")); } 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); } }