Thursday, 25 February 2016

A salutation drop down with validation in ASP.net MVC

Here is one way to have a drop down with a salutation list in ASP.net MVC. This technique will implement client and server side validation, and is easy to update at a later stage to get the list of data attributes from a dynamic source. As the model data is in a class, it can be associated to many views.

Step 1, Create a model to contain the list of values. 

 In this example the code is as follows:

    public class SalutationsList
    {
        public static IEnumerable<SelectListItem> GetSalutationsList()
        {
            IList<SelectListItem> items = new List<SelectListItem>
            {
                new SelectListItem{Text = "", Value = ""},
                new SelectListItem{Text = "Mr", Value = "Mr"},
                new SelectListItem{Text = "Mrs", Value = "Mrs"},
                new SelectListItem{Text = "Ms", Value = "Ms"},
                new SelectListItem{Text = "Sir", Value = "Sir"},
                new SelectListItem{Text = "Esq", Value = "Esq"},
                new SelectListItem{Text = "Dr", Value = "Dr"}
            };
            return items;
        }
    }


The key point to note is that this class has a static method that returns  IEnumerable<SelectListItem>. The method is static as it will not change for the life of the application, so there is no need for it to be instantiated each time it is used which will save a bit of CPU and memory - important for a busy site.

Step 2, Create the custom validation method.


For this example, you can use the following code:

    public class SalutationsListValidateAttribute : ValidationAttribute
    {
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            string theValue = "";  //the deafult is a empty string.
            if (value != null)
            {
                theValue = value.ToString();
            }

            foreach (SelectListItem salutationValue    in SalutationsList.GetSalutationsList())
            {
                if (salutationValue.Text.ToString() == theValue)
                {
                    return ValidationResult.Success;
                }
            }
            return new ValidationResult("The selected value is not in the list of accepted salutations.");
        }
    }

This will ensure that the model will validate against the list of values in the SalutationsList class. If the implementation of  SalutationsList changes to dynamically read data from a data source, this validation code will still be valid.

Step 3, Add the salutation attribute to the model it is used with.


The code for this example is

        [SalutationsListValidate]
        public string Salutation { get; set; } //class SalutationList


Step 4, Add (Update) code to your views.

 The code in your view will look something like:

        <div class="form-group">
            @Html.LabelFor(model => model.Salutation, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.DropDownListFor(x => Model.Salutation, ToyLibrary.Models.SalutationsList.GetSalutationsList(), htmlAttributes: new { @class = "form-control" })
                @Html.ValidationMessageFor(model => model.Salutation, "", new { @class = "text-danger" })
            </div>
        </div>


Summary.


 By using this approach, the validation will be applied on client and server side. This is handy, if someone tries to over post, then the field will be validated. Also, this will validate any updates you try to do as part of database initialization using entity framework. That said, you will be serving up some unobtrusive java script to validate on the client side which may be a consideration.

Tuesday, 2 February 2016

Displaying a dynamic chart in ASP.NET MVC

In this post I will show you two options for creating a chart in ASP.NET MVC application using data from a model. These examples were run in the community edition of Visual Studio with ASP.NET version 5. For these examples I am using the below model called ChartModel which returns a list of objects called DataPoints. In this case the model is hard coding the DataPoints object, but this would be substituted for a database call to retrieve a list of data to be displayed for a real application.

    public class DataPoints
    {
        public DataPoints(string nameTxt, int dataVal, string commentTxt )
        {
            nameText = nameTxt;
            dataValue = dataVal;
            commentText = commentTxt;
        }
        public string nameText { get; set; }
        public int dataValue { get; set; }
        public string commentText { get; set; }
    }

    public class ChartModel
    {
        public List<DataPoints> getDataPoints()
        {
            List<DataPoints> dataPointsList = new List<DataPoints>();
            dataPointsList.Add(new DataPoints("Cat", 10, "Meow"));
            dataPointsList.Add(new DataPoints("Fish", 8, "Blooop"));
            dataPointsList.Add(new DataPoints("Cow", 5, "Moo"));
            dataPointsList.Add(new DataPoints("Sheep", 8, "Baaaa"));
            dataPointsList.Add(new DataPoints("Frog", 2, "Glumph"));

            return dataPointsList;
        }
    }

Option 1, using the ASP.NET chart control.

ASP.NET has a built in chart control which provides basic charting functionality. This control works by taking a data set and creating an image file. This image is then sent to the clients browser. More details on this control can be found http://www.asp.net/web-pages/overview/data/7-displaying-data-in-a-chart

For this example, use the following is the controller code. This will create a bar chart showing the nameText and dataValue fields of the DataPoints objects:

        public ActionResult GetChartImage()
        {
            var chartData = new ChartModel();
            var dataPointsList = chartData.getDataPoints();
           
            var key = new Chart(300, 300, ChartTheme.Blue)
                .AddTitle("ASP.NET Chart")
                .SetXAxis("Animal")
                .SetYAxis("Count")

                .AddSeries(
                chartType: "Bar",
                name: "Animals",
                axisLabel: "axis",
                xField: "nameText",
                yFields: "dataValue",
                xValue: dataPointsList,
                yValues: dataPointsList);

            return File(key.ToWebImage().GetBytes(), "image/png");
        }

This is the view code:


<h1>Chart example - ASP.NET chart </h1>
<img src="@Url.Action("GetChartImage")" />
 
which looks like:
Option 2, using Google Charts

Google Developers provides a comprehensive and powerful charting library that is free to use. More details can be found https://google-developers.appspot.com/chart/interactive/docs/ Google charts uses some JavaScript libraries to draw the chart in the clients browser.

This library can be combined with a controller that returns Json to create a dynamic chart. Some details on this can be found http://www.c-sharpcorner.com/UploadFile/4d9083/how-to-create-google-charts-with-mvc-4/ which the below example is based on.

First is the controller code to return the data set in Json format:

        public JsonResult GetJsonChartData()
        {
            var chartData = new ChartModel();
            return Json(chartData.getDataPoints(), JsonRequestBehavior.AllowGet);
        }
 

Next, the following code should be added to the view:

<h1>Chart example - Google chart </h1>
<div id="googlechartdiv" style="width: 300px; height: 300px;">  </div>

This sets up a div that the Google chart library will draw the chart in. Next add the JavaScript scripts to the view that will get the Json data from the controller action and render it into the div:


<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">google.load("visualization", "1", { packages: ["corechart"] });</script>
    <script type="text/javascript">
        $(function () {
            $.ajax({
                type: 'POST',
                dataType: 'json',
                contentType: 'application/json',
                url: '@Url.Action("GetJsonChartData")',
                    data: '{}',
                    success: function (chartsdata) {

                        // Callback that creates and populates a data table,
                        // instantiates the pie chart, passes in the data and
                        // draws it.
                        var data = new google.visualization.DataTable();

                        data.addColumn('string', 'nameText');
                        data.addColumn('number', 'dataValue');

                        for (var i = 0; i < chartsdata.length; i++)
                        {
                            data.addRow([chartsdata[i].nameText, chartsdata[i].dataValue]);
                        }

                        // Instantiate and draw our chart, passing in some options
                        var chart = new google.visualization.BarChart(document.getElementById('googlechartdiv'));

                        chart.draw(data,
                          {
                              title: "Google Chart in Asp.net",
                              position: "top",
                              fontsize: "16px",
                              chartArea: { width: '60%' },
                              vAxis: { title: 'Animal' },
                              hAxis: { title: 'Count' },
                              legend: { position: "none" },
                          });
                    },
                    error: function () {
                        alert("Error loading data! Please try again.");
                    }
                });
            })
</script> 

which results in a chart that looks like:
Comments

Both options enable data to be displayed in a chart that is dynamically created at run time. Both options allow for a large variety of chart types to be implemented and allow a number of customization. The Google Developer option will – depending on the amount of data points – send less data from the server hosting your application to the client which could be a consideration in choosing the approach to take. However, Google Developer could change their implementation at any time that would brake you application, whereas the ASP.NET charting option would only change with a re-compile of your project.