Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NewtonSoft Json DeserializeObject empty Guid field

I'm using ASP.NET MVC C# with HTML CSS jQuery KnockoutJs frontend.

I have a modal contact form on my HTML page. The idea is that if I create a new contact the modal form pops up with blank values including a blank hidden id field.

If I edit a contact then the modal form pops up with filled out fields including that hidden id field.

In my controller I intend to do this:

public JsonResult Contact(string values)
{
    var contact = JsonConvert.DeserializeObject<contact>(values);

    if (contact.Id.Equals(Guid.Empty))
    {
         // create a new contact in the database
    } else
    {
        // update an existing one
    }
}

However, I get an error saying that can't convert "" to type Guid

How do you get around this with NewtonSoft Json, i've looked here at the Custom JsonConverter and it seems to be along the right lines, however I'm not sure where to go with this.

like image 338
Callum Linington Avatar asked Feb 14 '23 17:02

Callum Linington


1 Answers

A custom converter would look like this, but I feel like it's a bit overkill for something so trivial.

/// <summary>
/// Converts a <see cref="Guid"/> to and from its <see cref="System.String"/> representation.
/// </summary>
public class GuidConverter : JsonConverter
{
    /// <summary>
    /// Determines whether this instance can convert the specified object type.
    /// </summary>
    /// <param name="objectType">Type of the object.</param>
    /// <returns>Returns <c>true</c> if this instance can convert the specified object type; otherwise <c>false</c>.</returns>
    public override bool CanConvert(Type objectType)
    {
        return objectType.IsAssignableFrom(typeof(Guid));
    }

    /// <summary>
    /// Reads the JSON representation of the object.
    /// </summary>
    /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
    /// <param name="objectType">Type of the object.</param>
    /// <param name="existingValue">The existing value of object being read.</param>
    /// <param name="serializer">The calling serializer.</param>
    /// <returns>The object value.</returns>
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        try
        {
            return serializer.Deserialize<Guid>(reader);
        }
        catch
        {
            return Guid.Empty;
        }
    }

    /// <summary>
    /// Writes the JSON representation of the object.
    /// </summary>
    /// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
    /// <param name="value">The value.</param>
    /// <param name="serializer">The calling serializer.</param>
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        serializer.Serialize(writer, value);
    }
}

Usage:

class Contact
{
    [JsonConverter(typeof(GuidConverter))]
    public Guid Id { get; set; }
}

Alternatively:

var contact = JsonConvert.DeserializeObject<contact>(values, new GuidConverter());

EDIT

I presume that your JSON looks a lot like this:

{
    "id": "",
    "etc": "..."
}

The problem would probably be fixed if you can do this instead:

{
    "id": null,
    "etc": "..."
}
like image 95
Steven Liekens Avatar answered Feb 20 '23 12:02

Steven Liekens