How do I check if a property exists on a dynamic anonymous type in c#?

141,618

Solution 1

  public static bool DoesPropertyExist(dynamic settings, string name)
  {
    if (settings is ExpandoObject)
      return ((IDictionary<string, object>)settings).ContainsKey(name);

    return settings.GetType().GetProperty(name) != null;
  }

  var settings = new {Filename = @"c:\temp\q.txt"};
  Console.WriteLine(DoesPropertyExist(settings, "Filename"));
  Console.WriteLine(DoesPropertyExist(settings, "Size"));

Output:

 True
 False

Solution 2

public static bool HasProperty(dynamic obj, string name)
{
    Type objType = obj.GetType();

    if (objType == typeof(ExpandoObject))
    {
        return ((IDictionary<string, object>)obj).ContainsKey(name);
    }

    return objType.GetProperty(name) != null;
}

Solution 3

This works for anonymous types, ExpandoObject, Nancy.DynamicDictionary or anything else that can be cast to IDictionary<string, object>.

    public static bool PropertyExists(dynamic obj, string name) {
        if (obj == null) return false;
        if (obj is IDictionary<string, object> dict) {
            return dict.ContainsKey(name);
        }
        return obj.GetType().GetProperty(name) != null;
    }

Solution 4

if you can control creating/passing the settings object, i'd recommend using an ExpandoObject instead.

dynamic settings = new ExpandoObject();
settings.Filename = "asdf.txt";
settings.Size = 10;
...

function void Settings(dynamic settings)
{
    if ( ((IDictionary<string, object>)settings).ContainsKey("Filename") )
        .... do something ....
}

Solution 5

Merging and fixing answers from Serj-TM and user3359453 so that it works with both ExpandoObject and DynamicJsonObject. This works for me.

public static bool HasPropertyExist(dynamic settings, string name)
{
    if (settings is System.Dynamic.ExpandoObject)
        return ((IDictionary<string, object>)settings).ContainsKey(name);

    if (settings is System.Web.Helpers.DynamicJsonObject)
    try
    {
        return settings[name] != null;
    }
    catch (KeyNotFoundException)
    {
        return false;
    }


    return settings.GetType().GetProperty(name) != null;
}
Share:
141,618

Related videos on Youtube

David MZ
Author by

David MZ

Updated on May 09, 2022

Comments

  • David MZ
    David MZ about 2 years

    I have an anonymous type object that I receive as a dynamic from a method I would like to check in a property exists on that object.

    ....
    var settings = new {
                       Filename="temp.txt",
                       Size=10
    }
    ...
    
    function void Settings(dynamic settings) {
    var exists = IsSettingExist(settings,"Filename")
    }
    

    How would I implement IsSettingExist ?

  • David MZ
    David MZ about 12 years
    I can't change it, can I cast to ExpendoObject?
  • Whatever Man
    Whatever Man over 8 years
    Allowing exceptions to occur and then catching them is not a preferred solution because there is a lot of overhead associated with throwing and catching. It's a last resort only. Exceptions are for designed for situations that should not happen in the course of execution like a network being unavailable. There are much better solutions here.
  • evilom
    evilom over 7 years
    This does not work on dynamic objects. It always returns null.
  • Matas Vaitkevicius
    Matas Vaitkevicius about 7 years
    Fails with RuntimeBinderException and dynamicObj[property].Value when value is actually there ... var value = dynamicObj[property] is enough ... and when it does not exist KeyNotFoundException on Dictionary is thrown... see below...
  • Matas Vaitkevicius
    Matas Vaitkevicius about 7 years
    objType.GetProperty(name) != null; returns null on properties that do exist
  • Alex McMillan
    Alex McMillan about 7 years
    objType.GetProperty(name) != null will always return a bool, which (by definition) cannot ever be null.
  • Ian Kemp
    Ian Kemp over 6 years
    @AlexMcMillan Not sure what dimension you live in where Type.GetProperty(string) for a nonexistent property returns anything other than null.
  • Ian Kemp
    Ian Kemp over 6 years
    @evilom @Shikasta_Kashti Are you trying to use this method with an MVC ViewBag? If so, see stackoverflow.com/a/24192518/70345
  • Serg
    Serg over 6 years
    @IanKemp, AlexMcMillan said objType.GetProperty(name) != null in reply to MatasVaitkevicius comment actually.
  • Marco Guignard
    Marco Guignard almost 6 years
    GetProperties() doesn't list dynamic Member on a DynamicObject. There is a dedicated function GetDynamicMemberNames() for that.
  • Gaspa79
    Gaspa79 almost 6 years
    Using exceptions for things like these is not recommended. Should've gone for something like casting to JObject and using .Property() != null
  • rr789
    rr789 almost 5 years
    Great solution. I needed to add one more IF statement when converting JSON string into JObject...."if (obj is Newtonsoft.Json.Linq.JObject) return ((Newtonsoft.Json.Linq.JObject)obj).ContainsKey(name);"
  • Brijesh Kumar Tripathi
    Brijesh Kumar Tripathi almost 5 years
    Also worked for me. Wonderful answer Seth Reno. I have also added "if (obj is Newtonsoft.Json.Linq.JObject) return ((Newtonsoft.Json.Linq.JObject)obj).ContainsKey(name);" in above function as suggested by rr789. So please also edit your answer to include it.
  • pholpar
    pholpar almost 5 years
    Using the lambda expression Where first, and then Any is redundant, as you can formulate your filtering expression in Anyas well.
  • Artem A
    Artem A over 4 years
    It's not acceptable solution to use exceptions in business logic. 1 grade, 2nd term.
  • solublefish
    solublefish over 4 years
    @Gaspa79. It's a not-uncommon coding convention. Some folks like an "Is" prefix on all boolean properties. Consistency like that can prevent you from having to guess the first few characters of an identifier (after which, Intellisense works), but at the expense of making a little awkward English in cases like this.
  • Evan Nagle
    Evan Nagle about 4 years
    I find the invalid verb tense of the Is prefix to be more confusing than it would be otherwise to use HasProperty. I would also say that using a grammatically-incorrect prefix like this is actually non-idiomatic in C♯.
  • ryanwebjackson
    ryanwebjackson almost 4 years
    ExpandoObject is not the same thing as anonymous type. Am I wrong about that?
  • ryanwebjackson
    ryanwebjackson almost 4 years
    Thank you @BrijeshKumarTripathi! This was exactly my scenario.
  • Norcino
    Norcino over 3 years
    A bit of description and links could have been helpful