3

I have two property in my class as below. One property is in capital and another one is in small.

public class Points
{
      public string X { get; set; }
      public string x { get; set; }  
}

It compiles fine. In code, I deserialize the class value coming from the client side like this:

JavaScriptSerializer serializer = new JavaScriptSerializer();
object value = serializer.Deserialize("{X:\"Car\", x:\"car\"}", typeof(Points));

In that, I am getting the below exception:

{"Ambiguous match found."}

at System.RuntimeType.GetPropertyImpl(String name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers)

at System.Type.GetProperty(String name, BindingFlags bindingAttr)

at System.Web.Script.Serialization.ObjectConverter.AssignToPropertyOrField(Object propertyValue, Object o, String memberName, JavaScriptSerializer serializer, Boolean throwOnError)

at System.Web.Script.Serialization.ObjectConverter.ConvertDictionaryToObject(IDictionary2 dictionary, Type type, JavaScriptSerializer serializer, Boolean throwOnError, Object& convertedObject)

at System.Web.Script.Serialization.ObjectConverter.ConvertObjectToTypeInternal(Object o, Type type, JavaScriptSerializer serializer, Boolean throwOnError, Object& convertedObject)

at System.Web.Script.Serialization.ObjectConverter.ConvertObjectToTypeMain(Object o, Type type, JavaScriptSerializer serializer, Boolean throwOnError, Object& convertedObject)

at System.Web.Script.Serialization.ObjectConverter.ConvertObjectToType(Object o, Type type, JavaScriptSerializer serializer)

at System.Web.Script.Serialization.JavaScriptSerializer.Deserialize(JavaScriptSerializer serializer, String input, Type type, Int32 depthLimit)

at System.Web.Script.Serialization.JavaScriptSerializer.Deserialize(String input, Type targetType)

Is that the JSON is deserialized as case insensitive? How can I deserialize case-sensitive?

CodeCaster
  • 147,647
  • 23
  • 218
  • 272
user3326265
  • 257
  • 1
  • 4
  • 14
  • 4
    No, property names are definitely case sensitive in C#. It looks like the serializer you use isn't though. Create a small example that actually reproduces the problem and name any libraries you use. – CodeCaster May 06 '15 at 09:15
  • 2
    What is `serializer`? – Charles Mager May 06 '15 at 09:15
  • 1
    JavaScriptSerializer serializer = new JavaScriptSerializer(); – user3326265 May 06 '15 at 09:16
  • Please add the type of Serializer used. – Mattias May 06 '15 at 09:16
  • 4
    Your `Points` class doesn't have a static `Type PropertyType` and the code you show won't compile. Again, please create a small example that reproduces the problem. – CodeCaster May 06 '15 at 09:18
  • 2
    You are right. `ObjectConverter.AssignToPropertyOrField` uses `type.GetProperty(memberName, BindingFlags.IgnoreCase`. Don't ask me why. You cant do anything to solve this. Use Json.NET . – xanatos May 06 '15 at 09:22

1 Answers1

4

You are right. ObjectConverter.AssignToPropertyOrField (used internally by JavaScriptSerializer) uses

type.GetProperty(memberName, BindingFlags.IgnoreCase

(see the BindingFlags.IgnoreCase?) that throws the exception because it is ignoring the case :-)

Don't ask me why. You can't do anything to solve this.

Use Json.NET or another Json serializer/deserializer.

Technically you could:

public class DataObjectJavaScriptConverter : JavaScriptConverter
{
    private static readonly Type[] _supportedTypes = new[]
    {
        typeof( Points )
    };

    public override IEnumerable<Type> SupportedTypes
    {
        get { return _supportedTypes; }
    }

    public override object Deserialize(IDictionary<string, object> dictionary,
                                        Type type,
                                        JavaScriptSerializer serializer)
    {
        if (type == typeof(Points))
        {
            var obj = new Points();

            if (dictionary.ContainsKey("X"))
                obj.X = serializer.ConvertToType<string>(dictionary["X"]);
            if (dictionary.ContainsKey("x"))
                obj.x = serializer.ConvertToType<string>(dictionary["x"]);

            return obj;
        }

        return null;
    }

    public override IDictionary<string, object> Serialize(
            object obj,
            JavaScriptSerializer serializer)
    {
        var dataObj = obj as Points;
        if (dataObj != null)
        {
            return new Dictionary<string, object>
            {
                {"X", dataObj.X },
                {"x", dataObj.x }
            };
        }

        return new Dictionary<string, object>();
    }
}

and then

JavaScriptSerializer serializer = new JavaScriptSerializer();
serializer.RegisterConverters(new[] { new DataObjectJavaScriptConverter() });
object value = serializer.Deserialize("{X:\"Car\", x:\"car\"}", typeof(Points));

(you define a custom serializer/deserializer for JavaScriptSerializer... the code is quite plain)... Taken from https://stackoverflow.com/a/2004216/613130 (and modified a little)

Community
  • 1
  • 1
xanatos
  • 109,618
  • 12
  • 197
  • 280