Friday, 29 June 2012

ASP.NET DropDownList Postback: The jQuery AJAX Replacement for MVC

It was handy in ASP.NET WebForms to have the AutoPostback property and use the SelectedIndexChanged event, to allow other parts of your WebForm to be updated depending on user selection!

With MVC and Razor you can achieve the same functionality, but it has to be done using some other way that fits in with a View. Recently I had a requirement to render a list of checkboxes on a user form; the catch was that the list of checkboxes to be rendered was dependant on a drop down list option the user selected on the same form...

With this senario, we have three main components to any solution:

1. We need to fire a method when the drop down list selection changes.
2. This method needs to take the value of the selected item in the drop down list and return output based on that value.
3. The returned output needs to be rendered in the view.

With the requirement I had, I needed to query a database to return the data needed to render the checkboxes. The solution I used utilised jQuery AJAX and JSON.

I had an MVC Web Application with the latest version of jQuery installed, however I also needed the json2 library from (this can also be downloaded via NuGet).

With these libraries referenced, I needed to wire up a a method to fire on the change event of the dropdownlist using jQuery:

    $(document).ready(function () {



My getReceivers method makes an ajax call using JSON data to a controller action in my MVC application:

function getReceivers() {
            url: '/Person/ListRecievers',
            data: "{'organisationId':'" + $('#OrganisationId').val() + "', 'personId':'@Model.Person.Id'}",
            type: 'POST',
            contentType: 'application/json; charset=utf-8',
            dataType: 'json',
            success: function (result) {
                $.each(result, function (person) {
                    var isChecked;
                    if (this.selected) {
                        isChecked = 'checked=\'checked\'';
                    else {
                        isChecked = '';
                            '   <label class=\'checkbox\'>'
                            + '     <input type=\'checkbox\' name=\'Receivers\' ' + isChecked + ' value=\'' + + '\'>' + + ' at ' + this.organisationName + ''
                            + ' </label>'
            error: function () {


URL: the path to my controller action to get the data back for generating the checkbox HTML

Data: this is data I need to pass to my controller action. I have two inputs, organisationId and personId. It is important to remember that these are passed in the ajax call as strings - if the organisationId is a Guid (for example), you will need to convert this to a Guid once it is passed into your controller action

Success: This takes the returned data (in JSON) and iterates through to generate HTML for the checkboxes. The HTML is written to a div I have in my view with an ID of "receiversResponse".

My controller action that is called to return the data I need in JSON is:

        public ActionResult ListRecievers(string organisationId, string personId)
            var selectedOrganisation = db.Organisations.Where(p => p.Id == new Guid(organisationId)).Single();
                var people = db.People.ToList();
                var peopleList = from p in people
                                 select (new {
                                     id = p.Id,
                                     name = p.Name,
                                     organisationName = p.Organisation.Name,
                                     selected = db.People.Include("Receivers").Where(n => n.Id == new Guid(personId) && n.Receivers.Any(r => r.Id == p.Id)).Count() == 1
                return Json(peopleList.ToList(), JsonRequestBehavior.AllowGet);  

I hope the solution to this problem helps someone else to dynamically display HTML based on user selection of a dropdownlist option value. You don't have to just display checkboxes with this either!

Thursday, 7 June 2012

MVC: Security Best Practises for Entity Framework 4.3 Code First and SQL Server

With Entity Framework, using code first development is a real time saver - however there are several best practises to consider when using SQL Server as your data store.

1. The user credentials you specify in the web.config when developing your application must have elevated privileges to drop/create the database depending on the database initialiser you are using for development. The use of web.config transforms for specifying different configurations for different build environments is essential, so that a connection string for a production build has user credentials with the lowest possible privileges.

2. Use DataAnnotations to specify schemas. In most of the examples I have seen, objects are created in the dbo schema. An example of how to specify a schema for your entity is:

[Table("Course", Schema = "Students")]
    public class Course
        public int CourseID { get; set; }
        public string Title { get; set; }
        public int Credits { get; set; }
        public virtual ICollection<Enrollment> Enrollments { get; set; }

Why do this? Well, when the database and the user login are created (see item 3), the database user created for the login can then only be set explicit permissions for the schema(s) it needs to. 

3. When publishing to a production server for the first time, create the database manually and use Code First Migrations in Entity Framework 4.3 to publish an SQL script that can be run separately in the context of your database by a user with the correct privileges. This prevents your application requiring elevated privileges on your database; potentially disastrous if your the production server hosting your application is compromised.

I will add other best practises as I encounter them, however these are some things I have noted so far. Please add your own best practises below or comment on the above!