开发者

.ASMX weirdness deserializing JSON blob from log4javascript logging?

开发者 https://www.devze.com 2023-04-12 22:28 出处:网络
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'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 val开发者_如何学JAVAue 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);


The problem is that the JSON log4javascript is producing has a trailing comma here:

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

... 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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号