2

I have this model

public class DTO
{
    public int Id {get;set;}
    public string Name { get; set; }
    public string LastName { get; set; }

    public Dictionary<string, string> Items { get; set; }
}

Values in the Dictionary are coming from my database so they differ from one object to another. Anyway I need to return a Json in specific format in order to be understood by 3rd party grid. Example code

    public ActionResult Index()
    {
        DTO dto = new DTO()
        {
            Id = 1 ,
            Name = "Employee1",
            LastName = "last name value",
            Items = new Dictionary<string, string>()
        };
        // properties .....
        dto.Items.Add("Variable 1" , "Value 1 Goes here");
        dto.Items.Add("Variable 2", "Value 2 Goes here");
        dto.Items.Add("Variable 3", "Value 3 Goes here");              

        return Json(dto, JsonRequestBehavior.AllowGet);            
    }

the desired Json should be like this

{"Id":1, "Name":"Employee1","LastName":"Last Name Value","Variable 1":"Value 1 Goes here","Variable 2":"Value 2 Goes here","Variable 3":"Value 3 Goes here"}

Notice that Dictionary representation MUST not be an array i.e Converting rows to cols. I've tried a lot using JsonWriter and converters but I could not achieve this result.

tereško
  • 58,060
  • 25
  • 98
  • 150
Gerard
  • 65
  • 1
  • 6

1 Answers1

1

You need to create a converter for DTO class, not for its Items property, because you are modifying representation of the whole object.

class DtoConverter : JsonConverter
{
    public override void WriteJson (JsonWriter writer, object value, JsonSerializer serializer)
    {
        var dto = (Dto)value;
        var jobj = JObject.FromObject(dto);
        foreach (var item in dto.Items)
            jobj[item.Key] = item.Value;
        jobj.WriteTo(writer);
    }

    public override object ReadJson (JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override bool CanConvert (Type objectType)
    {
        return typeof(Dto).IsAssignableFrom(objectType);
    }
}

Usage (note JsonIgnoreAttribute):

class Program
{
    private static void Main ()
    {
        var dto = new Dto {
            Id = 1, Name = "Employee1", LastName = "LastName1",
            Items = new Dictionary<string, string> {
                { "Variable 1", "Value 1 Goes here" },
                { "Variable 2", "Value 2 Goes here" },
                { "Variable 3", "Value 3 Goes here" },
            }
        };
        Console.WriteLine(JsonConvert.SerializeObject(dto, new DtoConverter()));
        Console.ReadKey();
    }
}

class Dto
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string LastName { get; set; }

    [JsonIgnore]
    public Dictionary<string, string> Items { get; set; }
}
Athari
  • 33,702
  • 16
  • 105
  • 146
  • Thank you answer , Actually the returned string in not considered as json response ... it's string value looks like "{\"Name\":\"Employee1\",\"LastName\":\"LastName1\",\"Variable 1\":\"Value 1 Goes here\",\"Variable 2\":\"Value 2 Goes here\"} how to returned it as Json from a controller – Gerard Jun 14 '13 at 22:51
  • @Gerard As you've tagged the question with `json.net`, I expected you to have already solved this. You need to configure ASP.NET MVC to use JSON.NET with the supplied parameters (with this converter, to be specific). See http://stackoverflow.com/questions/7109967/using-json-net-as-default-json-serializer-in-asp-net-mvc-3-is-it-possible. If you don't worry about correct Content-Type, then I guess you can return the result as you would return a string (I'm not familiar with ASP.NET, so don't expect detailed instructions). – Athari Jun 15 '13 at 03:03