换句话说,使用 HttpContext,我如何检索传递给[WebMethod]
什么时候在全局错误处理程序中?
Kovu 给出了一个很好的例子如何做一个全局错误陷阱来抓取[WebMethod]
Global.asax 中的错误,我认为他是从那里得到的理查德刘在这里,但他的解决方案没有捕获传递给 WebMethod 的参数,我确实需要记录这些参数来重现错误。
我改编了 Richard/Kovu 的示例来开始捕获有关请求的更多内容,但我只是找不到输入参数的位置[WebMethod]
被隐藏。
/* global.asax */
protected void Application_PostMapRequestHandler(object sender, EventArgs e)
{
/* REQUIRES
<system.web>
<customErrors mode="Off"/>
TO WORK IN PRODUCTION
*/
HttpContext context = HttpContext.Current;
if (context.Handler is Page && !string.IsNullOrEmpty(context.Request.PathInfo))
{
string contentType = context.Request.ContentType.Split(';')[0];
if (contentType.Equals("application/json", StringComparison.OrdinalIgnoreCase))
{
context.Response.Filter = new PageMethodExceptionLogger(context);
}
}
}
using System.Collections.Generic;
using System.IO;
using System.Web;
using System.Web.Script.Serialization;
public class PageMethodExceptionLogger : Stream
{
private readonly HttpContext _context;
private readonly Stream _baseStream;
private readonly MemoryStream _capturedStream = new MemoryStream();
public PageMethodExceptionLogger(HttpContext context)
{
_context = context;
_baseStream = context.Response.Filter;
}
public override void Close()
{
if (_context.Response.StatusCode == 500 && _context.Response.Headers["jsonerror"] == "true")
{
string sErr = "trapped json error, probably in [WebMethod]:\r\n\r\n";
//this will log the error and stack trace.
_capturedStream.Position = 0;
string responseJson = new StreamReader(_capturedStream).ReadToEnd();
JavaScriptSerializer js = new JavaScriptSerializer();
var jsonObject = js.DeserializeObject(responseJson) as Dictionary<string, object>;
foreach (string sKey in jsonObject.Keys)
sErr += string.Format("{0}:\r\n{1}\r\n\r\n", sKey, jsonObject[sKey]);
//============= LOG THE INPUT PARAMETERS ========================================================
sErr += "\r\n=== Request ===\r\n";
sErr += "Content Type = " + _context.Request.ContentType + "\r\n";
sErr += "Content Encoding = " + _context.Request.ContentEncoding.BodyName + "\r\n";
_context.Request.InputStream.Position = 0;
//========= this holds the parameters passed to the [WebMethod] ========
// It holds a JSON string, so could deserialize as above, but
// useful to see the original string format for debugging
// purposes, as the json format could be the issue that triggered this log!! ;-)
sErr += "\r\n=== INPUT ===\r\n";
try
{
long iReadLen = _context.Request.InputStream.Length;
if (iReadLen > 0)
{
var bytes = new byte[iReadLen];
_context.Request.InputStream.Position = 0;
_context.Request.InputStream.Read(bytes, 0, (int)iReadLen);
sErr += System.Text.Encoding.UTF8.GetString(bytes) + "\r\n";
}
else
{
sErr += "Request.InputStream is empty\r\n";
sErr += System.Text.Encoding.Default.GetString(_context.Request.BinaryRead(_context.Request.TotalBytes));
}
}
catch(Exception oEx)
{
sErr += "Error reading Request.InputStream; " + oEx.Message;
}
sErr += "\r\n=== HEADERS ===\r\n";
sErr += HttpUtility.UrlDecode(_context.Request.Headers.ToString()).Replace("&", "\r\n") + "\r\n";
sErr += "\r\n=== USER ===\r\n";
try
{
sErr += "Current User = " + _context.User.Identity.Name + "\r\n\r\n";
}
catch
{
sErr += "oContext.User.Identity.Name could not be retrieved!!!\r\n\r\n";
}
//====== LOG THE SESSION ========
sErr += "\r\n=== Session Variables ===\r\n";
if (_context.Session == null)
{
sErr += "session object is null\r\n";
}
else
{
sErr += "There are " + _context.Session.Count.ToString() + " session variables\r\n";
foreach (string sKey in _context.Session)
{
sErr += sKey + "=" + _context.Session[sKey].ToString() + "\r\n";
}
}
sErr += "\r\n";
clsErrorHandler.LogMessage(sErr);
}
_baseStream.Close();
base.Close();
}
public override void Flush()
{
_baseStream.Flush();
}
public override long Seek(long offset, SeekOrigin origin)
{
return _baseStream.Seek(offset, origin);
}
public override void SetLength(long value)
{
_baseStream.SetLength(value);
}
public override int Read(byte[] buffer, int offset, int count)
{
return _baseStream.Read(buffer, offset, count);
}
public override void Write(byte[] buffer, int offset, int count)
{
_baseStream.Write(buffer, offset, count);
_capturedStream.Write(buffer, offset, count);
}
public override bool CanRead { get { return _baseStream.CanRead; } }
public override bool CanSeek { get { return _baseStream.CanSeek; } }
public override bool CanWrite { get { return _baseStream.CanWrite; } }
public override long Length { get { return _baseStream.Length; } }
public override long Position
{
get { return _baseStream.Position; }
set { _baseStream.Position = value; }
}
}
现在这段代码给出了以下输出。(格式很混乱,因为我不知道如何使用所见即所得编辑器,抱歉)。
=================================================== ========== 捕获的 json 错误,可能在 [WebMethod] 中:
消息:传入的对象无效,应为“:”或“}”。 (23):
{'sKitName':'christin'a'}
堆栈跟踪:位于
System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializeDictionary(Int32
深度)在
System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializeInternal(Int32
深度)在
System.Web.Script.Serialization.JavaScriptObjectDeserializer.BasicDeserialize(字符串
输入、Int32 深度限制、JavaScriptSerializer 序列化器)位于
System.Web.Script.Serialization.JavaScriptSerializer.Deserialize(JavaScriptSerializer
序列化器、字符串输入、类型类型、Int32 深度限制)位于
System.Web.Script.Serialization.JavaScriptSerializer.Deserialize[T](字符串
输入)在
System.Web.Script.Services.RestHandler.GetRawParamsFromPostRequest(HttpContext
上下文,JavaScriptSerializer 序列化器)位于
System.Web.Script.Services.RestHandler.GetRawParams(WebServiceMethodData
methodData、HttpContext 上下文)位于
System.Web.Script.Services.RestHandler.ExecuteWebServiceCall(HttpContext
上下文、WebServiceMethodData 方法数据)
异常类型:System.ArgumentException
=== 输入 === {'sKitName':'christin'a'}
=== headers === Connection=keep-alive Content-Length=25 Content-Type=application/json;字符集=UTF-8 接受=application/json,
文本/JavaScript,/; q=0.01 接受编码=gzip, deflate
接受语言=en-US,en;q=0.9
Cookie=.ADAuthCookie=A12630A2F7FEA673C36FDC28C7625ED4C4C92760B0EEE6C68C8068FF81A8773DF1916B4A067326576F4D067D4C26C874A9C3C96D81F74D15E0452EDD7 43C3472F530DE5E6542E8DE1DD19BF76114702F70AF483DBF963C8686727CB541151EBF32322CD647ADD6D9FC01C4785393227F19341D2BE320DF821E0E223A24B7FBB5E5 CA7F79D87815AF49AF24C455CA81FD;
ASP.NET_SessionId=iqc0ztobmcva4lqbtii222fa 主机=web04.local
推荐人=http://web04.local/APP/Chem_View/Reagent_Kit_Inventory.aspx用户代理=Mozilla/5.0(Windows NT 10.0;Win64;x64)
AppleWebKit/537.36(KHTML,如 Gecko)Chrome/76.0.3809.132
Safari/537.36 起源=http://web04.localX-Requested-With=XMLHttpRequest
=== 用户 === 当前用户 = lila.whitehead
=== 会话变量 === 有 1 个会话变量 dtTouched=
于 2019 年 9 月 9 日 2:37:00 下午
=================================================== =========