可以查找Json.net中不存在的Key

时间:2013-01-27 04:42:39

标签: c# json json.net

我有几种不同的格式,但我无法弄清楚如何处理它们,因为当我尝试通过键json.net崩溃找到。我希望它只会返回null。

foreach (var item in jsonObj)
{
    var msg = item.Value["Msg"];
    if (msg != null)
    {
       txtErrors.Text += msg + Environment.NewLine;
    }
}

//格式化一个

{[UserNotFound, {
  "SeverityType": 3,
  "ValidationType": 2,
  "Msg": "Email Not Found"
}]}

我的代码有效。

//格式2(因为我没有在服务器端捕获异常而来)

{
  "Message": "An error has occurred.",
  "ExceptionMessage": "Object reference not set to an instance of an object.",
  "ExceptionType": "System.NullReferenceException",
  "StackTrace": "  "
}

我当然可以修复此问题并捕获异常。但是,如果我再次忘记,我也不会让它在客户端崩溃。所以我很乐意打印出“消息”,但我不知道怎么做,所以它不会在var msg = item.Value["Msg"];上崩溃

尝试执行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)

3 个答案:

答案 0 :(得分:35)

假设您使用Newtonsoft.Json:

您可以使用JObject测试是否有属性:

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

答案 1 :(得分:5)

您可以使用 TryGetValue 它是一种标准方法,可以完全满足您的需求。我说标准,因为 Try 方法可以在.NET框架周围找到,并且通常总是具有相同的方法签名。

使用它你可以得到这样的值。

JObject json = new JObject();
JToken value;
if (json.TryGetValue("myProperty", out value))
{
    string finalValue = (string)value;
}

TryGetValue返回一个布尔值,告知是否找到了值,如果找到该值,则将作为第二个参数传递的值设置为属性值。否则设置为null。

答案 2 :(得分:0)

或者你可以简单地在JsonObject上使用ContainsKey。 以下是我自己的代码示例,其中存在类似问题:

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);
            }