webentwicklung-frage-antwort-db.com.de

Mögliche Suche nach einem Schlüssel, der in Json.net nicht vorhanden ist

Ich habe ein paar verschiedene Formate bekommen, aber ich kann nicht herausfinden, wie ich damit umgehen soll, denn wenn ich versuche, nach Schlüssel zu finden, stürzt json.net ab. Ich hatte gehofft, es würde einfach Null zurückgeben.

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

// Format eins

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

mein Code funktioniert.

// format 2 (kam zustande, weil ich auf serverseite keine ausnahme festgestellt habe)

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

Ich kann das natürlich beheben und die Ausnahme fangen. Aber wenn ich es mal wieder vergesse, habe ich es auch nicht auf dem Client abgestürzt. Ich würde es lieben, einfach die "Nachricht" auszudrucken, aber ich verstehe nicht, wie es geht, damit es nicht auf var msg = item.Value["Msg"]; abstürzt.

Der Fehler, den ich bekomme, wenn er versucht, var msg = item.Value["Msg"]; auszuführen

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)
17
chobo2

Angenommen, Sie verwenden Newtonsoft.Json:

Sie können mit JObject testen, ob eine Eigenschaft vorhanden ist oder nicht:

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.
}
34
Alexey Raga

Sie können TryGetValue verwenden, eine Art Standardmethode, um genau das zu tun, was Sie brauchen. Ich sage Standard, weil die Try -Methoden überall im .NET-Framework zu finden sind und im Allgemeinen immer die gleiche Methodensignatur aufweisen.

Damit können Sie den Wert so erhalten.

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

TryGetValue gibt einen booleschen Wert zurück, der angibt, ob der Wert gefunden wurde oder nicht. Wenn der Wert gefunden wird, wird der als zweiter Parameter übergebene Wert auf den Eigenschaftswert gesetzt. Ansonsten wird auf null gesetzt.

4
Fabio Marcolini

Oder Sie können den ContainsKey einfach für ein JsonObject verwenden .. Hier ist ein Beispiel meines eigenen Codes mit einem ähnlichen Problem wie bei Ihnen:

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