API Controllers (More Stuff!)

My last post demonstrated a few details that I learned about API controllers.  There was one other detail I forgot to mention.  Serialization.  I ran into an issue involving an API controller that worked OK, and then it quit sending JSON data completely.  I traced it down to the fact that I moved an object to another project (containing most of my business layer code) and I also added some methods to the object.  I discovered that I needed to add the [Serializable] attribute to the objects that I used to pass JSON data.  Like this:

[Serializable]
public class PersonnelType
{
    public string First;
    public string Last;
}


[Serializable]
public class TestType
{
    public int Number;
}

Also, the first sample I used in my previous article used a GET API controller and I named it “PostOne”.  That was a typo on my part, but it does demonstrate that the name of the method doesn’t really matter.

Working With Entity Framework

OK, this week I’m going to try to build something a bit more complex.  I’m going to add an Entity Framework database to the mix and show how you can shuttle data between an AJAX call and an MVC API controller.

First, we need a blank MVC4 project.  Next, add a controller using the technique I demonstrated in the previous article.  Name it HomeController.cs, then add a view to it.  Just use the default name.  Now you can run your program and you should get a basic web page.  Now create a scripts folder and add a personnel.js text file to it.  Put this code in your javascript file:

$(document).ready(function() {
 $.ajax({
  type: “GET“,
  url: “api/Personnel/ReadData“,
  contentType: “json“,
  success: function(personnelData) {
   data = jQuery.parseJSON(personnelData);
   $(‘#resultText‘).val(data[0].first + ‘ ‘ + data[0].last);
  },
  error: function(error) {
   alert(error.responseText);
  }
 });

});

Also, download and add JQuery 2 into your scripts directory.  Then modify your view.cshtml file to this:

<!doctype html>
<html>
    <head>
        <title></title>
        <script src=”~/scripts/jquery-2.1.0.js“></script>
        <script src=”~/scripts/Personnel.js“></script>
    </head>
    <body>
        <div>Test Page</div><br />
        <div><input type=”textid=”resultTextvalue=”” /></div>
    </body>
</html>

Now add another controller.  This time create an API controller and name it PersonnelController.cs.  Leave it blank for now. 

The Database Project

Create a new project in your solution.  Just create a class project and name it “Database” for now.  Right click on your new project and select “add -> New Item”, then select “Data” on the left treeview control and an “ADO.NET Entity Data Model” to your project.  Go through the standard steps of creating a connection and adding a table.  I’m using the person table that I created in an earlier blog box.  I’m also connecting to a SQL database, but you can use whatever database you’re comfortable with.  Once you have added the table and saved your edmx stuff, then you’ll need to copy your app.config settings to the web.config file of your other project.  You’ll have to add all of the config stuff from the app.config file to your web.config file.

Let’s add a PersonData class to the database project and put this code in it:

namespace Database
{
    public class PersonData
    {
        public List<person> ReadData()
        {
            using (var db = new sampledataEntities())
            {
                return (from p in db.people select p).ToList();
            }
        }
    }
}

The purpose of this code is to provide a business object to handle the querying of data and maybe some business computations.  I’m just going to grab all the records in the table and return them as a list. 

Now you need to add the database project to your MVC project.  You can right-click on the References directory in your MVC project and “Add Reference”.  Then select “Projects” on the left and check the database project in the list (it should be the only one there).  Now you can add a “using Database” to your API controller (PersonnelController.cs file) and reference anything in the database project that is public.

Now add a method to your API controller (in the PersonnelController.cs file) using this code:

[HttpGet]
public string ReadData()
{
    PersonData p = new PersonData();
    List<person> data = p.ReadData();

    var json = JsonConvert.SerializeObject(data);
    return json;
}

 
You’ll have to add two usings to the top to make this code compile:

using Database;
using Newtonsoft.Json;

If your code compiles, then run it and see what happens.  You should see the name of one person from your database (assuming you have records in your person table).

You can troubleshoot this app by first putting a cursor in your controller “ReadData()” method and running the app.  This should get called when the JQuery AJAX call is made.  If it doesn’t get there, then you have a problem with your html or your javascript.  It does get there, then it’s time to step through the data read and see if that works.  If you make it to the serializeObject line, then your data should be in the list called “data” (put your cursor of this variable and you can see how many items there are in the list).  Next, you should be able to get through the C# API controller and the program resumes execution at the JQuery AJAX call under the “success” function.  There you can put a breakpoint on the deserializing of the data and you should be able to see a list of items that match the format of the table that was passed from the C# code.  I peeled off the first record (record zero) and used the first and last name.  The names are not trimmed, but this is just for demonstration purposes.

Extending the Data Sent

Let’s pretend we are going to build a CRUD interface now and we need to have an “Edit” and a “Delete” Boolean variable to handle human interaction between the html interface and the C# controller.  Also, let’s assume that some sort of framework like AngularJS is used (though I’m not going to get into that in this article) and it becomes more convenient to have Booleans for each record to track what the user is doing.

So how can we add these in a manner that is easy to troubleshoot and understand?  We could just add the fields to the person table and ignore the data in the database.  That would be a waste of space on the server and we don’t really want to actually store this data because it just tells the controller that the user wants to modify or delete a record (I’m purposely leaving out the “add” operation, just to keep this short, but in reality, you’ll need that function as well). 

There are probably a dozen other “not so cool” methods to get around this problem, such as modifying the JSon text as it is passed between the JQuery and C# controller.  But the method I’m going to demonstrate is easy and clean.  First, add a class to your Database project and name it “PersonExtended.cs”.  Inside this class, you can “append” to the existing person class that is defined in the “person.cs” file (auto-generated by the EF-6 framework when you added the table to your edmx file).  If you open up the “person.cs” file you’ll see that the person class is actually a “partial” class.  Which means that you can declare another “partial” person class anywhere else in your project.  So that’s what I’m going to do.  Here’s the code I used inside the PersonExtended.cs file:

namespace Database
{
    public partial class person
    {
        public bool Edit { get; set; }
        public bool Delete { get; set; }
    }
}


What this code does is add two Boolean properties to the complete class.  These properties are not used by EF, but they can be used by your JQuery, or HTML to exchange user interactions with the API controller.  Once you add the code above, re-compile your project and put a breakpoint in your AJAX return call and examine a record of the data that arrives.  You’ll see the two extra fields inside that data.  You can initialize these variables in the query if you’d like, or you can initialize them in the person object.  Like this:

namespace Database
{
    public partial class person
    {
        public bool Edit { get; set; }
        public bool Delete { get; set; }

        public person() : base()
        {
            Edit = false;
            Delete = false;
        }
    }
}

To confirm these results, run the program with Edit and Delete set to false and check what arrives at the “success” point of your AJAX call.  Then change Edit to true in your initialization code and check what arrives a “success” this time.  You’ll see the values you expect. 

The reason that EF uses partial classes is so you can extend the class to include additional methods and properties without modifying the auto-generated files under the edmx file.  If you were forced to modify the generated class directly, then you would need to modify the T4 script file to insert your changes into the class generation (T4 script files end with tt file types and can be modified to change the way EF generates code). 

You can download the entire project here: MVC4 EF Test Project.

Summary

This project shows how to create an MVC API controller project using JQuery to communicate between a browser and a C# controller.  I also demonstrated how to setup another project to contain an Entity Framework 6 database.  I further showed how to include that project in your MVC project and extend an ORM table object in such a way that it will remain intact if you update your EF edmx file.

I’m currently working on a couple of projects for this blog.  One project includes a sample of AngularJS and the other project has unit testing for API controllers.  These projects will add onto what has been learned in this lesson and the previous lesson.


 

 

Leave a Reply