33

This seems like it should be so easy, but I am getting an exception when I try to deserialize some straightforward JSON into a managed type. The exception is:

MissingMethodException
No parameterless constructor defined for type of 'System.String'

While it is true that there are no parameterless constructors for System.String, I'm not clear as to why this matters.

The code that performs the deserialization is:

using System.Web.Script.Serialization;
private static JavaScriptSerializer serializer = new JavaScriptSerializer();
public static MyType Deserialize(string json)
{
    return serializer.Deserialize<MyType>(json);
}

My type is roughly:

public class MyType
{
    public string id { get; set; }
    public string type { get; set; }
    public List<Double> location { get; set; }
    public Address address { get; set; }
    public Dictionary<string, string> localizedStrings { get; set; }
}

The other class is for an address:

public class Address
{
    public string addressLine { get; set; }
    public string suite { get; set; }
    public string locality { get; set; }
    public string subdivisionCode { get; set; }
    public string postalCode { get; set; }
    public string countryRegionCode { get; set; }
    public string countryRegion { get; set; }
}

Here's the JSON:

{
    "id": "uniqueString",
    "type": "Foo",
    "location": [
        47.6,
        -122.3321
    ]
    "address": {
        "addressLine": "1000 Fourth Ave",
        "suite": "en-us",
        "locality": "Seattle",
        "subdivisionCode": "WA",
        "postalCode": "98104",
        "countryRegionCode": "US",
        "countryRegion": "United States"
    },
    "localizedStrings": {
        "en-us": "Library",
        "en-ES": "La Biblioteca"
    }
}

I get the same exception even if my JSON is just:

{
    "id": "uniquestring"
}

Can anybody tell me why a parameterless constructor is needed for System.String?

7
  • The MissingMethodException is associated with the string type (not having a parameterless constructor), not with the JavaScriptSerializer. Commented Feb 21, 2012 at 23:30
  • Possible duplicate: stackoverflow.com/questions/2959605 Commented Feb 21, 2012 at 23:32
  • 4
    DataContractJsonSerializer is generally a better option than JavaScriptSerializer anyways. Commented Feb 21, 2012 at 23:36
  • Thanks Robert, I see that System.String does not have a parameterless constructor; I am just not clear as to why this matters. Commented Feb 21, 2012 at 23:37
  • Thanks Steve. I do not get to choose the deserilaization class for this project. Commented Feb 21, 2012 at 23:37

3 Answers 3

28

Parameterless constructors need for any kind of deserialization. Imagine that you are implementing a deserializer. You need to:

  1. Get a type of object from the input stream (in this case it's string)
  2. Instantiate the object. You have no way to do that if there is no default constructor.
  3. Read the properties/value from stream
  4. Assign the values from the stream to the object created on step 2.
Sign up to request clarification or add additional context in comments.

5 Comments

Oh but there is a way :)
@LucasTrzesniewski could you post this as an answer?
@jrh my comment above refers to the "You have no way to do that if there is no default constructor" part of this answer, but it doesn't solve OP's problem in any way.
@LucasTrzesniewski Yeah, I see what you mean, it wouldn't work on strings now that I look at it a bit more closely. It is good information to have though. For strings it isn't useful, but for the more generic case of trying to deserialize an arbitrary object, it is definitely useful.
In case Lucas's link breaks (MSDN likes to shift URLs around)... Use FormatterServices.GetUninitializedObject to get around no default constructor problem. A quote from the page: "Because the new instance of the object is initialized to zero and no constructors are run, the object might not represent a state that is regarded as valid by that object. The current method should only be used for deserialization when the user intends to immediately populate all fields. It does not create an uninitialized string, since creating an empty instance of an immutable type serves no purpose."
7

I had the same issue and this was what fixed the issue.

Cheers!

//Deserializing Json object from string
DataContractJsonSerializer jsonObjectPersonInfo = 
    new DataContractJsonSerializer(typeof(PersonModel));
MemoryStream stream = 
    new MemoryStream(Encoding.UTF8.GetBytes(userInfo));
PersonModel personInfoModel = 
    (PersonModel)jsonObjectPersonInfo.ReadObject(stream);

1 Comment

The good thing about using this is that is specifies if something is wrong with your modeling of the json
3

Resurrecting this in case I need it myself; in my case the error was in the JSON.

I was deserializing to a List<string> but the JSON was erroneously passing a list of ey value pairs e.g.

{
    "Roles": [ 
        { "ID": "Administrator", "Name": "Administrator" }, 
        { "ID": "Client", "Name": "Client" }
    ]
}

Into:

public List<string> Roles { get; set; }

This gives the OP's error when it tries to deserialize the objects into strings.

It'd be handy if if gave the property name it failed on!

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.