1

I'm working on a custom add in for excel, I want it to get a list of projects from a remote web service. The JSON is coming back from the web servive to excel, but I'm having trouble turning the JSON into objects in C#.

Here is the AddIn code:

using Microsoft.Office.Tools.Ribbon;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Diagnostics;
using System.Web;

namespace TestAddIn
{
    class Project
    {
        static string currentProject;
        static List<Project> validProjects;

        public int id { get; set; }
        public string name { get; set; }
        public int svar_reserved_space { get; set; }

        // Set the current project we're working on
        internal static void setCurrentProject(string path)
        {
            Match match = Regex.Match(path, @"^[A-Za-z]:\\(\w+)");

            Project.currentProject = match.Groups[1].Value;

            foreach (Project validProject in validProjects)
            {
                RibbonDropDownItem dropDown = Globals.Ribbons.Ribbon1.Factory.CreateRibbonDropDownItem();

                dropDown.Label = validProject.name;

                if (validProject.name.Equals(Project.currentProject))
                {
                    Globals.Ribbons.Ribbon1.projectComboBox.Items.Add(dropDown);
                }
            }
        }

        // Connect to a web service and get a list of valid projects
        internal static void getValidProjects()
        {
            string url = "http://192.168.118.128/projects/json";

            WebRequest webRequest;
            webRequest = WebRequest.Create(url);

            Stream objStream;
            objStream = webRequest.GetResponse().GetResponseStream();

            StreamReader objReader = new StreamReader(objStream);

            string sLine = objReader.ReadLine();

            Debug.WriteLine("begin: " + sLine);

            validProjects = JsonConvert.DeserializeObject<List<Project>>(sLine);

            Debug.WriteLine("end");
        }
    }
}

When using this json:

[{"Project":{"id":1,"name":"test1","svar_reserved_space":2}},{"Project":{"id":2,"name":"test2","svar_reserved_space":0}}]

I get two Project objects in validProjects but the id and svar_reserver_space are 0, and the name is null. Thoguhts?

Joel
  • 43
  • 1
  • 7

2 Answers2

1

This is the easiest with some addins/nuget magic:

And use this code:

WebClient wc = new WebClient();
string json = wc.DownloadString("http://192.168.118.128/projects/json");
var a = JsonConvert.DeserializeObject<YourGeneratedMainClass>(json);

Where YourGeneratedMainClass is a class generated by pasting the json as classes.

If you use the method above, you will probably see that it has a parent object

public class Project
{
    public int id { get; set; }
    public string name { get; set; }
    public int svar_reserved_space { get; set; }
}

public class Parent
{
    public Project Project { get; set; }
}

More about it in these two S.O. questions:

Json.net deseralize to a list of objects in c# .net 2.0

Deserialized Object Has All Values Set to Null

Community
  • 1
  • 1
JP Hellemons
  • 5,977
  • 11
  • 63
  • 128
  • Installed the web essentials, but the paste as objects never appeared, using http://json2csharp.com/ did the trick though. – Joel Nov 02 '12 at 16:20
  • @Joel: its at the context menu under the paste special option: http://madskristensen.net/image.axd?picture=image_28.png – JP Hellemons Nov 05 '12 at 07:56
1

I would suspect you need the JSON to look like:

[{"id":1,"name":"test1","svar_reserved_space":2},{"id":2,"name":"test2","svar_reserved_space":0}]

In order to use the default Json deserialization.

James Gaunt
  • 14,631
  • 2
  • 39
  • 57
  • Totally agree! This is not needed: `"Project":` as wrapping the object. And since the JSON source seems in the same LAN (192.168.x.x) it seems that he can change the JSON output :) you are right – JP Hellemons Nov 02 '12 at 15:50