.ASMX 从 log4javascript 日志记录中反序列化 JSON blob 很奇怪?
当我尝试反序列化 log4javascript 使用 ajax 附加程序 与 json布局。
我编写了一个 Web 服务方法来接收 log4javascript 发送的 JSON,但 JSON 被声明为无效,并且当 .NET 尝试反序列化它时会抛出异常,我不明白为什么。
JS 设置看起来像这样:
var requestURL = (
$.url.build({
"path": "ClientSideLoggingSupport.asmx/Log"
})
);
var requestURLEncoded = $.url.encode(requestURL)
var log4js = log4javascript.getLogger();
var ajaxAppender = new log4javascript.AjaxAppender(requestURLEncoded);
ajaxAppender.setLayout(new log4javascript.JsonLayout(false, false));
log4js.addAppender(ajaxAppender);
log4js.info("Message 1");
'log' 方法看起来像这样:
[WebMethod(Description = "Accepts a request to log client side information")]
[ScriptMethod(UseHttpGet = false, ResponseFormat = ResponseFormat.Json, XmlSerializeString = false)]
public void Log()
{
try
{
System.Collections.Specialized.NameValueCollection nvcss = this.Context.Request.Form;
var jss = new JavaScriptSerializer();
string s = nvcss["data"].ToString();
Dictionary<string, string> x = jss.Deserialize<Dictionary<string, string>>(nvcss["data"].ToString());
var dict = jss.Deserialize<Dictionary<string, string>>(nvcss["data"]);
_NLogLogger.Info("The logging web service was invoked");
}
catch (Exception ex)
{
_NLogLogger.Error("Some sort of problem occurred1");
_NLogLogger.Error(String.Format("Ex.Message = {0}", ex.Message));
_NLogLogger.Error(String.Format("Ex.Source = {0}", ex.Source));
_NLogLogger.Error(String.Format("Ex.StackTrace = {0}", ex.StackTrace));
_NLogLogger.Error(String.Format("Ex.InnerException = {0}", ex.InnerException));
throw;
}
}
上面方法中 s 的值在抛出异常之前看起来像这样 : :
"[{\"logger\":\"[anonymous]\",\"timestamp\":1318394483187,\"level\":\"INFO\",\"url\":\"http://localhost:19019/Logon.aspx\",\"message\":[\"Message 1\"],}]"
在我看来,这像是一个合理的字符串来提供反序列化器,但显然它是不是 !有人知道我(或 log4javascript)做错了什么吗?
好吧,我已经意识到我的代码有一些错误,但修复它并不能真正解决问题。
JSON 表示对象数组,因此接收反序列化结果的对象需要一个字典列表。所以我修改了反序列化代码如下:
//Alter instantion of JavaScriptSerializer
JavaScriptSerializer jsss = new JavaScriptSerializer();
//Request Deserialization presuming a list of dictionaries
List<Dictionary<string, string>> xx = jsss.Deserialize<List<Dictionary<string, string>>>(nvcss["data"]);
所以,我相信更好,但仍然抛出相同的异常。
对于它的价值,我现在在方法中包含以下代码行,并且它执行得很好,因此它看起来越来越像是由 log4javascript 生成的 JSON,需要以某种方式进行调整
List<Dictionary<string, string>> o = jsss.Deserialize<List<Dictionary<string, string>>>("[{'a':1,'b':2},{'a':10,'b':20}]");
欢迎任何建议。
在注意到 JSON 的“message”属性本身就是一个数组后,我暂时更改了“message”,使其成为一个缩放器,取得了更多(某种程度)的进展。这样,JSON 看起来像这样:
List<Dictionary<string, string>> ooo = jsss.Deserialize<List<Dictionary<string, string>>>("[{\"logger\":\"[anonymous]\",\"timestamp\":1318394483187,\"level\":\"INFO\",\"url\":\"http://localhost:19019/Logon.aspx\",\"message\":\"Message 1\"}]");
...然后就可以执行,所以问题似乎是 JSON 具有嵌入数组,因此需要指定不同的目标对象才能反序列化 JSON成功地。
最终编辑! 感谢 Tim 发现了 JSON 中的缺陷,我现在有了一个工作版本。我假装 JSON 正在做正确的事情,然后以一种相当不优雅的方式转储消息有效负载,但它可能对将来的某人有用。
List<Dictionary<string, object>> lstMsg = jsss.Deserialize<List<Dictionary<string, object>>>("[{\"logger\":\"[anonymous]\",\"timestamp\":1318394483187,\"level\":\"INFO\",\"url\":\"http://localhost:19019/Logon.aspx\",\"message\":[\"Message 1\"]}]");
string sOut = "";
foreach (Dictionary<string, object> m in lstMsg)
{
sOut = sOut + m["timestamp"];
foreach(string sMessage in (ArrayList)m["message"])
{
sOut = sOut + "|" + sMessage;
}
}
_NLogLogger.Info("sOut:" + sOut);
I'm getting 'invalid JSON primitive' when i try to deserialize a JSON blob generated by log4javascript using the ajax appender with the json layout.
I've written a web service method to recieve the JSON sent by log4javascript but the JSON is declared invalid and an exception thrown when .NET tries to deserialize it and I can't understand why.
The JS setup looks like this :
var requestURL = (
$.url.build({
"path": "ClientSideLoggingSupport.asmx/Log"
})
);
var requestURLEncoded = $.url.encode(requestURL)
var log4js = log4javascript.getLogger();
var ajaxAppender = new log4javascript.AjaxAppender(requestURLEncoded);
ajaxAppender.setLayout(new log4javascript.JsonLayout(false, false));
log4js.addAppender(ajaxAppender);
log4js.info("Message 1");
The 'log' method looks like this :
[WebMethod(Description = "Accepts a request to log client side information")]
[ScriptMethod(UseHttpGet = false, ResponseFormat = ResponseFormat.Json, XmlSerializeString = false)]
public void Log()
{
try
{
System.Collections.Specialized.NameValueCollection nvcss = this.Context.Request.Form;
var jss = new JavaScriptSerializer();
string s = nvcss["data"].ToString();
Dictionary<string, string> x = jss.Deserialize<Dictionary<string, string>>(nvcss["data"].ToString());
var dict = jss.Deserialize<Dictionary<string, string>>(nvcss["data"]);
_NLogLogger.Info("The logging web service was invoked");
}
catch (Exception ex)
{
_NLogLogger.Error("Some sort of problem occurred1");
_NLogLogger.Error(String.Format("Ex.Message = {0}", ex.Message));
_NLogLogger.Error(String.Format("Ex.Source = {0}", ex.Source));
_NLogLogger.Error(String.Format("Ex.StackTrace = {0}", ex.StackTrace));
_NLogLogger.Error(String.Format("Ex.InnerException = {0}", ex.InnerException));
throw;
}
}
The value of s in the above method looks like this just before the exception is thrown : :
"[{\"logger\":\"[anonymous]\",\"timestamp\":1318394483187,\"level\":\"INFO\",\"url\":\"http://localhost:19019/Logon.aspx\",\"message\":[\"Message 1\"],}]"
That looks to me like a plausible string to feed the deserializer but clearly it's not ! Anyone know what I (or log4javascript) is doing wrong ?
OK I've realised something about my code which is wrong but fixing that doesn't actually fix the problem.
The JSON represents an array of objects and so the object receiving the results of the deserialization needs to a list of dictionaries. So I have amended the deserialization code as follows :
//Alter instantion of JavaScriptSerializer
JavaScriptSerializer jsss = new JavaScriptSerializer();
//Request Deserialization presuming a list of dictionaries
List<Dictionary<string, string>> xx = jsss.Deserialize<List<Dictionary<string, string>>>(nvcss["data"]);
So this is, I believe better, but still throws the same exception.
For what it's worth I now have the following line of code within the method and it executes fine so it looks increasingly as if it's the JSON produced by log4javascript which needs adjusting in some way
List<Dictionary<string, string>> o = jsss.Deserialize<List<Dictionary<string, string>>>("[{'a':1,'b':2},{'a':10,'b':20}]");
Any suggestions welcome.
More progress (of a sort) after noticing that the 'message' attribute of the JSON was itself an array I temporarily changed 'message' so that it's a scaler. In this way the JSON looks like this:
List<Dictionary<string, string>> ooo = jsss.Deserialize<List<Dictionary<string, string>>>("[{\"logger\":\"[anonymous]\",\"timestamp\":1318394483187,\"level\":\"INFO\",\"url\":\"http://localhost:19019/Logon.aspx\",\"message\":\"Message 1\"}]");
... and this is then able to execute so it seems like the problem is that the JSON has an embedded array and so a different target object will need to be specified in order to deserialize the JSON successfully.
Final edit ! Thanks to Tim spotting the flaw in the JSON I've now got a working version. I've pretended the JSON is doing the right thing and then just dumped out the message payload in a fairly unelegant fashion but it may be useful to someone in future.
List<Dictionary<string, object>> lstMsg = jsss.Deserialize<List<Dictionary<string, object>>>("[{\"logger\":\"[anonymous]\",\"timestamp\":1318394483187,\"level\":\"INFO\",\"url\":\"http://localhost:19019/Logon.aspx\",\"message\":[\"Message 1\"]}]");
string sOut = "";
foreach (Dictionary<string, object> m in lstMsg)
{
sOut = sOut + m["timestamp"];
foreach(string sMessage in (ArrayList)m["message"])
{
sOut = sOut + "|" + sMessage;
}
}
_NLogLogger.Info("sOut:" + sOut);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
问题是,生成的 JSON log4javascript 此处有一个尾随逗号:
... 这是无效的,对于作为 log4javascript 开发人员的我来说有些尴尬。
我会修复这个问题并尽快发布新版本。
The problem is that the JSON log4javascript is producing has a trailing comma here:
... which is invalid, and somewhat embarrassing for me as log4javascript's developer.
I'll fix this and release a new version as soon as possible.