问题
I got a couple different formats that come in but I can't figure out how to handle them all because when I try to find by key json.net crashes. I was hoping it would just return null.
foreach (var item in jsonObj)
{
var msg = item.Value["Msg"];
if (msg != null)
{
txtErrors.Text += msg + Environment.NewLine;
}
}
// format one
{[UserNotFound, {
"SeverityType": 3,
"ValidationType": 2,
"Msg": "Email Not Found"
}]}
my code works.
// format 2 (came because I did not catch an exception on serverside)
{
"Message": "An error has occurred.",
"ExceptionMessage": "Object reference not set to an instance of an object.",
"ExceptionType": "System.NullReferenceException",
"StackTrace": " "
}
I can of course fix this and catch the exception. However if I ever forget again, I rather not have it crash on the client as well. So I would love to just print out the "message" but I don't get how to do it so it does not crash on var msg = item.Value["Msg"];
The error I get when it tries to do var msg = item.Value["Msg"];
System.InvalidOperationException was unhandled
Message=Cannot access child value on Newtonsoft.Json.Linq.JValue.
StackTrace:
at Newtonsoft.Json.Linq.JToken.get_Item(Object key)
at Fitness.WindowsPhone7.UI.MainPage.<btnSignIn_Click>b__0(IRestResponse response)
at RestSharp.RestClientExtensions.<>c__DisplayClass1.<ExecuteAsync>b__0(IRestResponse response, RestRequestAsyncHandle handle)
at RestSharp.RestClient.ProcessResponse(IRestRequest request, HttpResponse httpResponse, RestRequestAsyncHandle asyncHandle, Action`2 callback)
at RestSharp.RestClient.<>c__DisplayClass3.<ExecuteAsync>b__0(HttpResponse r)
at RestSharp.RestClient.<>c__DisplayClass5.<>c__DisplayClass7.<ExecuteAsync>b__2(Object s)
at System.Reflection.RuntimeMethodInfo.InternalInvoke(RuntimeMethodInfo rtmi, Object obj, BindingFlags invokeAttr, Binder binder, Object parameters, CultureInfo culture, Boolean isBinderDefault, Assembly caller, Boolean verifyAccess, StackCrawlMark& stackMark)
at System.Reflection.RuntimeMethodInfo.InternalInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, StackCrawlMark& stackMark)
at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
at System.Delegate.DynamicInvokeOne(Object[] args)
at System.MulticastDelegate.DynamicInvokeImpl(Object[] args)
at System.Delegate.DynamicInvoke(Object[] args)
at System.Windows.Threading.DispatcherOperation.Invoke()
at System.Windows.Threading.Dispatcher.Dispatch(DispatcherPriority priority)
at System.Windows.Threading.Dispatcher.OnInvoke(Object context)
at System.Windows.Hosting.CallbackCookie.Invoke(Object[] args)
at System.Windows.Hosting.DelegateWrapper.InternalInvoke(Object[] args)
at System.Windows.RuntimeHost.ManagedHost.InvokeDelegate(IntPtr pHandle, Int32 nParamCount, ScriptParam[] pParams, ScriptParam& pResult)
回答1:
Assuming that you use Newtonsoft.Json:
You can use JObject to test if there is a property or not:
JObject jObj; //initialized somewhere, perhaps in your foreach
var msgProperty = jObj.Property("msg");
//check if property exists
if (msgProperty != null) {
var mag = msgProperty.Value;
} else {
//there is no "msg" property, compensate somehow.
}
回答2:
You can use the TryGetValue it's kinda a standard method for doing exactly what you need. I say standard because the Try methods can be found all around the .NET framework and have generally always the same method signature.
Using that you can get the value like this.
JObject json = new JObject();
JToken value;
if (json.TryGetValue("myProperty", out value))
{
string finalValue = (string)value;
}
The TryGetValue return a boolean telling whether the value was found or not, if the value is found the value passed as second parameter is setted to the property value. Otherwise is setted to null.
回答3:
Or you can simply use the ContainsKey on a JsonObject. Here is a sample of my own code with similar problem to yours:
foreach (JsonObject feed in data)
{
var fbFeed = new FacebookFeeds();
if (feed.ContainsKey("message"))
fbFeed.Message = (string)feed["message"];
if (feed.ContainsKey("story"))
fbFeed.Message = (string)feed["story"];
if (feed.ContainsKey("picture"))
fbFeed.Message = (string)feed["picture"];
fbFeeds.Add(fbFeed);
}
来源:https://stackoverflow.com/questions/14544503/possible-to-look-for-key-that-does-not-exist-in-json-net