-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WebServiceTarget support for Posting JSON, XML + Injecting JSON serializer into NLog #1740
WebServiceTarget support for Posting JSON, XML + Injecting JSON serializer into NLog #1740
Conversation
…rget added corresponding tests to WebServiceTargetTests
Cool! Could you undo the moved methods? It would be easier to review and otherwise we have a hard time merging this also in the .NET Core branch. Thanks! |
Oh I see, that auto sorting and formatting of VS has created a diff-hell. Good night. |
How do you want JSONSerializer to be 'injected' ? For XmlSerializer too? |
Maybe, but that's already in non system.web libraries so less a problem IMO |
So JSONSerializer injecting by defining an interface and adding a property to the target? |
Yes, and it would be nice if the property is at higher level than this target. I think |
good night! |
So, tried a completed reformatting as good as possible. I would then go and deal with JsonFormatter injection. |
Current coverage is 82% (diff: 83%)@@ master #1740 diff @@
==========================================
Files 276 274 -2
Lines 17711 18224 +513
Methods 2768 2833 +65
Messages 0 0
Branches 2020 2085 +65
==========================================
+ Hits 14271 14854 +583
+ Misses 2987 2908 -79
- Partials 453 462 +9
|
Two possible ways spontaneously cross my mind:
The first option would be more simple and quickly done, the second option indeed slightly more complex but more extendible and may be used for further scenarios. On the other hand, if no one can think of any additional use cases, that would be a perfect example of overkill. |
Interface so far (inspired by JsonSerializer by NewtonSoft):
|
I prefer the first one. More in line with the current options in NLog. :) |
After reflecting about it... |
Well then the simple json serializer will work. Except that is an issue with the current implementation when there is a quote in the value AFAIK. |
private static string getJsonValueString(object value) | ||
{ | ||
if (value == null) return "null"; | ||
else if (value is string) return string.Format("\"{0}\"", value); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we need to escape the quote inside the string?
Yup, now as you say it, forgot to escape strings. |
I'm on it by tomorrow. |
thus a custom JSON serialize can be set in and injected via ConfigurationItemFactory into WebServiceTarget
So, since the named parameters in config are just objects, I decided to add a slim serilizer interface, namely Let me know, what you think... uhm, and I just see, I have to deal with Travis complaints :-/ |
Don't understand this: AppVeyor is complaining about things, that aren't contained in that files ?!? |
fixed Silverlight specific constructors
So I'm tempted to say, we keep the serializer rudimentary and leave out serialization of collection types, because there are ready, mature serializers out there one can use, which have been the reason for this interface. |
/// </summary> | ||
public class DefaultJsonSerializer : IJsonSerializer | ||
{ | ||
private static List<Type> NumericTypes = new List<Type> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please create use a hashset (because of the contains
futher)
The easier and better way is to store the reference the a hashset? (and compare if it's already used) |
Good point, doubting as I think we are almost there. |
So: Allright? |
Yes that would be nice! |
I'm on it |
Although the question may be: how to handle reference loops? JSON.NET for example per default breaks with an exception. You can alter this behavior to 2 alternatives. |
Consider extracting the method JsonLayout.IsNumeric() into a helper-class, then you can skip the HashSet-Lookup. |
I prefer skip instead of exception |
Now it uses Hashset (and Contains() ) for checking current serialization path for loop. In the (unlikely) case of an infinite loop because of special implementations of IEnumerable for example, there is also an maximum recursion depth of 10, just protecting application from a stack overflow or out of memory. |
👍 |
string valueString = string.Empty; | ||
if (!string.IsNullOrEmpty(parameterValue)) | ||
{ | ||
var sb = new StringBuilder(Math.Max(parameterValue.Length + 20, Target.Parameters.Count > 1 ? 256 : 0)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Target.Parameters.Count-check only makes sense when using the same StringBuilder for streaming all parameters.
Unless you optimize the (re-)usage of the StringBuilder, then it should just be:
var sb = new StringBuilder(parameterValue.Length + 20);
UrlHelper.EscapeDataEncode(parameterValue, sb, encodingFlags); | ||
valueString = sb.ToString(); | ||
} | ||
|
||
return string.Format("{0}={1}", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could it not be changed it into:
if (string.IsNullOrEmpty(parameterValue))
{
return string.Concat(parameter.Name, "=");
}
else
{
var sb = new StringBuilder(parameter.Name.Length + parameterValue.Length + 20);
sb.Append(parameter.Name);
sb.Append("=");
UrlHelper.EscapeDataEncode(parameterValue, sb, encodingFlags);
return sb.ToString();
}
(Could probably be optimized even more if re-using the StringBuilder)
|
||
protected override string GetFormattedContent(string parametersContent) | ||
{ | ||
return string.Format("{{{0}}}", parametersContent); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider changing into this:
return string.Concat("{{", parametersContent, "}}");
} | ||
else | ||
{ | ||
soapAction = Target.Namespace + "/" + Target.MethodName; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider changing into this:
soapAction = string.Concat(Target.Namespace, "/", Target.MethodName);
(Maybe also use string.Concat for the one without slash for consistency)
This is ready to merge right? |
} | ||
else | ||
{ | ||
var sb = new StringBuilder(parameterValue.Length + 20); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider changing it into:
var sb = new StringBuilder(parameter.Name.Length + parameterValue.Length + 20);
Reviewed 1 of 17 files at r10, 1 of 4 files at r11, 21 of 22 files at r13, 1 of 1 files at r14. Comments from Reviewable |
@tetrodoxin I have one final comment: please don't create variables with just 1 char! When those names are fixed, I will merge it. @snakefoot it's OK for me to merge it and tweaks some last things with a new PR. |
Added support for POST of JSON and XML documents and added respective tests. I tried to keep it simple, comprehensible and not to break with existing functionality.
I'd have to change existing tests in WebServiceTargetTests to extend their usability to the new types but I wasn't sure about altering existing tests of other authors, so I added new parts.
Have a look and tell me what you think about the direction it's heading.
This change is
fixes #700