. asmx怪从log4javascript日志反序列化JSON blob

.ASMX weirdness deserializing JSON blob from log4javascript logging?

本文关键字:JSON blob 反序列化 日志 怪从 log4javascript asmx      更新时间:2023-09-26

当我试图反序列化log4javascript使用ajax appender与JSON布局生成的JSON blob时,我得到了'无效的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);

问题是,JSON log4javascript正在生产有一个末尾逗号在这里:

'"message'":['"Message 1'"],

…这是无效的,有点尴尬的我作为log4javascript的开发人员。

我会修复这个问题,并尽快发布新版本。