Attribute Routing In MVC

26. August 2012 14:33

ASP.NET ASP.NET MVC Web 

I took a look at Stack Overflow Stack-Exchange Data Explorer that is built in MVC and is open-source application to query the Stack Exchange data dump that is being provided by Stack Exchange team in every month or few. I do have a dump, but I was more curious to know about the application that they built to query the database. And I must admit that I learned tons of things. I came to know the power of Micro-ORM (Dapper) over Entity-Framework (EF) and one more pretty thing that attracted me was the routing mechanism used in the application. I strongly recommend that you check out this tool/application and take a deep dive in the code, lot of things to learn.

Before we start writing the code, we'll take a quick look at a NuGet package AttributeRouting. You can find the source code at GitHub in case if you are interested. The documentation is simple and explains almost every bit of the package. It's incredibly easy.

The NuGet package I am using is for MVC, if you want to do the same with your Web API application then use this package.

To see how easy it is to implement routing in your MVC application. Start Visual Studio and create a new MVC4 (Internet) application and fire up the below NuGet command.

This command just don't install one single package but also some other dependent packages. Here is the output when I fire the above NuGet command:

PM> Install-Package AttributeRouting
Attempting to resolve dependency 'AttributeRouting.Core (≥ 2.5.1.0)'.
Attempting to resolve dependency 'AttributeRouting.Core.Web (≥ 2.5.1.0)'.
Attempting to resolve dependency 'WebActivator (≥ 1.0.0.0)'.
Successfully installed 'AttributeRouting.Core 2.5.1.0'.
Successfully installed 'AttributeRouting.Core.Web 2.5.1.0'.
Successfully installed 'WebActivator 1.0.0.0'.
Successfully installed 'AttributeRouting 2.5.1.0'.
Successfully added 'AttributeRouting.Core 2.5.1.0' to MVCAttrRouteTest.
Successfully added 'AttributeRouting.Core.Web 2.5.1.0' to MVCAttrRouteTest.
Successfully added 'WebActivator 1.0.0.0' to MVCAttrRouteTest.
Successfully added 'AttributeRouting 2.5.1.0' to MVCAttrRouteTest.

Now before you make any changes to the web application, hit CTRL+F5. Hover or click on the links which are on the top which are About and Contact. The URL rendered in the address bar is something like this (as what specified in your application Global.asax file).

For About View:

/Home/About

For Contact View:

/Home/Contact

The Home that we see here is the name of the controller being used. I don't want the name of the controller to be visible to my site visitors or maybe I just want a different name there. Usually, I would have switch to my application Global.asax file and register a new route there. But now I can now control my routes within controller itself. This is pretty cool for and a time saver, as I do not have to avoid working with Global.asax. This is the simplest implementation of AttributeRouting. Below are the 2 Home controller methods About and Contact:

[GET("About")]
public ActionResult About()
{
    ViewBag.Message = "Your app description page.";
    return View();
}

[GET("Contact")]
public ActionResult Contact()
{
    ViewBag.Message = "Your contact page.";
    return View();
}

There are no changes in the method, only the routing attribute has been added. The URLs for About and Contact are now free from the controller name Home. Now we look at a second condition where I want to have a totally different URL for About view or to be specific I would say I want to have outbound URLs and this will require RouteName property with the routing attribute. This is called Named Routes. I am going to change the URL to /App/AboutMe.

[GET("App/AboutMe", RouteName = "About")]
public ActionResult About()
{
    ViewBag.Message = "Your app description page.";
    return View();
}

Working with parameters without routing can lead to very ugly URLs or some un-wanted params in the URLs. Again to have a clean URL we can handle the parameters passed to the controller action. I have added a new view named Welcome (no scaffolding) in the Home controller and added a ViewBag property GreetMessage. When this view is called, it will display a greeting message in a heading. The GreetMessage will hold the name of the person, which is our parameter. Below is our controller action:

[GET("App/Greet/{name}")]
public ActionResult Welcome(string Name)
{
    ViewBag.GreetMessage = "Welcome " + Name;
    return View();
}

The URL that is rendered on the browser is:

http://domain.com/App/Greet/Prashant

/App/Greet/ is the URL we want to show and Prashant is the parameter is being passed to the Welcome view.

This is it for this tutorial but this is not it. The AttributeRouting package has to offer a lot of things and has a very powerful and easy way of routing. There are very advance topics that are documented at GitHub.

Related Links:

 No Rating

Deploying .NET Application To Appharbor Using Git

7. August 2012 13:12

ASP.NET MVC Utils 

I have an account with Appharbor but never tried to deploy an application. Appharbor has an excellent integration with Github and Codeplex and if you are planning to showcase you application latest build then Appharbor is the best thing to do that. The Appharbor site has a detailed tutorial on how you can deploy your application from Github and Codeplex. But the question here is what will a programmer do if he just wants to deploy the application from his dektop or in other words if he wants to test his application which is not an open source application. Fortunately, it is possible and is pretty easy to use by using Git Bash. All a programmer need to to is to execute a bunch of commands to deploy the application. I have already deployed one of my application called MP3app to Appharbor (just for few days) which was previously hosted on sub-domain.

If you have an application and you want to showcase it then you can deploy the application to Appharbor. The application I have with me right now is an ASP.NET MVC application which demonstrates the use of Micro-ORM Dapper. This application is with me and is not hosted on Github or Codeplex and therefore I cannot take the advantage of deploying it from the code hosting service. 

Before you proceed I assume that you have an account with Appharbor and have Git bash installed on your machine. If you don't have Git bash installed on your machine, download it from here. After successfull login you can create a new application with the name of your choice. You can also select the datacenter location for your application, either United States or Europe.

Click Create New button to create your application, after which you will be shown with the application settings screen. On the right-hand side you can also see the links which will help you to get started with Appharbor using Bitbucket, Github and Codeplex. Moreover, you can also select add-on services like SQL Server with 20MB of space. You can see the complete list of add-ons and their charges here.

I am calling my application DapperTest which demonstrates the use of Micro-ORM with SQL ServerCE 4.0 in ASP.NET MVC3. On the left side under the application name and other configurations you can see two buttons, REPOSITORY URL and BUILD URL. Click on the REPOSITORY URL button and you will have the URL copied to your clipboard. Open any text editor and paste the copied URL over there as you will be need it afterwards.

Open Git bash and then navigate to the project/solution directory. This will be the original project/solution with source code and not the published version. Also you need to be sure that the project/solution has Visual Studio solutiuon (.sln) file. If the file is not present then you will not be able to deploy your application to Appharbor.

To navigate to the project directory fire the below command in the Git bash console:

cd D:\DapperApp

To initialize empty Git repository, execute the below command:

git init

If you navigate to your project folder, then you can see a folder named .git. By default, this folder is hidden. Now the repositiry is created, I can now add all the files to the repo using the below command:

git add .

It might be possible that you don't want to add certain files to the repository then you can add a .gitignore file. You can see an example here. After this, I can then commit it using the below command:

git commit -m "initial commit"

After the commit is successful, copy the repository URL that you saved initially in your text editor. Add the remote repository (in our case it is Appharbor) using the below command:

git remote add appharbor https://prashantkhandelwal@appharbor.com/dappertest.git

Make sure to replace the URL with the correct one. Once this command executed successfully, you can then deploy/push to Appharbor by using below command:

git push appharbor master

Before the application is being deployed, it will ask you for your Appharbor password. Make sure that you type it slowly because you will not be able to see the password being typed on the Git bash console.

This is it, enjoy the power of cloud.

Here is the list of few applications hosted on Appharbor:

Currently rated 3.0 by 1 person

MP3APP - A Web Application To Get Lyrics, Album Name, Album Art and More

29. June 2012 20:53

ASP.NET MVC Utils Web 

I was busy in few of my freelance projects and got a very rough weekends this whole month. But still I get a bit of time to work on my so called in-house project and somehow I was able to get it completed after a bit of testing. The application I built is a simple web application which will allow you to enter artist name and the song name and let you search the lyrics, album art, artist image, album name and album release date. I hope this application help few people out there.

Now, something about the internals and history of the application. I created a windows application 2 years back and thought of porting the same application for the web. For the, web I used ASP.NET MVC 3 with jQuery but the internals of the application remains the same as it was for my windows app. To fetch the lyrics I use LyrDB and WikiLyrics web services and for album art, album name, artist image etc. I used Last.FM web service. I package the whole stuff and what I got is the application which I was running since 2 years on my machine and now the same application is out for you, use it and suggest me something new if you anything in your minds.

I am not yet finished with this application and you'll see more in coming days.

Try out the application here: http://mp3app.midnightprogrammer.net

 No Rating

Working With Micro-ORM Dapper In MVC

29. May 2012 12:50

ASP.NET MVC 

I love working with MVC but I do have a hard time working with complex data with EntityFramework (EF). I heard of using inline SQL queries in MVC but don't know how to use it and will it have any performance issues? Few month's back I downloaded the StackOverflow (SO) Data Explorer which is an open-source project built on MVC to explore data dump provided by SO. The thing that took my attention in that code was that they have been SQL queries to get the data from the database. This looks promising to me as the guys at SO will never compromise with performance. SO Data Explorer uses the micro-ORM called Dapper which is authored by Sam Saffron of Stack Overlfow.

Getting Dapper

Dapper is also available on NuGet or you can also drop this single file in your project which is hosted at Google Code. You can use the below NuGet command to install Dapper.

Usage

Performing CRUD operations in EF is simple for simple scenarios, but when the required data is complex I prefer using SQL queries with joins and other related stuff which make my work far much easier. To demonstrate how to use Dapper to perform CRUD operations, I am building a simple application to manage contacts. I started up with creating a model named ContactModel. You can copy the below code or you can have one for yourself.

public class Contacts
{
    [Key]
    public int ContactID { get; set; }
    public string Name { get; set; }
    public string Address { get; set; }
    public string Email { get; set; }
    public string Skype { get; set; }
}

The model is ready but we are not using EF Code First which created the database for us on the fly and therefore I have a bit more work to do. I'll now create a database with a table which is same like my model. After the table has been created now I will add a new class to my project where I will write functions which will help me in performing CRUD operations. I will talk about view and controllers later when I am done with my DB access class. For this sample application I have used SQL CE 4.0 DB, but if you wish you can use SQL Server DB.

At the first, I just want to list down the contacts I have in the database. Practically this would have been the last thing to show in the example but I am showing this at first so you get an idea how Dapper works. As we have fresh database with no records, write down and insert query or just simply punch in the data in. Now in my data access class I will create a simple function which returns me the collection of contacts.

try
{
    using (SqlCeConnection con = new SqlCeConnection(ConStr))
    {
        con.Open();
        var contacts = con.Query<Contacts>("Select Name, Address, Email, Skype from Contacts");
        return contacts;
     }
}
catch (Exception x)
{
    throw x;
}

The above functions returns the collection of the contacts which I will use in my Index view where I am going to list down all the contacts I have with me (See the SQL query :) ). Add a new controller or use the existing Home controller and add the below ActionResult method ListContacts.

public ActionResult ListContacts()
{
    var db = new DB();
    return View(db.GetContacts());
}

I now must have a view which will display the list of all the contacts. Right-click on ListContacts() method and choose Add View. A pretty familiar dialog pops up like the one below.

Nothing fancy here, just select the model class as the Contacts and Scaffold template as List. Hit F5 and change the URL to {View}/ListContacts and you will be able to see the list of contacts.

Performing INSERT/UPDATE and DELETE operations

To insert the data in the database create the below method in the DB access class:

public bool CreateContact(Contacts contact)
{
    try
    {
        using (SqlCeConnection con = new SqlCeConnection(ConStr))
        {
            con.Open();

            string sqlQuery = "INSERT INTO Contacts([Name],[Address],[Email],[Skype]) VALUES (@Name,@Address,@Email,@Skype)";
            con.Execute(sqlQuery,
                                  new
                                  {
                                      contact.Name,
                                      contact.Address,
                                      contact.Email,
                                      contact.Skype
                                  });
        }
        return true;
    }
    catch (Exception x)
    {
        return false;
    }
}

I have a normal INSERT statement which will insert the records for me. The point that you need to note is that it is executed by the Execute extension method of the SqlCeConnection class. If you use SQL Server then the class will be SqlConnection class. Returning to controller and just to remind you that if we were working with EF which would have done the CRUD part for us then you must be aware that there are 2 ActionResult methods which were required for this purpose. One will just return the view and the other one with [HttpPost] attribute will create the record. I require a create view so I can add contacts. Follow the same steps you have followed above while creating the ListContacts view. For your further help here are the 2 ActionResult methods to create a new record (I am sure you can create a view!! Just right-click Create() method and click AddView and the scaffold is Create).

public ActionResult Create()
{
    return View();
}

[HttpPost]
public ActionResult Create(Contacts contact)
{
    var db = new DB();
    bool isCreated = db.CreateContact(contact);
    if (isCreated)
    {
        return RedirectToAction("ListContacts");
    }
    else
    {
        return View();
    }
}

The process of updating a contact will be similar like we have done for the insert. Before updating a contact I need to get the details of the contact when the user clicks on the Edit link on the page. When the user clicks the Edit hyperlink on the list page, the contact ID will be paased as a parameter.

public Contacts GetContactByID(int ContactId)
{
    using (SqlCeConnection con = new SqlCeConnection(ConStr))
    {
        con.Open();
        string strQuery = string.Format("Select ContactID, Name, Address, Email, Skype from Contacts where " +
        "ContactID={0}", ContactId);
        var customer = con.Query<Contacts>(strQuery).Single<Contacts>();
        return customer;
    }
}

public bool UpdateContact(Contacts contact)
{
    try
    {
        using (SqlCeConnection con = new SqlCeConnection(ConStr))
        {
            con.Open();
            string sqlQuery = "UPDATE Contacts SET Name =@Name, Address =@Address, Address = @Address, " +
            "Email = Email, Skype = @Skype WHERE ContactID=@ContactID";
            con.Execute(sqlQuery, new
            {
                contact.Name,
                contact.Address,
                contact.Email,
                contact.Skype,
                contact.ContactID
            });
        }
        return true;
    }
    catch (Exception)
    {
        return false;
    }
}

The GetContactByID method will accept the contactId which is passed as a parameter to the Edit ActionResult method. I am calling this method from the Edit ActionResult. The main purpose of this method is to fetch the contact details on the basis of the ID passed to it. The returned Contacts serves as a model to the Edit view which then populates the details of the contact I want to edit. I assume here you know how to create a View. Here is my Edit and Edit with HttpPost which does the actual update work. The UpdateContact method will get called from the Edit ActionResult method which is attributed with HttpPost.

public ActionResult Edit(int ContactID)
{
    var db = new DB();
    return View(db.GetContactByID(ContactID));
}

[HttpPost]
public ActionResult Edit(Contacts contact)
{
    var db = new DB();
    db.UpdateContact(contact);
    return RedirectToAction("ListContacts");
}

Following the same procedure that I followed for insert and update I am going to implement the delete functionality. The below code will be used to delete the contact details.

public bool DeleteContact(int ContactID)
 {
     try
     {
         using (SqlCeConnection con = new SqlCeConnection(ConStr))
         {
             con.Open();
             string sqlQuery = "DELETE FROM Contacts WHERE ContactID=@ContactID";
             con.Execute(sqlQuery, new { ContactID });
         }
         return true;
     }
     catch (Exception)
     {
         return false;
     }
 }

And for your ease, here are the 2 ActionResult methods.

public ActionResult Delete(int ContactID)
{
    var db = new DB();
    return View(db.GetContactByID(ContactID));
}

[HttpPost]
public ActionResult Delete(int ContactID, FormCollection frm)
{
    var db = new DB();
    bool IsDeleted = db.DeleteContact(ContactID);
    if (IsDeleted)
    {
        return RedirectToAction("ListContacts");
    }
    else
    {
        return View();
    }
}

This is it. A simple application where you can perform CRUD operations using SQL queries with micro-ORM Dapper.

Performance

Another reason for using a micro-ORM, Dapper in my case, but if you check the documentation you can see the table which clearly state the difference between the different ORMs.

There are other ORMs that you can try like the Massive ORM and PetaPOCO.

 No Rating

Get Song Lyrics From LYRDB With ASP.NET MVC And JQuery

26. November 2011 14:59

API ASP.NET MVC 

Most of the times I have seen people looking for song lyrics on online MP3 or lyrics database sites. Few of them provide API to fetch lyrics which is good for developers. Last.fm has a powerful API but they don't provide any API call to fetch lyrics. The two most popular APIs on the web that I am aware of is WikiLyrics, LyricsDB (popularly known as LyrDB), there is another API from ChartLyrics but I don't find it as useful as the other two APIs. The WikiLyrics API works beautifully, but it has one drawback the lyrics fetched from the service is incomplete. I wrote a complete desktop application to fetch lyrics, album art, artist image, album name and album release date but never made it available to download for public. I am planning to release it to general users. But till then you can take a look at this simple little app which I created in my spare time to fetch lyrics from LyrDB.

This little simple application is in ASP.NET MVC. I am not a designer so I will take advantage of the default design. In the home controller I have a simple method named GetLyrics which accepts two parameters Artist Name and Song Name. The method returns results in JSON as it will be good for me to parse the results in JQuery. Take a look at the code:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult GetLyrics(string ArtistName, string SongName)
{
            string response = string.Empty;
            string LyrURL = string.Empty;
            string url = "http://webservices.lyrdb.com/lookup.php?q=" + ArtistName + "|" + SongName + "&for=match";
            WebResponse wResp = (WebRequest.Create(url) as HttpWebRequest).GetResponse();
            using (StreamReader sReader = new StreamReader(wResp.GetResponseStream()))
            {
                response = sReader.ReadToEnd();
            }

            if (response == "")
            {
                response = "No Lyrics found on LyrDB for " + SongName + " by " + ArtistName;
                goto Output;
            }

            string[] lyrID = response.Split('\\');

            response = "";

            LyrURL = "http://webservices.lyrdb.com/getlyr.php?q=" + lyrID[0]+"&callback=?";

            Output:

            return Json(new
            {
                success = true,
                Lyrics = LyrURL
            });
}
The above code does not return the lyrics but the URL to get the lyrics. I am a big Jquery fan and as usual I will be using it here to make an AJAX call and load an IFRAME with the lyrics URL.
$(document).ready(function () {
        $("#btnSearch").click(function () {
            $("#btnSearch").attr('disabled', true);
            $("#lyrics").addClass("loading");
            $("#LyrFrame").attr('src', '');
            var Artist = $("#txtArtistName").val();
            var Song = $("#txtSongName").val();
            var url = "/Home/GetLyrics?ArtistName=" + Artist + "&SongName=" + Song;
            $.ajax({
                url: url,
                type: "POST",
                dataType: "json",
                data: "{'ArtistName': " + Artist + ",'SongName': " + Song + "}",
                success: function (data) {
                    $("#lyrics").html("<iframe id=\"LyrFrame\" src=\"" + data.Lyrics + "\" marginwidth=\"0\" marginheight=\"0\" frameborder=\"0\" vspace=\"0\" hspace=\"0\" width=\"980\" height=\"750\"></iframe>");
                    $("#btnSearch").attr('disabled', false);
                    $("#lyrics").removeClass("loading");
                }
            });

        });
});

The URL in the above script calls GetLyrics method which is inside Home Controller takes artist and song name as query string. On the success of the call the IFRAME gets loaded with the lyrics URL. The output will look something like this:

 

You can download the application source code from the below link, but I want to tell you that it will not fetch each and every song lyrics for you. It's a database and it can provide us only information it has. But the desktop application I am will release in future will check around 2 lyrics API at least and I believe that my application guarantees 100% result. So follow my upcoming posts.

Download: LyrDBApp.zip (886.46 kb)

Related Links:

 No Rating