Rename JProperty in json.net

后端 未结 1 1119
不思量自难忘°
不思量自难忘° 2020-12-06 13:09

I\'ve the following property

{
  \"bad\": 
  {
    \"Login\": \"someLogin\",
    \"Street\": \"someStreet\",
    \"House\": \"1\",
    \"Flat\": \"0\",
             


        
1条回答
  •  情深已故
    2020-12-06 14:09

    Somewhat counterintuitively, that extension method assumes that the token you are passing to it is the value of a JProperty, not the JProperty itself. Presumably, this is to make it easy to use with the square bracket syntax:

    JObject jo = JObject.Parse(json);
    jo["bad"].Rename("good");
    

    If you have a reference to the property, you can still use that extension method if you call it on the property's Value like this:

    JObject jo = JObject.Parse(json);
    JProperty prop = jo.Property("bad");
    prop.Value.Rename("good");
    

    However, that makes the code seem confusing. It would be better to improve the the extension method so that it will work in both situations:

    public static void Rename(this JToken token, string newName)
    {
        if (token == null)
            throw new ArgumentNullException("token", "Cannot rename a null token");
    
        JProperty property;
    
        if (token.Type == JTokenType.Property)
        {
            if (token.Parent == null)
                throw new InvalidOperationException("Cannot rename a property with no parent");
    
            property = (JProperty)token;
        }
        else
        {
            if (token.Parent == null || token.Parent.Type != JTokenType.Property)
                throw new InvalidOperationException("This token's parent is not a JProperty; cannot rename");
    
            property = (JProperty)token.Parent;
        }
    
        // Note: to avoid triggering a clone of the existing property's value,
        // we need to save a reference to it and then null out property.Value
        // before adding the value to the new JProperty.  
        // Thanks to @dbc for the suggestion.
    
        var existingValue = property.Value;
        property.Value = null;
        var newProperty = new JProperty(newName, existingValue);
        property.Replace(newProperty);
    }
    

    Then you can do:

    JObject jo = JObject.Parse(json);
    jo.Property("bad").Rename("good");  // works with property reference
    jo["good"].Rename("better");        // also works with square bracket syntax
    

    Fiddle: https://dotnetfiddle.net/RSIdfx

    0 讨论(0)
提交回复
热议问题