Browsing:

Month: July 2010

ASP.NET MVC 2 and MongoDb Part 4 – First steps with jQuery, AJAX and JSON

In the past articles we created a simple application to submit bugs to a project. If you run the BugBase app, it looks like this:



It’s ugly!
Let’s add some style quickly. And since I am not a webdesigner, I Google for ‘minimalist templates’ and grab a free one, like this one, courtesy to Cardeo.

Masterpages are around for eons, so I won’t go into the technical details of this phenonemon much. After creating a masterpage from Cardeo’s design, BugBase looks like this:

And the bug submitform:

It’s slightly better, no?

JavaScript, Ajax and JSON

Ajax is a technique that provide a snappier user experience through the use lightweight calls to the web server, in stead of full roundtrips to the server every time you submit a form. These asynchronous calls are initiated on the client using JavaScript and involve formatting data, sending it to a web server, and parsing and working with the returned data. While most browsers can construct, send, and parse XML, JavaScript Object Notation (or JSON) provides a standardized data exchange format that is better-suited for Ajax-style web applications. (Okay, I didn’t write the last paragraph myself, Microsoft did. But I never found a more clever desription of the JQuery. AJAX and JSON triade.)

So, let’s Ajaxify the Bug submit form. Let’s make use of the jQuery Form Plugin, which actually does everything for you. Just copy jquery.form.js to the Scripts folder and make references in the head sections of Create.aspx (or in the BugBase.Master).

Next, I’m going to go ahead and add my own .js file (Add, New Item) to the scripts folder for my jQuery code. Also add a reference to this script:

[csharp htmlscript=”true” highlight=”4,5,6″]
<head>
<title>BugBase the Bug submitting app</title>
<link href="../../Content/style.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="../../Scripts/jquery-1.4.1.js"></script>
<script type="text/javascript" src="../../Scripts/jquery.form.js"></script>
<script type="text/javascript" src="../../Scripts/BugBase.js"></script>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
</head>
<body>
[/csharp]

Next thing we need to do, is add an ID to the /Bug/Create form. As you can see, the HTML is rendered with the help of HTML Helpers (hm, so that’s where those helpers get their names from) but I am not sure if HTML is better with or without these helpers. So, I just click on View Source in my browser and copy the generated HTML to Create.aspx. Next, I can add an ID to the form, which is important because this is how the jquery.form.js references the submit form.

[csharp language=”true” highlight=”1″]
<form action="/Bug/Create" method="post" id="BugSubmitform">
<div class="editor-label">
<label for="Name">Name</label>
</div>
<div class="editor-field">
<input id="Name" name="Name" type="text" value="" />
</div>
<div class="editor-label">
<label for="Description">Description</label>
</div>
<div class="editor-field">
<textarea cols="20" id="Description" name="Description" rows="2">
</textarea>
</div>
<p>
<input type="submit" value="Create" />
</p>
</form>
<h6><h6>
[/csharp]

Next step is edit the (still empty) BugBase.js and add the following code:

[javascript highlight=”5″]
$(document).ready(function () {
$(‘#BugSubmitform’).ajaxForm({
dataType: ‘json’,
success: function (response) {
$(‘h6’).text("Bugname: " + response.Name + ".
And the description is: " + response.Description);
alert(response.Description);
}
});
});
[/javascript]

Hmm, this is pretty self-explanatory I think? The first line you should know by heart if you plan to write more jQuery.
The next thing you see how we reference the id of the form, i.c. #BugSubmitform. So the form plugin knows at which point it should wake up. Then we are specifying the dataType, which is json. On success, we’re going to display an alert, with the Description of our bug. Also, we will display the bug name and bug description between H6 tags, which I added on the Create.aspx page.

You see, ‘response’ in line 5 is actually the submitted bug serialized in json format. So, we can use all the properties of the Bug class here!

We’re not completely finished though. We’ll have to make sure the Create function of our controller actually returns JSON. Which is in fact very easy:

[csharp]
[RequiresAuthentication]
[HttpPost]
public ActionResult Create(Bug bug)
{
BugSession.Save(bug);

if (Request.IsAjaxRequest())
{
return Json(bug);
}

return new RedirectResult("Create");
}
}
[/csharp]

That’s it. Let’s try it.

To see that we really really Ajaxified things, we should fire Firebug form Firefox. If you check out the console, you’ll notice the XMLHttpRequest, which proves that this was an AJAX request and the returnformat is JSON:

So now we know how we can speed up our app by using AJAX and jQuery and how we can provide the user feedback with the JSON result. As soon as I completed the BugBase app, I will post it here for you to download.


Entity Framework from scratch Part 4 EF4 Multi Layered – System.Data.Entity not referenced

As i mentioned in the previous post, there seems to be a problem when you work with Multi layered Solutions in the Entity Framework. You need to add the Entity references to all the solutions in your project, but i found another small problem when creating a web front to your application.
I’ve built this app with EF4 features with web functionality.

When i debug my code, the database connection works and the table rows are fetched, but my webpage displays an compilation error: CS0012: The type ‘System.Data.Objects.DataClasses.EntityObject’ is defined in an assembly that is not referenced. You must add a reference assembly to ‘System.Data.Entity, version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089’.

You need to add extra code manualy to your Web.config file directly under the system.web

[csharp]<configuration>
<system.web>[/csharp]

copy/paste the following code:

[csharp]
<compilation debug="true" targetFramework="4.0">
<assemblies>
<add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</assemblies>
</compilation>
[/csharp]

If you built and re-run the the app, the webpage is displayed correctly.


Entity Framework from scratch Part 3 EF4 Database

How to connect your existing database  to a new entity Framework driven app.  I was surprised about the ease of connecting the database to the app. It takes just 5 steps to realise the connection with any available database. EF supports all sorts of databases.

Here we go: First open your project and right click Shoeshoedata

Then we  select Ado.net Entity Data Model and name it Myshoes.edmx

Choose your excisting datamodel

Choose your data Connection, in this case we use the  excisting’ Shoe’ database

Select which tables (or views)  you’ll need for your EF app

and the database is connected to your new EF4 project. See that was easy.

Now the project is ready to use your database.

And now for the Multiple solution config in EF4

Is this yet another famous Microsoft workaround!? Since the new EF4 app couldn’t find his connection string.

We we’re looking for a solution to get our App.config to communicate with the console reference. this problem only occurs  when you work with multiple project solutions, he can’t seem to find the correct references.

We found out it doesnt work when you just change the .config properties to Copy always, you also need to copy the app.config file to the console app.  as soon as this is done, it works. Maybe there is another solution for this problem, but i have not yet found it.


Entity Framework from scratch Part 2 EF4 release

A lot has happened since the last blog where we introduced the entity framework and tried to explain the possible benefits it could have over the other NoSQL.
Microsoft has released a new EF4 that builds us cleaner code, “Code First Development”

They have kept their eyes out on the other NoSQL movements and learned, In this post we are going to introduce 2 new types, the DbContext and the DbSet that EF4 brought us.
At first I was puzzled as in why two new types, and not just remake the ObjectContext and ObjectSet.
But there is a logica behind this, as you can read on the Msdn blog. They are no replacement, they are just simplified. Now you can always choose to use the more advanced types. DBSet has full compatibility with the excisting EF’s and to switch to the ObjectContext and ObjectSet.

We are going to build a standard console app.
First, make sure you’re on .Net version 4, or the entity framework 4 will not work.

Dwnload the new EF4 features here and install them.

Fire up your visual studio and choose the console app, and name it ShoeShoe. Now add a using statement on top of the program.cs

using System.Data.Entity;

Now define the two classes we need for our data, namely ShoeShoe a class that describes the shoes in my closet and second the type of shoes i have collected.

public class ShoeCat
{
    public string ShoeCatId { get; set; }
    public string Name { get; set; }

    public virtual ICollection Shoe { get; set; }
}

public class ShoeShoe
{
    public int ShoeShoeId { get; set; }
    public string Name { get; set; }
    public string CategoryId { get; set; }

    public virtual ShoeCat Category { get; set; }

Now we are gonna add context using the new DbContext DbSet type from EF4

public class ShoeShoeCatalog : DbContext
{
    public DbSet Categories { get; set; }
    public DbSet Products { get; set; }
}

To get your console app to recognize the Dbset statement, we need to add 2 references:
The Microsoft.Data.Entity.CTP
microsoft.data.entity
and the system.data.entity.

this is all the code needed to start the process of storing and retrieving data.

Now let’s put some data in the app and build a program class

class Program
{
    static void Main(string[] args)
    {
        using (var context = new ShoeShoeCatalog())
        {
            var Pump = new ShoeCat { ShoeCatId = "Pump", Name = "Sexy" };
            context.Categories.Add(Pump);
            int recordsAffected = context.SaveChanges();

            Console.WriteLine(
                "Succesfully Saved {0} row(s) to the database, press any key to exit.",
                recordsAffected);

            Console.ReadKey();
        }
    }
}

Now we successfully added shoeshoe data.
This is ofcourse just the beginning of our shoeshoe app, but i hope you are bit more familiar with the 2 new types EF4 has provided us.

Enjoy ! Next we are going to build extra features in ourShoeShoe console application.


ASP.NET MVC 2 and MongoDb Part 3 – Custom membershipprovider

Out of the box you can easily implement a user management system in a ASP.NET MVC (2) application with very little effort. You can use the SqlMembershipProvider which will create a database for you with tables for maintaining users and their roles. But what if you don’t use SQL as a backend but Mongo instead?
Then you need to implement your own custom membership provider. Here are the steps to do just that.

NB: This is just to get you started! It’s not a very tightly secured authentication system, so don’t use this in production. In production you’ll probably want to use SSL and encrypted passwords.

In ASP.NET MVC it is possible to secure controller actions, like this:

[csharp]
[RequiresAuthentication]
public ActionResult Index()
{
var session = new MongoSession();
{
var userlist = session.users.AsEnumerable();
return View(userlist);
}
}
[/csharp]

By adding the RequiresAuthentication attribute above the controller method ‘Index’, the /User/Index page is secured.

To accomplish this, we need to take the following steps:

  • Add the authentication attribute class
  • Add a membership class which implements the MembershipProvider interface
  • Add a Controller and a View
  • Modify web.config

Let’s start with the RequiresAuthenticationAttribute class, which inherits from the ActionFilterAttribute:

[csharp]
public class RequiresAuthenticationAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
//redirect if not authenticated
if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
{
//use the current url for the redirect
string redirectOnSuccess = filterContext.HttpContext.Request.Url.AbsolutePath;

//send them off to the login page
string redirectUrl = string.Format("?ReturnUrl={0}", redirectOnSuccess);
string loginUrl = FormsAuthentication.LoginUrl + redirectUrl;
filterContext.HttpContext.Response.Redirect(loginUrl, true);
}
}
}
[/csharp]

Now that we have this class defined, let’s create our custom membershipprovider class.
Firstly, create a class with the name ‘BugBaseMembership’ and let it implement the MembershipProvider interface:

implement membershipprovider interface

Now scroll down to the last method:

implement3

Here you can implement your own validate user method. And our backend is of course MongoDb so here we go:

[csharp]
public override bool ValidateUser(string email, string password)
{
using (var session = new MongoSession())
{
User user = session.users
.Where(u => u.Email == email &amp;&amp; u.Password == password).FirstOrDefault();
if (user == null) return false;
else return true;
}
}
[/csharp]

Next, create an AccountController and implement the Login method:

[csharp]
namespace BugBase.Controllers
{
public class AccountController : Controller
{
public ActionResult Logon()
{
return View();
}

[HttpPost]
public ActionResult Logon(string email, string password, string returnUrl)
{
// Basic parameter validation
if (String.IsNullOrEmpty(email))
{
ModelState.AddModelError("email", "You must specify a mailaddress.");
}
if (String.IsNullOrEmpty(password))
{
ModelState.AddModelError("password", "You must specify a password.");
}

if (ViewData.ModelState.IsValid)
{

BugBaseMembership provider = new BugBaseMembership();
bool loginSuccessful = provider.ValidateUser(email, password);

if (loginSuccessful)
{
SetAuthenticationCookie(email);
return RedirectToAction("Index", "Bug");
}

else
{
ModelState.AddModelError("_FORM", "The username or password provided is incorrect.");
}
}

// If we got this far, something failed, redisplay form

return View();

}

public virtual void SetAuthenticationCookie(string username)
{
FormsAuthentication.SetAuthCookie(username, false);
}

public void Logoff()
{
FormsAuthentication.SignOut();
Response.Redirect("/");
}
}
}
[/csharp]

When the logon is successfull, you are directed to /Bugs/Index and the authentication is set. Which means that you can retrieve the logonname from the user during the session (User.Identity.Name returns the current logon name).

We’re not there yet. We have create a View for the user to enter Username and Password.
It should be strongly typed View and derive from the BugBase.Models.User class.

[csharp htmlscript=”true”]
<label for="email">email</label>
<label for="password">password</label>
<input type="submit" value="Log in" />
[/csharp]

There is one thing left to do. We need to plug our custom membership system into the website.
Open web.config and add the following in the System.Web section:

implement4

There you go. You just created your own custom membership provider with a MongoDb backend. Pretty easy, no?

You can download the codesample here.