In part 1 of SubSonic 3 with MVC and jQuery, I walked you through getting started and setup with MVC 1.0 and SubSonic. Here in part 2, I'll be showing more code on MVC Actions like Details, Create, Edit and Delete.
Picking up from the part 1 of the series where I was dissecting the "Index" view, let's go back to the ProductsController class in the "Controllers" folder.
ActionResult: Details
This is straight forward, but it's the first ActionResult where you are receiving a parameter like a normail method. In my code below, I'm establishing my repository with SubSonic using the SimpleRepository method. Next, it looks up the product based on the "id" being passed.
If it doesn't find it, then it redirects to the "NotFound" View. If it does find it, then it goes to the "Details" View and passes the product data class.
//
// GET: /Products/Details/5
public ActionResult Details(int id)
{
// Get Product
var _repo = new SimpleRepository();
Product product = _repo.Single<Product>(id);
if (product == null)
{
return View("NotFound");
}
else
{
return View("Details", product);
}
}
Like before with the "Index" view, Right-Click on the "Details" that's next to the ActionResult and select "Add View". Be sure to select your "data class" for products and your "view content" for Details.

Again, by telling Visual Studio MVC what data class you are using and the view content that you want, it automatically builds the view for you by putting in the database fields that you have which is very cool and convenient. :)
ActionResult: Delete
The Delete is also simple in that you call it like you do the "Details" view (in the Get method type). The code within is virtually identical to the "Details" view, but just returning to the "Delete" view instead. Follow the same instructions fo the "Delete" view as you did for the "Details" View.
After you created the "Delete" view, add code like the following to the "MainContent" section of the "Delete" view (this is from the NerdDiner example, btw):
<h2>Delete Confirmation</h2>
<div>
<p>Please confirm you want to delete the product titled:
<i> <%= Html.Encode(Model.ProductName) %>?</i></p>
</div>
<% using (Html.BeginForm())
{ %>
<input name="confirmButton" type="submit" value="Delete" />
<% } %>
ActionResult: Delete (From a Post request)
Ok, now we are starting to build on the MVC framework a bit. The code below shows the Post request coming back from the "Delete" view saying "Delete this Product". Using the [AcceptVerbs(HttpVerbs.Post)], we tell the method to be on the lookout for a Post coming from the "Delete" view with the parameters for the productID, and the string value of the confirmButton.
//
// HTTP POST: /Products/Delete/1
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Delete(int id, string confirmButton)
{
// Get Product
var _repo = new SimpleRepository();
Product product = _repo.Single<Product>(id);
if (product == null)
{
return View("NotFound");
}
else
{
_repo.Delete<Product>(id);
return View("Deleted");
}
}
ActionResult: Create
Like the other views, Right-Click on the "Create" to the right of the "ActionResult" to Add the "Create" View. Be sure to select your "Products" data class and the "Create" for view content. I won't bother you anymore with screen shots of adding the view since it's pretty redundant. The purpose of this simple "Create" view is merely to redirect you to the View itself.
jQuery Validation (I know, it's about time right)
The jQuery Validation is very cool stuff. It's a plugin for the jQuery framework, and makes client-side validation a breeze. Check out the code below on how to add it to your View for some quick validation.
- First things first: update your using {Html.BeginForm()} tag like the following code (below). We need to give the form a name so jQuery knows how to talk to it.
<% using (Html.BeginForm("Create", "Products", FormMethod.Post, new { id = "Form1" }))
{%> - Next, you need to reference both the jquery-1.3.2.js and jquery.validate.js classes, then add your jQuery code below it. In the code below, I'm doing validation on the ProductName field and the UnitsInStock field. You can obviously add more fields and changed them out.
<script src="../../Scripts/jquery-1.3.2.js" type="text/javascript"></script>
<script src="../../Scripts/jquery.validate.js" type="text/javascript"></script>
<script type="text/javascript" language="javascript">
$(document).ready(function(){
$("#Form1").validate({
rules: {
ProductName: {
required: true,
minlength: 2
},
UnitsInStock: {
required: true
}
},
messages: {
ProductName: {
required: "* Required",
minlength: "* Minimum (2) Characters Required"
},
UnitsInStock: {
required: "* Required"
}
}
});
})
</script>
The jQuery doesn't require anymore then that code above. You don't have to touch your fields in the HTML code. It will automatically valid on the designated form's Post. Also, it means that you can leave your pre-built server-side validation in place that the MVC framework has built for you.
ActionResult: Create (From a Post response)
Now that we have our "Create" view setup, we need to handle it. If you view the code below, this is doing several things:
- Sets up the database connection via SimpleRepository (SubSonic 3)
- Sets up the entities via new Product()
- Uses the "UpdateModel([entity class])" from the MVC framework to grab all of the Request.Form data (very cool)
- If successful, it redirects them to the "Details" view along with the new productID of the product added.
- If not successful, it puts them back to the originating view (in this case "Create" view), along with the Error Message which fires up the Validation Summary, highlights the fields in question along with their individual error messages.
//
// POST: /Products/Create
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(FormCollection collection)
{
// Add Product
var _repo = new SimpleRepository();
Product item = new Product();
try
{
UpdateModel(item);
_repo.Add<Product>(item);
return RedirectToAction("Details", new { id = item.ProductID });
}
catch (Exception ex)
{
ModelState.AddModelError("Error", ex.Message);
}
return View(item);
}
ActionResult: Edit
If you had a mashup between the "Details" and the "Create" view, you would have the "Edit" view. Same as before, get the data, load it into the Entity, and then pass it to the view model. Just like the "Create" view, you can add your jQuery Validation to this page the same way. Just cut and paste!
//
// GET: /Products/Edit/5
public ActionResult Edit(int id)
{
// Get Product
var _repo = new SimpleRepository();
Product item = _repo.Single<Product>((x => x.ProductID == id));
if (item == null)
{
return View("NotFound");
}
else
{
return View("Edit", item);
}
}
ActionResult: Edit (From a Post response)
This is just like intercepting the Post response from a "Create" View, but "Edit". Here you notice that we can reuse the "UpdateModel" courtesy of the MVC Framework. SubSonic 3 just has the "Update" in lieu of "Add".
//
// POST: /Products/Edit/5
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(int id, FormCollection collection)
{
// Update Product
var _repo = new SimpleRepository();
Product item = _repo.Single<Product>((x => x.ProductID == id));
try
{
UpdateModel(item);
_repo.Update<Product>(item);
return RedirectToAction("Details", new { id=item.ProductID });
}
catch (Exception ex)
{
ModelState.AddModelError("Error", ex.Message);
}
return View(item);
}
I hope that with the SubSonic 3 with MVC and jQuery Example it helps you get started with MVC and SubSonic 3, this more complete example would have made it a bit easier for me learning it I know. :)



