Posts Tagged ‘asp.net mvc’

May 11th, 2009

Creating Your First MVC ViewEngine

A question that I have been hearing a lot lately is:

How do I change the view location in MVC?

But what they really mean to say is:

How do I create a new ViewEngine that uses the view locations of my choosing?

It is actually very simple to do, and once you see it, I think you will agree with my assessment.  The first thing we are going to do to create our custom ViewEngine, is define the paths that we want to use for our master pages, view pages, and shared pages.  I have taken the liberty to define the following paths, you can customize them however you wish:

  • Master Pages:
    ~/Templates
    it use to be ~/Views/Shared or the controllers view
  • View Pages:
    ~/Views
  • Shared Pages:
    ~/Common
    it use to be ~/Views/Shared

The next thing we need to do is create a new class for our ViewEngine, for this example we are going to call it SimpleViewEngine.

public class SimpleViewEngine : VirtualPathProviderViewEngine
{
}

As you might have noticed from above our SimpleViewEngine inherits from VirtualPathProviderViewEngine, this is the root ViewEngine that uses the VirtualPathProvider (VPP). The VPP provides a way for web applications to read files off the file system in their local web application, so it is perfect for what we are doing. If you don’t want a file system based ViewEngine, and maybe want a ViewEngine based from the database, you can use the IViewEngine interface to create your own custom ViewEngine that fits your needs. (MVC is very flexible, by design)

The next thing we need to do is code our paths in to our SimpleViewEngine. We will do this in the constructor, so that they only have to be initialized once for the entire life span of our SimpleViewEngine.

public SimpleViewEngine ()
{
	/* {0} = view name or master page name
	 * {1} = controller name
	 */

	// create our master page location
	MasterLocationFormats = new[] {
		"~/Templates/{0}.master"
	};

	// create our views and common shared locations
	ViewLocationFormats = new[] {
		"~/Views/{1}/{0}.aspx",
		"~/Common/{0}.aspx",
	};

	// create our partial views and common shared locations
	PartialViewLocationFormats = new[] {
		"~/Views/{1}/{0}.ascx",
		"~/Common/{0}.ascx"
	};
}

As you can see the format is pretty straight forward. We create a string[] array with the paths of where our master pages, views, and common views are located. The only thing that we need to do is set place holders in our path so the the VirtualPathProviderViewEngine can replace the master name, view name, and controller name to construct our appropriate path.

  • {0}: is the view name or master page name.
  • {1}: is the controller name.

After we have done the hard part, which honestly wasn’t that hard, of creating the constructor with the paths, we just need to return the view objects from the constructed partial paths. Since we are using the standard ASP.NET Web Form (ASPX/ASCX) rendering engine. We are able to leverage the work already done by the MVC team and just return a new instance of the WebFormView object.

protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath)
{
	return new WebFormView(partialPath, null);
}

protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath)
{
	return new WebFormView(viewPath, masterPath);
}

Nothing really earth shattering here, just simply filling out the constructor with the proper parameters from our method, and then returning the newly created view. If you wanted to create a view based out of the database, or off your own syntax (meaning not ASP.NET syntax) then you would have to create your own view based off of the IView interface. But for this example we are only concerned with changing where our views are located.

There is one more thing that we need to do, and that is register our new SimpleViewEngine for use in the framework. The registration of view engines is done in the Global.asax, similar to the same way we register new routes.

public static void RegisterViewEngines(ViewEngineCollection viewEngines)
{
	viewEngines.Clear();
	viewEngines.Add(new SimpleViewEngine());
}

public static void RegisterRoutes(RouteCollection routes) { ... }

protected void Application_Start()
{
	RegisterRoutes(RouteTable.Routes);
	RegisterViewEngines(ViewEngines.Engines);
}

So we are now done. You have created a new view engines, defined your own routes, and registered this view engine with the MVC framework. Some other types of paths you may want to consider trying for your applications, using a custom ViewEngine, are special folders for your mobile or Facebook versions of your website.

  • Mobile: ~/Views/{1}/Mobile/{0}.aspx
  • Facebook: ~/Views/{1}/Facebook/{0}.aspx

I told you it was simple and straight forward, and I hope you agree that the MVC team has done an awesome job at providing a very flexible framework for us to tweak and customize it so it fits our applications.

Tags: , ,

Posted in ASP.NET, C#, How To | kick it on DotNetKicks.com | Bookmark | View blog reactions | 10 Comments »

March 18th, 2009

ASP.NET MVC 1.0 Released

Final Cover PhotoIt was just announced at MIX09 that ASP.NET MVC 1.0 has been released for general use and is out of the Release Candidate phase.  There has been no word on the changes form RC 2 to this release version.  But I will keep this post updated as I learn more.  Also as of writing this the download hasn’t been posted to CodePlex either, but I am sure that it will be posted pretty soon.

I am assured by Wrox that the cover of the book will be updated to look like what is on the right of your screen.  So it should be any day now, so go pre-order a copy today by clicking on the cover image to your right and it will take you to the Amazon page where you can place your pre-order.  That way as soon as the book ships you will have a copy waiting on your front porch.

Update: It is available from Microsoft Download.  Probably on CodePlex by the end of the day.  Here is the final description of the download for your reading pleasure.

ASP.NET MVC 1.0 provides a new Model-View-Controller (MVC) framework on top of the existing ASP.NET 3.5 runtime. This means that developers can take advantage of the MVC design patterns to create their Web Applications which includes the ability to achieve and maintain a clear separation of concerns (the UI or view from the business and application logic and backend data), as well as facilitate test driven development (TDD). The ASP.NET MVC framework defines a specific pattern to the Web Application folder structure and provides a controller base-class to handle and process requests for “actions”. Developers can take advantage of the specific Visual Studio 2008 MVC templates within this release to create their Web applications, which includes the ability to select a specific Unit Test structure to accompany their Web Application development.

The MVC framework is fully extensible at all points, allowing developers to create sophisticated structures that meet their needs, including for example Dependency Injection (DI) techniques, new view rendering engines or specialized controllers.

As the ASP.NET MVC framework is built on ASP.NET 3.5, developers can take advantage of many existing ASP.NET 3.5 features, such as localization, authorization, Profile etc.

Update: Phil Haack just posted his MVC 1.0 Release Anouncement.

Tags:

Posted in ASP.NET, News | kick it on DotNetKicks.com | Bookmark | View blog reactions | 2 Comments »

March 3rd, 2009

ASP.NET MVC 1.0 Release Candidate 2

Final Cover PhotoPhil Haack has announced the availability of ASP.NET MVC 1.0 Release Candidate 2.

You can download the new version from Microsoft. Source code and samples are also available on the ASP.NET CodePlex workspace.

Overall, this new version doesn’t have many changes in the area of development and tooling, but there has been improvement for deploying ASP.NET MVC applications.  The setup process now requires .NET 3.5 SP1 to be installed, where in the past it was optional because the additional assemblies where included with the install.

Don’t worry though /bin deployment is still supported, they are not taking a runtime dependency on SP1 other than our existing dependency on System.Web.Routing.dll and System.Web.Abstractions.dll. Thus you can still bin deploy your application to a hosting provider who has .NET 3.5 installed without SP1 by following these instructions.

They are also adding an option to the installer that enables installing on a server that does not have Visual Studio at all on the machine, which is useful for production servers and hosting providers.  To do a server install you just need to run the following command to install MVC on your server.

msiexec /i AspNetMvc-setup.msi /q /l*v .\mvc.log MVC_SERVER_INSTALL="YES"

Also because of the latest breaking changes from Beta to RC 1 & 2, we are taking the time between now and the final release of the MVC Framework to work on the book and make sure all the loose ends are tied up.

I also got noticed today that our final cover design is done.  So we are in the final stretch of this book.  The cover hasn’t been uploaded to Amazon yet, but if you are interested in pre-ordering a copy just click on the cover image to your right and it will take you to the Amazon page where you can place your order.

Tags: , ,

Posted in ASP.NET, News, Personal, Portfolio, Review, SQL | kick it on DotNetKicks.com | Bookmark | View blog reactions | 2 Comments »

February 3rd, 2009

A potentially dangerous Request.Form value was detected in ASP.NET MVC

If you are getting something like the following error message in ASP.NET MVC:

A potentially dangerous Request.Form value was detected from the client (Description=”<p>some HTML text</p>”)

This is because of something called Request Validation, that is a feature put in place to protect your application cross site scripting attacks, as described in a White Paper on ASP.NET:

Many sites are not aware that they are open to simple script injection attacks. Whether the purpose of these attacks is to deface the site by displaying HTML, or to potentially execute client script to redirect the user to a hacker’s site, script injection attacks are a problem that Web developers must contend with.

Script injection attacks are a concern of all web developers, whether they are using ASP.NET, ASP, or other web development technologies.

The ASP.NET request validation feature proactively prevents these attacks by not allowing unencoded HTML content to be processed by the server unless the developer decides to allow that content.

You need to add the following to your action method:

[ValidateInput(false)]
public ActionResult MyAction (int id, string content) {
    // ...
}

This is a new feature that was added to ASP.NET MVC RC1 and it will turn off request validation for this action and this action only. However you need to take special precautions to double check your content for script tags, which may indicate a cross site scripting attack. And if you find one make sure to do a simple replace that will render it harmless, such as:

content = content.Replace("<script", "[script").Replace("</script>","[/script]");

The above is not the most bullet proof code, but if you are using the ValidateInputAttribute on your action make sure to do a quick search on XSS or Cross Site Scripting and become familiar with the basics of this kind of attack.

Tags: ,

Posted in ASP.NET | kick it on DotNetKicks.com | Bookmark | View blog reactions | 23 Comments »