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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14544503/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 12:13:06  来源:igfitidea点击:

Possible to look for Key that does not exist in Json.net

c#jsonjson.net

提问by chobo2

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.

我得到了几种不同的格式,但我无法弄清楚如何处理它们,因为当我尝试通过键查找时 json.net 崩溃了。我希望它只会返回 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)

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

{
  "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"];

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

The error I get when it tries to do 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)

采纳答案by Alexey Raga

Assuming that you use Newtonsoft.Json:

假设您使用 Newtonsoft.Json:

You can use JObject to test if there is a property or not:

您可以使用 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.
}

回答by Fabio Marcolini

You can use the TryGetValueit's kinda a standard method for doing exactly what you need. I say standard because the Trymethods can be found all around the .NET framework and have generally always the same method signature.

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

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.

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

回答by Ben

Or you can simply use the ContainsKey on a JsonObject. Here is a sample of my own code with similar problem to yours:

或者您可以简单地在 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);
            }