In newtonsoft json.net when we use
JsonConvert.SerializeObject(null, Formatting.Indented)
I get "null" in the output as expected.
Now, I would like to represent objects (which can be null) with a JObject, but it throws an exception when I try to encode null this way:
(JObject.FromObject(null)).ToString(Formatting.Indented)
Is there a way to do this?
Thanks
To represent a null value with a JToken, you can use JValue.CreateNull().
JToken token = JValue.CreateNull();
string json = token.ToString();
If, like me, you are just trying to cast an object that may or may not be null to a JToken, you can use the implicit value conversion operators by just casting it to JToken.
JObject obj = new JObject();
string s = null;
int? i = null;
obj.Add("s", (JToken)s);
obj.Add("i", (JToken)i);
var serialized = obj.ToString(Formatting.Indented);
Related
I'm stuck on something:
I deserialized a JSON file using JObject.Load:
// get the JSON into an object
JObject jsonObject = JObject.Load(new
JsonTextReader(new StreamReader("mydoc.json")));
Fine. I now have a populate jsonObject.
Now I iterate through its properties like this:
foreach (JProperty jsonRootProperty in jsonObject.Properties())
{
if (jsonRootProperty.Name=="Hotel")
{
... !!! I just want a JObject here...
}
}
Once I find a property with a Name equal to "Hotel", I want that property's value as a JObject. The catch is that the Hotel property name might be a single value (say, a string), or it might be a JSON object or a JSON array.
How can I get the property's value into a JObject variable so that I can pass it to another function that accepts a JObject parameter?
Get the Value of the JProperty, which is a JToken, and look at its Type. This property will tell you if the token is an Object, Array, String, etc. If the token type is Object, then you can simply cast it to a JObject and pass it to your function. If the token type is something other than Object and your function has to have a JObject, then you'll need to wrap the value in a JObject in order to make it work.
foreach (JProperty jsonRootProperty in jsonObject.Properties())
{
if (jsonRootProperty.Name=="Hotel")
{
JToken value = jsonRootProperty.Value;
if (value.Type == JTokenType.Object)
{
FunctionThatAcceptsJObject((JObject)value);
}
else
{
FunctionThatAcceptsJObject(new JObject(new JProperty("value", value)));
}
}
}
I remember that one of my friends told me that I can throw anything into JSON.NET and serialize them into JSON format.
public string GetRecords(string apiKey, DateTime start, DateTime end)
{
var user = db.Users.SingleOrDefault(u => u.Id == apiKey);
if (user == null)
{
return string.Empty;
}
var records = db.Histories.Where(h => h.Date >= start && h.Date <= end);
JavaScriptSerializer s = new JavaScriptSerializer();
return JsonConvert.SerializeObject(records);
}
But now I got an exception:
There is already an open DataReader associated with this Command which
must be closed first.
What can I do to resolve this?
Call .ToList() on records, before passing it to JsonConvert.SerializeObject
You probably didn't enable multiple active result sets (MARS) in your config file.
Follow this link
Basically need to add
"MultipleActiveResultSets=True"
Or you could eager load as suggested by 3dd
More help here There is already an open DataReader associated with this Command which must be closed first
I have few empty route values I want in the query string:
var routeValues = new RouteValueDictionary();
routeValues.Add("one", "");
routeValues.Add("two", null);
routeValues.Add("three", string.Empty);
If I then pass it to UrlHelper.RouteUrl() it ignores all the values and the generated query string is empty. However, urls like /?one=&two=&three= are perfectly valid. How can I do that?
This behavior is built into the default Route class. It calls into the ParsedRoute.Bind() method where it does this check:
if (IsRoutePartNonEmpty(obj2))
{
acceptedValues.Add(key, obj2);
}
Which does this:
private static bool IsRoutePartNonEmpty(object routePart)
{
string str = routePart as string;
if (str != null)
{
return (str.Length > 0);
}
return (routePart != null);
}
This effectively prevents any query string values from being output if they are empty. Everything it does is private, static, internal, and otherwise impossible to override. So, there are really only 2 options to override this behavior.
Subclass Route and override GetVirtualPath(), replacing ParsedRoute.Bind() with a custom implementation.
Subclass RouteBase and create a custom route implementation.
I guess the 3rd option is to leave it alone, as others have pointed out this isn't really a problem since having an empty parameter in the query string has little or no value.
Is there a way to deserialize an array sent by jquery post method to directly c# string array(string[])?
I tried posting data like this
$.post(url,
{
'selectedTeams[]'=['Team1','Team2']
},
function(response) {}, 'json');
And trying to consume it like this in C# class
string jsonData = new StreamReader(context.Request.InputStream).ReadToEnd();
var selectedTeams = new JavaScriptSerializer().Deserialize<string[]>(jsonData);
It didn't work and ofcource it should not as there is no property selectedTeams[] in string[]
I am aware of the way to define a class something like this
class Teams
{
public string[] SelectedTeams{get;set;}
}
and then do the deserialization.
But I think that is an unnecessary defining a class so isn't there a way to directly convert json array to c# string array
Thanks in advance.
Figure it out!
Using stringified array object rather than direct named json parameter to pass as data solved my problem
I am now posting like this
var Ids = new Array();
Ids.push("Team1");
Ids.push("Team2");
$.post(url, JSON.stringify(Ids), function(response) {}, 'json');
And now able to deserialize json response directly to string array like this
string jsonData = new StreamReader(context.Request.InputStream).ReadToEnd();
var selectedTeams = new JavaScriptSerializer().Deserialize<string[]>(jsonData);
Thanks!!
you could develop your own class, but I would suggest you use this:
http://json.codeplex.com/
.Net's System.Web.HttpUtility class defines the following function to parse a query string into a NameValueCollection:
public static NameValueCollection ParseQueryString(string query);
Is there any function to do the reverse (i.e. to convert a NameValueCollection into a query string)?
System.Collections.Specialized.NameValueCollection does NOT support this, but a derived internal class System.Web.HttpValueCollection DOES (by overriding ToString()).
Unfortunately (being internal) you cannot instantiate this class directly, but one is returned by HttpUtility.ParseQueryString() (and you can call this with String.Empty, but not Null).
Once you have a HttpValueCollection, you can fill it from your original NameValueCollection by calling Add(), before finally calling ToString().
var nameValueCollection = new NameValueCollection {{"a","b"},{"c","d"}};
var httpValueCollection = System.Web.HttpUtility.ParseQueryString(String.Empty);
httpValueCollection.Add(nameValueCollection);
var qs = httpValueCollection.ToString();
nameValueCollection.ToString() = "System.Collections.Specialized.NameValueCollection"
httpValueCollection.ToString() = "a=b&c=d"
A NameValueCollection has an automatic ToString() method that will write all your elements out as a querystring automatically.
you don't need to write your own.
var querystringCollection = HttpUtility.ParseQueryString("test=value1&test=value2");
var output = querystringCollection.ToString();
output = "test=value1&test=value2"
I found that a combination of UriBuilder and HttpUtility classes meets my requirements to manipulate query parameters. The Uri class on its own is not enough, particularly as its Query property is read only.
var uriBuilder = new UriBuilder("http://example.com/something?param1=whatever");
var queryParameters = HttpUtility.ParseQueryString(uriBuilder.Query);
queryParameters.Add("param2", "whatever2");
queryParameters.Add("param3", "whatever2");
uriBuilder.Query = queryParameters.ToString();
var urlString = uriBuilder.Uri.ToString();
The above code results in the URL string: http://example.com/something?param1=whatever¶m2=whatever2¶m3=whatever2
Note that the ToString() goes via a Uri property, otherwise the output string would have an explicit port 80 in it.
It's nice to be able to do all this using framework classes and not have to write our own code.
I don't think there is a built in one, but here is an example of how to implement http://blog.leekelleher.com/2008/06/06/how-to-convert-namevaluecollection-to-a-query-string/
Here are 2 very useful functions that I use all the time:
private string GetQueryStringParameterValue(Uri url, string key)
{
return HttpUtility.ParseQueryString(url.Query.TrimStart('?'))[key];
}
private Uri SetQueryStringParameterValue(Uri url, string key, string value)
{
var parameters = HttpUtility.ParseQueryString(url.Query.TrimStart('?'));
parameters[key] = value;
var uriBuilder = new UriBuilder(url) { Query = parameters.ToString() };
return uriBuilder.Uri;
}