Archive

Posts Tagged ‘JSON’

Build Your Own Dashboard

October 27, 2012 Leave a comment

I had a great time presenting on Build Your Own Dashboards at the SQL Saturday #174 Charlotte BI Edition.  Thank you to everyone who came to my session and participated in my talk.

Here is a link to the sample dashboard site I presented on:

Dashboards

Be advised that this site and the sample code is only optimized for IE 9.  You need to provide CSS3 vendor specific entries for WebKit and Mozilla if you want this to work perfectly in Chrome, Safari, and Firefox.

Here are the slides and sample code:

Slides and Sample code

Thanks again for the opportunity…

Build Your Own Dashboard (BYOD) in HTML5

September 20, 2012 1 comment

I am excited to be speaking at the SQL Saturday #174 Charlotte BI Edition event on October 27, 2012!

Here is my presentation summary:

Need to have some dashboard reports that support cross-platform devices?  Ever wanted to build your dashboard and see it on the iPad or Android, or Windows 8 Surface?  With this session, we will take a look at what it takes to provide simple dashboards using goodness of HTML5.  We will look at using client-side JavaScript to provide our data using Web API and JSON.

Looking forward to seeing you there!

ASP.NET MVC4 and WebAPI

I had a great time Tuesday night speaking at the Greenville Spartanburg Developers Guild.  Thanks to all who came out to the presentation!

Here are the slides and sample code:

Slides and Sample code

Hope you enjoy…

ASP.NET MVC4 and WebAPI

I will be speaking Tuesday, May 15 at the Greenville Spartanburg Developers Guild in Greenville, SC on ASP.NET MVC4 and Web API.

Here is my presentation summary:

Microsoft likes big stacks! Look at Windows Presentation Foundation (WPF) or, better yet, Windows Communication Foundation (WCF). With either of these “foundations”, you start out a noob and you come out the other side a freak’in Ph.D in Quantum Physics. It doesn’t have to be that hard! There has to be a better way.

Well, Microsoft has been definitely been going the right direction. If you have followed any of the work on the WCF Web API, then you know how awesome this stuff is. This is its new home but you can still self host just like you could before. We are talking about a Web API that is heavily Convention-Over-Configuration based! Gone are the days of looking through a myriad of documentation as to how to setup your web.config file. Those days are over and you will be surprised at how nice the new stack is.

Look forward to seeing you there!

ASP.NET MVC4 and Web API

March 15, 2012 1 comment

I will be speaking this evening, March 15 at the WNC .NET Developers Guild in Asheville, NC on ASP.NET MVC4 and Web API. I will also be doing the same presentation on Thursday, March 22 at the Triad Developers Guild in Greensboro, NC and also on Wednesday, April 11 at the Columbia Enterprise Developers Guild in Columbia, SC.

Here is my presentation summary:

Microsoft likes big stacks! Look at Windows Presentation Foundation (WPF) or, better yet, Windows Communication Foundation (WCF). With either of these “foundations”, you start out a noob and you come out the other side a freak’in Ph.D in Quantum Physics. It doesn’t have to be that hard! There has to be a better way.

Well, Microsoft has been definitely been going the right direction. If you have followed any of the work on the WCF Web API, then you know how awesome this stuff is. This is its new home but you can still self host just like you could before. We are talking about a Web API that is heavily Convention-Over-Configuration based! Gone are the days of looking through a myriad of documentation as to how to setup your web.config file. Those days are over and you will be surprised at how nice the new stack is.

Look forward to seeing you there!

Raleigh Code Camp

November 2, 2011 Leave a comment

I will be presenting the following topic “Building a Windows Phone 7 App using JSON/ASP.NET MVC Data Service Layer” at the Raleigh Code Camp this weekend. We will take a look at leveraging ASP.NET MVC and JSON to become your best friend from the point of data serialization. Want to build a simple WP7 application? Want a simple way to pass data back and forth from the server? JSON seems to be the obvious choice when developing web applications, how does it work when developing WP7 applications? I am looking forward to it!

Categories: English Tags: , , , , ,

Using ICustomTypeProvider in Silverlight 5 with XML

September 16, 2011 1 comment

Back in June I did a post on ICustomTypeProvider with JSON and ASP.NET MVC 3. Today, I want to present to you the ability to use XML as your source data for the ICustomTypeProvider and being able to bind to the data. If you download the code from my previous post and start looking around, you will see a class with the following structure:

    public class JsonHelper<T> where T : ICustomTypeProvider
    {
        private readonly IEnumerable<string> _keys = Enumerable.Empty<string>();
        private readonly Dictionary<string, Func<object, object>> _converters = 
            new Dictionary<string, Func<object, object>>();

        public JsonHelper(IDictionary<string, JsonValue> template)
        {
            CustomTypeHelper<T>.ClearCustomProperties();

            _keys = (from k in template.Keys select k).ToArray();

            foreach (var key in template.Keys)
            {
                int integerTest;
                double doubleTest;
                DateTime datetimeTest;
                var value = template[key].ToString();
                if (DateTime.TryParse(value.Replace(@"\", "").Replace("\"", ""), out datetimeTest))
                {
                    CustomTypeHelper<T>.AddProperty(key, typeof(DateTime));
                    _converters.Add(key, obj => DateTime.Parse(obj.ToString().Replace(@"\", "").Replace("\"", "")));
                }
                else if (int.TryParse(value, out integerTest))
                {
                    CustomTypeHelper<T>.AddProperty(key, typeof(int));
                    _converters.Add(key, obj => int.Parse(obj.ToString()));
                }
                else if (double.TryParse(value, out doubleTest))
                {
                    CustomTypeHelper<T>.AddProperty(key, typeof(double));
                    _converters.Add(key, obj => double.Parse(obj.ToString()));
                }
                else
                {
                    CustomTypeHelper<T>.AddProperty(key, typeof(string));
                    _converters.Add(key, obj =>
                    {
                        // strip quotes
                        var str = obj.ToString().Substring(1);
                        return str.Substring(0, str.Length - 1);
                    });
                }
            }
        }

        public void MapJsonObject(Action<string, object> setValue, JsonValue item)
        {
            foreach (var key in _keys)
            {
                setValue(key, _converters[key](item[key]));
            }
        }
    };

Again, thanks goes out to all the other posts that I read and used in my solution.

This class is actually does all the magic for allowing us to map our JSON data to an object that implements ICustomTypeProvider. It gets a lot of help from a CustomTypeHelper class that you can look at in the source code from the previous post. But what is nice about this class is that we have a simple implementation that allows us to map our JSON object to a typed CustomType object. As you can see, we are basically trying to parse the data into the underlying data types we care about.

It happens that I had a requirement to be able to take XML in as an input and create a CustomType that I could bind to a DataGrid in XAML. Well this turned out to be extremely easy. Here is the new class that provides the same functionality as the JsonHelper class called, XamlHelper:

    public class XmlHelper<T> where T : ICustomTypeProvider
    {
        private readonly IEnumerable<string> _keys = Enumerable.Empty<string>();
        private readonly Dictionary<string, Func<object, object>> _converters =
            new Dictionary<string, Func<object, object>>();


        public XmlHelper(XElement input)
        {
            CustomTypeHelper<T>.ClearCustomProperties();

            var template = new Dictionary<string, object>();

            foreach (var xe in input.Descendants())
            {
                template.Add(xe.Name.LocalName, xe.Value);
            }
            _keys = (from k in template.Keys select k).ToArray();

            foreach (var key in template.Keys)
            {
                int integerTest;
                double doubleTest;
                DateTime datetimeTest;
                var value = template[key].ToString();
                if (DateTime.TryParse(value, out datetimeTest))
                {
                    CustomTypeHelper<T>.AddProperty(key, typeof(DateTime));
                    _converters.Add(key, obj => DateTime.Parse(obj.ToString()));
                }
                else if (int.TryParse(value, out integerTest))
                {
                    CustomTypeHelper<T>.AddProperty(key, typeof(int));
                    _converters.Add(key, obj => int.Parse(obj.ToString()));
                }
                else if (double.TryParse(value, out doubleTest))
                {
                    CustomTypeHelper<T>.AddProperty(key, typeof(double));
                    _converters.Add(key, obj => double.Parse(obj.ToString()));
                }
                else
                {
                    CustomTypeHelper<T>.AddProperty(key, typeof(string));
                    _converters.Add(key, obj => obj.ToString());
                }
            }
        }

        public void MapXmlObject(Action<string, object> setValue, XElement item)
        {
            foreach (var key in _keys)
            {
                setValue(key, _converters[key](item.Element(key).Value));
            }
        }
    };

Here is a snippet of code that uses this new helper:

StringReader sr = new StringReader(item);
XDocument xDoc = XDocument.Load(sr);
if (xDoc.Element("data").Descendants("Table").Count() > 0)
{
    // Pull the first record as a template.
    XElement template = xDoc.Element("data").Descendants("Table").ToList()[0];
    // Use the template to get type information.
    var xmlHelper = new XmlHelper<CustomType>(template);
    // Iterate over the results and add to the underlying collection.
    foreach (var xe in xDoc.Element("data").Descendants("Table").ToList())
    {
        var customType = new CustomType();
        xmlHelper.MapXmlObject(customType.SetPropertyValue, xe);
        ResultsPaneItems.Add(customType);
    }
}

In my XAML, I have a DataGrid that has its ItemsSource property bound to the ResultsPaneItems property on my ViewModel.

From the server, I am using a ADO.NET DataSet and DataAdapter to write the DataSet out as XML. Then on the client side, I just receive the XML and use the ICustomTypeProvider implementation to allow me to bind to this shape. The cool thing about this is that the shape of my query can be anything as long as it is tabular. I would have to do some extra work if I want to support hierarchical data.

With the helper classes in place, you can provide mappers for just about any shape you need and still have the ability to bind to it in Silverlight. Pretty cool, right?

If you want to use this class, download the source code from my previous post on this subject and just copy and paste this class.

Hope this helps…

Using ICustomTypeProvider in Silverlight 5 beta with JSON and ASP.NET MVC 3

June 3, 2011 6 comments

One of the really powerful new features in Silverlight 5 is the new interface ICustomTypeProvider. This allow us to have a dynamic way to bind to objects that we don’t know the shape of until at runtime. There are three blog posts that you need to read before continuing forward. Please read this post by Alexandra Rusina. In it she provides a nice implementation for ICustomTypeProvider. The other post is by Jeremy Likness. In his post he expounds a little more on what Alexandra provided and gives us the ability to parse JSON. The last post, basically gives us an easy way to format our JSON so that we can see it in a human readable format instead of what it looks like once we pull it from the stream.

This post basically will takes us from the point where Jeremy and Alexandra left us and use ASP.NET MVC 3 to act as our service host for getting data across the wire.

Ok, let’s get started. First of all, I created a blank solution called “CustomTypeProvider”.

Next, I added a new Silverlight 5 project. When asked, I changed the host to be a ASP.NET MVC project. I gave the name of the Silverlight project, “CustomerTypeProvider.Silverlight” and the web host, “CustomTypeProvider.Web”.

I like to use Caliburn.Micro whenever I can and I opted to use the latest version of Caliburn.Micro in my Silverlight project. I used NuGet to pull down the package. It is as easy as right-clicking your References and selecting, “Add Library Package Reference”. Once the dialog appeared, I changed it to online and entered, “Caliburn.Micro” in the search and installed it once it appeared.

I basically followed the steps provided in the web page that comes up in Visual Studio once Caliburn.Micro’s package is installed. I also added the following assembly references:

  • System.Json
  • System.ComponentModel.DataAnnotations
  • System.Windows.Controls.Data

Let’s look at the code necessary for the web first:

namespace CustomerTypeProvider.Web.Controllers
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    using System.Collections;
    using System.Data.SqlClient;

    [HandleError]
    public class HomeController : Controller
    {
        public JsonResult GetCustomers()
        {
            var data = LoadCustomers();
            return Json(data, JsonRequestBehavior.AllowGet);
        }
        public JsonResult GetOrders()
        {
            var data = LoadOrders();
            return Json(data, JsonRequestBehavior.AllowGet);
        }
        public JsonResult GetQuery(string query)
        {
            var data = LoadQuery(query);
            return Json(data, JsonRequestBehavior.AllowGet);
        }
        private List<Customer> LoadCustomers()
        {
            List<Customer> result = new List<Customer>();
            result.Add(new Customer() { FirstName = "Matt", LastName = "Duffield" });
            result.Add(new Customer() { FirstName = "Dean", LastName = "Duffield" });
            return result;
        }
        private List<Order> LoadOrders()
        {
            List<Order> result = new List<Order>();
            result.Add(new Order() { ContactName= "Matt Duffield",
              OrderDate= DateTime.Now, OrderNumber = 100 });
            result.Add(new Order() { ContactName = "Dean Duffield",
              OrderDate = DateTime.Now, OrderNumber = 101 });
            return result;
        }
        private ArrayList LoadQuery(string query)
        {
            ArrayList objs = new ArrayList();

            //SqlConnection conn = new SqlConnection("Data Source=(local);Initial Catalog=Northwind;User Id=myUsername;Password=myPassword;");
            SqlConnection conn = new SqlConnection("Data Source=(local);Initial Catalog=Northwind;Integrated Security = SSPI;");
            //SqlCommand cmd = new SqlCommand("SELECT TOP 10 [CustomerID],[CompanyName],[Address],[City],[Region],[PostalCode],[Country]  FROM [Customers]", conn);
            SqlCommand cmd = new SqlCommand(query, conn);
            conn.Open();
            SqlDataReader r = cmd.ExecuteReader();
            while (r.Read())
            {
                objs.Add(new
                {
                    CustomerID = (r["CustomerID"] is DBNull ? "" : r["CustomerID"]),
                    CompanyName = (r["CompanyName"] is DBNull ? "" : r["CompanyName"]),
                    Address = (r["Address"] is DBNull ? "" : r["Address"]),
                    City = (r["City"] is DBNull ? "" : r["City"]),
                    Region = (r["Region"] is DBNull ? "" : r["Region"]),
                    PostalCode = (r["PostalCode"] is DBNull ? "" : r["PostalCode"]),
                    Country = (r["Country"] is DBNull ? "" : r["Country"])
                });
            }
            r.Close();
            conn.Close();

            return objs;
        }

        public class Customer
        {
            public string FirstName { get; set; }
            public string LastName { get; set; }
        }
        public class Order
        {
            public int OrderNumber { get; set; }
            public DateTime OrderDate { get; set; }
            public string ContactName { get; set; }
        };
    };
}

Okay, so there is a little going on but we will start from the top. We basically have three public methods at the top:

  • GetCustomers()
  • GetOrders()
  • GetQuery(string query)

The first two call helper methods that basically create a generic List<> with some sample data and pass it back to the calling method.  The third is a little more dynamic in that it uses ADO.NET to create a SqlConnection, SqlCommand, and finally a SqlDataReader.  It executes the query passed in and then loops through the data reader to shapes a new object that gets added to an ArrayList.  The ArrayList then gets passed back to the calling method. One thing to note about the data reader loop is that we are checking for DBNull and giving it a default value. This is necessary on the client side so that we can infer the type information.

In each of the corresponding methods above, a new Json object is created passing in the data that was returned from the helper methods as well as a second parameter is set to allow the Get verb.

Now let’s move on to the client side.  In the client side, I have to folders that are of interest:

  • Formatting
  • Framework

In the Formatting folder is the logic necessary to format the JSON stream that comes from the web make it human readable.

In the Framework folder is the logic that I took from Alexandra Rusina’s and from Jeremy Likness’ blog posts.  I won’t go into detail in these classes since there are separate posts by each of them dedicated to the classes.  What I will show you is the ShellView and ShellViewModel to see how we get this data and render on screen.

Let’s take a look at the ShellView:

<UserControl x:Class="CustomerTypeProvider.Silverlight.ShellView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" 
    >
    <Grid Background="White" Margin="5">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="Auto" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <sdk:DataGrid AutoGenerateColumns="True"
            ItemsSource="{Binding Path=ResultsPaneItems}"
            IsReadOnly="True"
            />
        <TextBox x:Name="JsonResult" AcceptsReturn="True"
                 Grid.Column="1" Grid.Row="0" 
                 Width="400" VerticalScrollBarVisibility="Auto" 
                 HorizontalScrollBarVisibility="Auto"/>
        <StackPanel Grid.Column="0" Grid.Row="1" Orientation="Horizontal">
            <Button x:Name="LoadCustomers" Content="Load Customer" Margin="5" />
            <Button x:Name="LoadOrders" Content="Load Orders" Margin="5" />
            <Button x:Name="LoadQuery" Content="Load Query" Margin="5" />
        </StackPanel>
    </Grid>
</UserControl>

Because I am using Caliburn.Micro, my XAML is very clean.  We see a DataGrid that has it’s ItemsSource property bound to collection property called, “ResultsPaneItems” object.  We also see a TextBox that is bound to a property called, “JsonResult” as well.  Finally, we see three buttons that call the three corresponding web methods.
Looking at the ShellViewModel we see the following:

namespace CustomerTypeProvider.Silverlight 
{
    using System.ComponentModel.Composition;
    using System.Collections.ObjectModel;
    using Core.Framework;
    using Core.Framework.Formatting;
    using Caliburn.Micro;
    using System;
    using System.Net;
    using System.Json;
    using System.IO;
    using System.Diagnostics;

    [Export(typeof(IShell))]
    public class ShellViewModel : Screen, IShell 
    {
        public ObservableCollection<CustomType> ResultsPaneItems { get; private set; }
        private string _jsonResult;
        public string JsonResult
        {
            get { return _jsonResult; }
            set
            {
                _jsonResult = value;
                NotifyOfPropertyChange(() => JsonResult);
            }
        }

        #region ctor

        public ShellViewModel()
        {
            ResultsPaneItems = new ObservableCollection<CustomType>();

        }

        #endregion

        public void LoadCustomers()
        {
            LoadResultsPane("/home/GetCustomers");
        }

        public void LoadOrders()
        {
            LoadResultsPane("/home/GetOrders");
        }
        public void LoadQuery()
        {
            string query = "SELECT TOP 10 [CustomerID],[CompanyName],[Address],[City],[Region],[PostalCode],[Country]  FROM [Customers]";
            LoadResultsPane("/home/GetQuery?query=" + query);
        }

        private void LoadResultsPane(string uri)
        {
            ResultsPaneItems = new ObservableCollection<CustomType>();
            NotifyOfPropertyChange("ResultsPaneItems");

            Uri serviceUri = new Uri(uri, UriKind.Relative);
            WebClient downloader = new WebClient();
            downloader.OpenReadCompleted += (s, e) =>
            {
                // Load the JsonArray from the service call.
                StreamReader sr = new StreamReader(e.Result);
                var content = sr.ReadToEnd();
                JsonResult = new JsonFormatter(content).Format();
                var jsonArray = JsonArray.Load(e.Result) as JsonArray;
                Debug.WriteLine(content);
                if (jsonArray == null) return;

                // Pull the first record as a template.
                var template = jsonArray[0] as JsonObject;
                if (template == null) return;

                // Use the template to get type information.
                var jsonHelper = new JsonHelper<CustomType>(template);

                // Iterate over the results and add to the underlying collection.
                foreach (var item in jsonArray)
                {
                    var customType = new CustomType();
                    jsonHelper.MapJsonObject(customType.SetPropertyValue, item);
                    ResultsPaneItems.Add(customType);
                }
            };
            // Retrieve the data.
            downloader.OpenReadAsync(serviceUri);
        }

    };
}

Okay, let’s start from the top and work our way down. First we see that declaration of the ResultsPaneItems collection. Next we see the property for the JsonResult string. In the constructor, we initialize the collection.

Next, we have the three methods that respond to the corresponding buttons. All three of them call a helper method called, “LoadResultsPane(string uri)”. It is this method that does all of the heavy lifting. The only difference in the methods is that the last one also passes in the query as part of the query string to the GetQuery method on the controller.

In the LoadResultsPane(…) method, we are initializing the ResultsPaneItems to a new collection. Note that this collection is of type CustomType. This is important since we want each button click to load a fresh set of data. Next we use the Uri and WebClient objects to perform the OpenReadAsync(…) call. This is an asynchronous call and that is we we have an anonymous delegate in the form of a lambda expression stating what to do when the call comes back. Inside the expression, we create a StreamReader object off of the Result. We read the stream so that we can use our formatter class and display the raw JSON that was just returned to us. Next we create a JsonArrary and load the same Result object trying to cast it to a JsonArrary object. If that is successfuly, then we use the first row as a representation of the data so that we can type it accordingly. If you recall, this is why we had the test for DBNull in the data reader loop on the controller. Finally, we loop over the JsonArrary and create a CustomType object. We use the JsonHelper provided by the previous blog posts and then add it to our collection.

That is all there is to it. You now have a very dynamic model in which you can data bind to any object that is sent from the server. You no longer need to know about it. The server-side code could be further abstracted so that you had a completely generic solution instead of the hard-coding I have shown in the loop of the data reader.

Here is a sample screen shot of the application:

You can download the sample code here. Don’t forget that this solutions works only for Silverlight 5 beta.
Hope you enjoy…

Building a Windows Phone 7 App using JSON/ASP.NET MVC Data Service Layer

May 25, 2011 8 comments

I had a great time speaking at Charlotte’s Enterprise Developers Guild last night. Here is a link to my slides and sample code.

Thanks again to everyone who came out!