August 6, 2012 07:14 by
Scott
ASP.NET MVC 4 was released in beta by the Microsoft ASP.NET MVC Developer Team and it comes with a number of really cool features: Bundling and Minification Support of CSS and JavaScript, Database Migrations using Entity Framework 4.3, Web APIs, Mobile Web with support for jQuery Mobile, Real Time Communication via SignalR, and Asynchronous Support. The Database Migrations using Entity Framework Code-First is really cool and is very much like Rails where you can change your code and then via Package Manager add migrations and update your database as your code evolves. Because the EF Migration Files and Configuration get added to your Visual Studio Solution, all the database migration changes get added to source code.
ASP.NET MVC 4 and Entity Framework Code-First
ASP.NET MVC support for EF Code-First has been there since ASP.NET MVC 3. To jump start playing with Database Migrations start an empty ASP.NET MVC 4 Project and use Package Manager to install or update Entity Framework to the latest version that includes Database Migrations.
Install-Package EntityFramework
Add a simple Product Class that represents a product in your E-Commerce Website. Let's intially make Product simple by just providing an Id and Title to it.
public class Product {
public int Id { get; set; }
publis string Title { get; set; }
}
Run the Add Controller Recipe in ASP.NET MVC 4 to add a Products Controller that uses Entity Framework to read/write to the Database of your E-Commerce Website.
Once the Add Controller Recipe is finished you will have a working ASP.NET MVC 4 Website that reads and writes products to the Database using Entity Framework. The ProductsController was created along with all actions and views that display, create, update, and delete products.
Enable Database Migrations to ASP.NET MVC 4 Website
Now we want to enable database migrations to ASP.NET MVC 4 by using the Package Manager Console.
Enable-Migrations
Enabling database migrations creates a new Migrations Folder in your Visual Studio Solution as well as an InitialCreate Target Migration that has both an Up and Down Migration. The Up Migration creates the Products Table while the Down Migration drops the Products Table.
public partial class InitialCreate : DbMigration {
public override void Up() {
CreateTable(
"Products",
c => new
{
Id = c.Int(nullable: false, identity: true),
Title = c.String(),
})
.PrimaryKey(t => t.Id);
);
}
public override void Down() {
DropTable("Products");
}
}
Add New Database Migration to ASP.NET MVC 4 Website
Now let's say we want to add more properties to the Product Class as well as make Title a Required Property and a length of 255 characters.
public class Product {
public int Id { get; set; }
[Required,MaxLength(255)]
public string Title { get; set; }
public string Description { get; set; }
public decimal Price { get; set; }
}
One can now add a data migration as well as update the database via the Package Manager Console.
Add-Migration AddDescriptionPriceToProduct
Update-Database
The Add-Migration command creates another file in the Migrations Folder of our ASP.NET MVC 4 Project and the Update-Database command updates the database with the new Description and Price Columns as well as modifies the Title Column to be only 255 characters and not nullable.
If you look at the ASP.NET MVC 4 Database before and after issuing this Database Migration you will notice the effect.
And, of course, the new Database Migration File has the approprite Up and Down Methods.
public partial class AddDescriptionPriceToProduct : DbMigration {
public override void Up() {
AddColumn("Products", "Description", c => c.String());
AddColumn("Products", "Price",
c => c.Decimal(nullable: false, precision: 18, scale: 2));
AlterColumn("Products", "Title",
c => c.String(nullable: false, maxLength: 255));
}
public override void Down() {
AlterColumn("Products", "Title", c => c.String());
DropColumn("Products", "Price");
DropColumn("Products", "Description");
}
}
Conclusion
If you are a Rails Developer moving to ASP.NET MVC 4, you will find the Database Migrations support in Entity Framework a nice addition to the tooling. And, of course, those ASP.NET MVC 4 Developers that love Code-First Development with Entity Framework will love the new Database Migrations support in EF 4.3. Don't forget to check out other ASP.NET MVC 4 Features such as bundling and minification of CSS and JavaScript, Web API's, Asynchronous Support, and the mobile web templates. ASP.NET MVC 4 is still in beta at this point, but it has a go-live license.
June 19, 2012 07:11 by
Scott
ASP.NET MVC 4.0 has two great features: One is Display Mode allows you to create mobile-specific and desktop-specific views and Second is Web API platform for building RESTful applications. Sometimes, You might need to return different data or perform different operations for desktop and mobile request. This article explains how to implement separate actions for mobile request keeping same URL format in Web API.
1. In Visual Studio, Select File > New Project > ASP.NET MVC 4 Web Application > Enter name > OK
2. Select ‘Web API‘ > View Engine: ‘Razor‘ > OK
3. You’ll get default ValuesController. When you access <your app url>/api/Values, the array of string value1, value2 is returned.
To create separate action for mobile request, We are going to create separate controller having ‘Mobile‘ suffix.
Right Click on ‘Controllers‘ folder > Add Controller > Give Name ‘ValuesMobileController‘ > Template: ‘API Controller with empty read/write actions‘ > Add
To differentiate both controllers, replace value1, value2 to mobile-value1, mobile-value2 in get method.
4. Now our object is to call action of Mobile controller when request comes from mobile device.
In Global.asax:
default api route:
routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
Change it to
routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
).RouteHandler = new MyRouteHandler();
and add following class:
public class MyRouteHandler : HttpControllerRouteHandler
{
protected override IHttpHandler GetHttpHandler(RequestContext requestContext)
{
//Check whether request comes from mobile browser
if (requestContext.HttpContext.Request.Browser.IsMobileDevice)
{
string controller = requestContext.RouteData.Values["controller"].ToString();
requestContext.RouteData.Values["controller"] = controller + "Mobile";
}
return new MyHttpControllerHandler(requestContext.RouteData);
}
}
public class MyHttpControllerHandler : HttpControllerHandler, IRequiresSessionState
{
public MyHttpControllerHandler(RouteData routeData)
: base(routeData)
{
}
}
You have to import following namespaces:
using System.Web.Http.WebHost;
using System.Web.SessionState;
In this RouteHandler, Request.Browser.IsMobileDevice checks whether request comes from mobile browser and change controller name with ‘Mobile‘ suffix.
Now run app on browser, For testing, You can change user-agent to iPhone with user agent switcher Firefox add-on and open same URL. you’ll get mobile-value1 and mobile-value2.
Hope it helps
June 4, 2012 08:29 by
Scott
Please see the previous post at here.
Once I removed all the TasksController files and the TodoItem, I chose the Models folder, right click and “Add New Item” and searched for “ADO.NET Entity Model” and added it to the folder.
It allowed me to connect to the Northwind database through “Generate from database” and I selected just three tables “Products”, “Categories” and “Suppliers” table for simplicity. At the end of the wizard, we get a EDMX design file with the 3 tables. On this screen I right clicked and choose “Add Code Generation Item” as below
and then in the dialog that came up, chose the “ADO.NET DbContext Generator” and Added (note, if you don’t see this template, you probably don’t have Entity Framework 4.1 installed)
This step created the Model1.Context (not required for us though) and the Model1.tt template which groups the individual class files for each of the tables above (these are required)
The next thing I did, was to remove the NorthwindEntities connectionstring that got automatically added when we followed the ADO.NET Entity Model wizard. We don’t need this connection string.
Also, I deleted the Model1.Context file and also the Model1.cs files which are not required (we will be generating a new context to suit our database name)
Note that these files are not required only for our SPA approach here and they are required when working with EF CodeFirst normally as they do the DbSet Tracking and whole bunch of things
So, we now have the basic model classes required for wiring up our Controller required to create the SPA Pages. One important thing I learnt in this process was that, I had to edit the Model classes as follows:-
In Supplier.cs added the “private” keyword to the ICollection<Products> property. Same is the case with Category.cs. Otherwise you would run into an error explained here.
After this, I added Controller for Products as per the settings below (Right Click Controller – Add –Controller)
Note several important things. I have chosen the “Single Page Application with read/write actions and views, using Entity Framework” template under Scaffolding options. Also, I have edited the Data context class and made it simply MvcApplication126.Models.Northwind. This would be referenced in the web.config connection string as well so that SPA picks up our existing Northwind database instead of creating a new one.
Once you click “Add” the following files are generated.
Under Controllers
- NorthwindController.cs
- NorthwindController.Product.cs
- ProductsController.cs
Under Scripts
- ProductsviewModel.js
Under Views
- Products folder and the Views and Partial Views required
Repeat the steps for adding Controllers for “Categories” and “Suppliers” and the only change would be the respective Model Classes.
One important thing to do is to add the following connectionstring to the web.config file
<add name="Northwind" connectionString="Data Source=SERVERNAME;Initial Catalog=Northwind;User Id=YOUR USER NAME;Password=YOUR PASSWORD" providerName="System.Data.SqlClient" />
Then, when you run the project, it opens up the default Home Page.
- Navigate to /Products and it should load the list of Products from Northwind database.
- Click on each product and edit and note that everything happens in a single page inline.
- Just notice the URLs change in pattern with hash tags.
- Notice that the Categories and Suppliers are wired up as dropdownlists since these are foreign key references.
- Notice that all the items load asynchronously
I went ahead and edited the Shared –> Layout.cshtml under Views folder to add Menu Items for Products, Categories and Suppliers, as below:-
<ul id="menu">
<li>@Html.ActionLink("Home", "Index", "Home")</li>
<li>@Html.ActionLink("Products", "Index", "Products")</li>
<li>@Html.ActionLink("Categories", "Index", "Categories")</li>
<li>@Html.ActionLink("Suppliers", "Index", "Suppliers")</li>
<li>@Html.ActionLink("About", "About", "Home")</li>
<li>@Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>
Now, we have our full blown Northwind Traders Application running as a SPA.
You can download the sample from https://skydrive.live.com/redir.aspx?cid=069f94a102eff49a&resid=69F94A102EFF49A!919&parid=root
May 30, 2012 06:42 by
Scott
Single Page Application Frameworks are gaining popularity in the ever evolving web community with lot of libraries such as JavaScriptMVC, Backbonejs and many other libraries. ASP.NET MVC 4 introduces experimental support for building single page application (SPA) through a template. Much of the plumbing work of wiring up the client side scripts, javascript modelviews and the controllers is automated, making it a quick start to develop SPAs relatively easier. Lets examine a scenario where we are building a Northwind Store using SPA.
I installed the ASP.NET MVC 4 Beta for Visual Studio 2010 and the Northwind Sample Database for SQL Server
Post that I did a “File – New Project – ASP.NET MVC 4 Web Application”
In MVC 3 we are used to see a screen with 3 options i.e. Intranet, Internet and Empty templates. In MVC 4 we have additional templates as you can see below and I chose the “Single Page Application” template and created the project template.
In MVC 3 we are used to see a screen with 3 options i.e. Intranet, Internet and Empty templates. In MVC 4 we have additional templates as you can see below and I chose the “Single Page Application” template and created the project template.
Next, the important folder is the Scripts folder and there I found that it creates a <Modelname>ViewModel.js file that holds all the observer pattern script required. In addition, this folder contains a truckload of JavaScript files including jQuery, Knockout, upshot and modernizr.
Finally, inside the “Views” folder, it creates the necessary Partial Views and Index View for Tasks. Once you build and run, you can experience all of this SPA for your TodoItem Model without having written a single line of JavaScript code yet.
So, you learn
1. The ContextName that you select when creating the TasksConroller (inour case it is MVCApplication126Context)is important for you to work with other Databases. By default when you run this solution, Visual Studio would create a SQL Express Database in C:\Program Files\Microsoft SQL Server\MSSQL10.SQLEXPRESS\MSSQL\DATA folder with the name MVCApplication126Context.
The way I see the SPA framework identifies is, if you don’t have a connectionstring by the name of the Context, it defaults to creating a database in SQL Express with the ContextName in the above mentioned path.
If you have a connectionstring mentioned with the same contextname, it tries and uses that Database (SQL Express, SQL Server). However, when you are running for the first time, if you create a Database and point it in the connectionstring, it would expect that the Table (mapped to the model i.e. TodoItems) need to exist. Otherwise, it throws an exception. So best, is to either use a Model for which there is a Table that already exists in the Database or provide a new Database name in which case, VS would create the Database with the TodoItems Table as well. There must be someplace to configure all of these, but for the lack of time I didn’t delve deep into these things for now.
So, coming to our Northwind Sample. Northwind has been Developers’ best friend to experiment new things and the saga continues here.
I had to do a couple of things though. First I removed the TodoItem.cs class and also removed the TasksController, Views since we don’t need them. So, for all practical purposes, it is now a plain MVC 4 Application with the default Home & Account Controllers and their respective Views. I also removed the Contextfiles created inside the Controllers Folder.
A bit of analogy on how I built this Northwind App before I explain the actual steps.
The TodoItem is a simple class file and can be hand wired. However, in real world, or for that matter, a simple Northwind database table has a lot of columns and hence properties to be wired up. Also, it requires to map foreign relationships and other things. So, I decided to use the ADO.NET Entity Data Model first to create a model class for the Northwind Database. This would help me in generating DbContext classes using EF CodeFirst Template, which are much simpler than the complex EDMX file that is created by the ADO.NET Entity Model. Thereafter, I can use the class files generated to create the Controller, View and JS ViewModels.
May 25, 2012 06:47 by
Scott
This blog post shows how to validate models containing complex types such as Objects and Lists in ASP.NET MVC 3.
In a first step we modify the properties of the model ( Models/ValidationModel.cs) and add some complex types:
public class ValidUserNameAttribue : ValidationAttribute
{
public override bool IsValid(object value)
{
return (value != null && value.ToString() == "Bob");
}
}
public class User
{
[Required]
[StringLength(8, MinimumLength = 3)]
[ValidUserNameAttribue(ErrorMessage = "User name != 'Bob'")]
[Display(Name = "User name")]
public string UserName { get; set; }
[Required]
[StringLength(8, MinimumLength = 3)]
[Display(Name = "Display name")]
public string DisplayName { get; set; }
}
public class ValidationModel
{
public User User { get; set; }
public List Users { get; set; }
}
In a second step we modify the form ( Views\Home\Partial\_Form.cshtml) to add input element for the new model properties:
@model MVC3_Ajax_Form_jQuery_Validation.Models.ValidationModel
@DateTime.Now: Partial/_Form.cshtml rendered
< hr/>
@using (Html.BeginForm("Form", "Home"))
{
<h1><em>User</em> object</h1>
<p>
@Html.LabelFor(m => m.User.UserName):
@Html.EditorFor(m => m.User.UserName)
@Html.ValidationMessageFor(m => m.User.UserName)
</p>
<p>
@Html.LabelFor(m => m.User.DisplayName):
@Html.EditorFor(m => m.User.DisplayName)
@Html.ValidationMessageFor(m => m.User.DisplayName)
</p>
<h1>List of <em>User</em> objects</h1>
for (var i = 0; i <= 1; i++)
{
<h2>User @i</h2>
<p>
@Html.LabelFor(m => m.Users[i].UserName):
@Html.EditorFor(m => m.Users[i].UserName)
@Html.ValidationMessageFor(m => m.Users[i].UserName)
</p>
<p>
@Html.LabelFor(m => m.Users[i].DisplayName):
@Html.EditorFor(m => m.Users[i].DisplayName)
@Html.ValidationMessageFor(m => m.Users[i].DisplayName)
</p>
}
<input type="submit" value="Submit" />
}
In a last step we adapt the “success-view” ( Views\Home\Partial\_Success.cshtml) that is shown after the data have been successfully validated on the server side:
@model MVC3_Ajax_Form_jQuery_Validation.Models.ValidationModel
< p><strong>Model is valid :)</strong></p>
< p>
Model.User.Username: '@Model.User.UserName'<br />
Model.User.DisplayName: '@Model.User.DisplayName'<br />
Model.Users[0].Username: '@Model.Users[0].UserName'<br />
Model.Users[0].DisplayName: '@Model.Users[0].DisplayName'<br />
Model.Users[1].Username: '@Model.Users[1].UserName'<br />
Model.Users[1].DisplayName: '@Model.Users[1].DisplayName'
</ p>
As you can see in the source code above, there is no magic; model binding and validation of complex objects and lists work out of the box in ASP.NET MVC 3.
April 23, 2012 07:42 by
Scott
HostForLIFE.eu was established to cater to an under served market in the hosting industry; web hosting for customers who want excellent service. HostForLIFE.eu – a cheap, constant uptime, excellent customer service, quality, and also reliable hosting provider in advanced Windows and ASP.NET technology. We proudly announces the availability of the SQL 2012 hosting in our entire servers environment. HostForLife customer can choose SQL 2012 when creating a database from inside HostForLife hosting control panel.
The first new option is Windows SQL Server 2012, which is available to customers from today. With the public release just last week of Microsoft’s latest version of their premier database product, HostForLife has been quick to respond with updated their shared server configurations. SQL Server 2012 Web Edition is available for the same low monthly rental price as the previous SQL 2008, as well as Express Edition, which is a basic version of Microsoft’s SQL Database product, available for free.
“We’re proud to be at the cutting edge for new technologies. With these additions, customers have the option to explore these new products in the safe environment of their own shared server. Developers and IT Managers can research the potential impact of next-generation software without risking current infrastructure. With Microsoft’s announcement of the general availability of their new SQL server, we are proud to launch SQL 2012 hosting along with a suite of SQL 2012 management tools." Said John Curtis, VP Marketing and Business Development at HostForLIFE.eu.
John added, “It’s very important to our customers that we support their current deployments; we want to make sure that our customers have their good opportunity to test this new technology."
“HostForLIFE customers can now take advantage of SQL Server 2012’s advanced BI capabilities, We’re excited to see the benefits of this release add value to the energy management and manufacturing arena. Ensuring compatibility with Microsoft’s new SQL Server 2012 demonstrates how HostForLife and Microsoft remain committed together to providing leading edge technology for the benefit of our shared customers." Said CEO of HostForLIFE.eu, Anthony Johnson.
For more information about this new product, please visit http://www.hostforlife.eu/SQL-2012-European-Hosting.aspx.
About us:
We are European Windows Hosting Provider which FOCUS in Windows Platform ONLY. We support Microsoft technology, such as the latest ASP.NET 4, ASP.NET MVC 3, SQL 2008/2008 R2, and much more.
Our number one goal is constant uptime. Our data center uses cutting edge technology, processes, and equipment. We have one of the best up time reputations in the industry.
Our second goal is providing excellent customer service. Our technical management structure is headed by professionals who have been in the industry since it's inception. We have customers from around the globe, spread across every continent. We serve the hosting needs of the business and professional, government and nonprofit, entertainment and personal use market segments.
April 6, 2012 05:09 by
Scott
This is the second article focusing on the new additions to ASP.NET MVC 4. Today’s article will focus on using Display Modes. This selects a view depending on the browser making the request, which means you can target specific devices and give the user a truly rich experience.
Before getting started, you should read the first article in this series on ASP.NET MVC 4 Developer Preview.
Installation
Before undertaking any development, you’ll need to install the MVC 4 builds. The simplest way to do this is via the Web Platform Installer. MVC 4 is available for Visual Studio 2010 or Visual Studio 2011 Developer Preview.
All of the MVC articles I’m authoring are developed in Visual Studio 2011 Developer Preview. Below are the links to get started.
- ASP.NET MVC 4 for Visual Studio 2010
- ASP.NET MVC 4 for Visual Studio 2011 Developer Preview
Default Mobile Views in MVC 4
It’s important to understand a new feature in MVC 4. By default, if you add a .mobile.cshtml view to a folder, that view will be rendered by mobile and tablet devices.
This is a nice feature, but if you want to target specific devices, such as the iPhone, iPad or Windows Phone, you can use Display Modes.
To do this, you need to register a new DefaultDisplayMode instance to specify which name to search for when a request meets the condition. You set this in the global.asax file in the Application_Start event. Here’s how to specify a display mode for an iPhone.
protected void Application_Start()
{
DisplayModes.Modes.Insert(0, new DefaultDisplayMode("iPhone")
{
ContextCondition = (context =>context.Request.UserAgent.IndexOf
("iPhone", StringComparison.OrdinalIgnoreCase) >= 0)
});
}
To consume views that meet this condition, you create a view but change the extension to .iPhone.cshtml. Likewise if you want to target an iPad, create an iPad instance.
DisplayModes.Modes.Insert(0, new DefaultDisplayMode("iPad")
{
ContextCondition = (context =>context.Request.UserAgent.IndexOf
("iPad", StringComparison.OrdinalIgnoreCase) >= 0)
});
Basically, Display Modes checks the User Agent. If it finds a matching suffix, it will display any view it finds that matches the suffix. The suffix is the parameter that’s passed to the DefaultDisplayMode method. To see this in action, I’ve created a Home controller and added three views to the Home folder.
The differences between the views is the H1 heading. They’ll display iPhone, iPad or Desktop depending on the device. I’m also displaying the User Agent so you can see it changing. First I’ll debug the website through my desktop browser. You can see the desktop specific page being served.
Now navigate to the website using an iPhone. You’ll see the iPhone specific page being served.
Switching over to an iPad, you’ll see the iPad specific page being served.
This is a simple way to target specific devices, producing a view that suits the device – and thus the user.
Testing with Emulators
To test these new features, you can either use a physical iPhone or iPad, or you can use an emulator. The emulator I was using is from MobiOne. You can download a 15 day free trial here.
The Windows Phone RC emulator is free and can be downloaded here.
Likewise another good option is the User Agent Switcher add-on for Firefox, which changes the user agent that’s sent to the browser. That can be downloaded here.
Do you want to test new ASP.NET MVC 4 hosting for FREE??? Please visit our site at http://www.hostforlife.eu/ASPNET-45-Beta-European-Hosting.aspx.
April 5, 2012 09:59 by
Scott
Microsoft is ramping up the release cycles of some of its products, and the phenomenal rate at which the ASP.NET MVC framework is being updated is testament to that.
The latest version, MVC 4 Developer Preview, has some cool new additions to its armory. Over the next few weeks, I’ll be taking a look at some of the features new to the framework, and how you might use these in your website.
The more noticeable features added to the framework include:
- Mobile project templates
- Display modes
- Recipes
- Task support for Asynchronous controllers
- Azure SDK
- Bug fixes
Installation
Before undertaking any development, you’ll need to install the MVC 4 builds. The simplest way to do this is via the Web Platform Installer. MVC 4 is available for Visual Studio 2010 or Visual Studio 2011 Developer Preview. All of the MVC articles I’m authoring are developed in Visual Studio 2011 Developer Preview. Below are the links to get started.
- ASP.NET MVC 4 for Visual Studio 2010
- ASP.NET MVC 4 for Visual Studio 2011 Developer Preview
Task Support for Asynchronous Controllers
The feature I’m going to be focusing on today is task support for asynchronous controllers.
Nobody likes to wait, so why should your users wait for a long-running asynchronous task? It doesn’t make sense!
Developing asynchronous controllers has been available since MVC 3, but for this to work you had to write a bunch of extra code – what I like to refer to as code noise – to get it to work.
Take the example of integrating Twitter into a webpage. In MVC 3, the code needed to follow specific rules. Instead of there being one action method, there had to be two action methods. Both were named the same, but for the method beginning the asynchronous request, you needed to append Async to the action name. For the method handling the ending of the asynchronous request, you needed to append Completed to the action name.
It’s much easier to follow if you see some code. The sample code below requests data from Twitter asynchronously.
public void SearchTwitterAsync()
{
const string url = "http://search.twitter.com/search.atom?q=guycode&rpp=100&result_type=mixed";
// the asynchronous operation is declared
AsyncManager.OutstandingOperations.Increment();
var webClient = new WebClient();
webClient.DownloadStringCompleted += (sender, e) =>
{
AsyncManager.Parameters["results"] = e.Result;
AsyncManager.OutstandingOperations.Decrement();
};
webClient.DownloadStringAsync(new Uri(url)); //the asynchronous process is launched
}
public ActionResult SearchTwitterCompleted(string results)
{
// Now return the twitter results to the client
return Json(ReadTwitterResults(results), JsonRequestBehavior.AllowGet);
}
The code above is going off to Twitter, searching for data and returning the results asynchronously. There’s a lot of code noise in there and to me, it’s violating – for want of a better word – the Don’t Repeat Yourself (DRY) principle.
Well, in MVC 4, these tasks have been rolled into one. You can now write asynchronous action methods as single methods that return an object of type Task or Task<ActionResult>.
These features are only available in MVC 4 or C# 5. Here’s the simplified code below.
public async Task<ActionResult> Search()
{
string url = "http://search.twitter.com/search.atom?q=guycode&rpp=100&result_type=mixed";
var webClient = new WebClient();
string xmlResult = await webClient.DownloadStringTaskAsync(url);
return Json(ReadTwitterResults(xmlResult), JsonRequestBehavior.AllowGet);
}
The results are the same, but now you can reduce the amount of code you need to accomplish the same outcome.
Asynchronous action methods that return Task instances can also support timeouts. To set a time limit for your action method, you can use the AsyncTimeout attribute. The following example shows an asynchronous action method that has a timeout of 2500 milliseconds. Once it has timed out, the view “TimedOut” will be displayed to the user.
[AsyncTimeout(2500)]
[HandleError(ExceptionType = typeof(TaskCanceledException), View = "TimedOut")]
public async Task<ActionResult> Search()
{
string url = "http://search.twitter.com/search.atom?q=guycode&rpp=100&result_type=mixed";
var webClient = new WebClient();
string xmlResult = await webClient.DownloadStringTaskAsync(url);
return Json(ReadTwitterResults(xmlResult), JsonRequestBehavior.AllowGet);
}
Nothing else has changed with asynchronous actions.
The controller still needs to derive from AsyncController, and you still access the action in the same way but you have to write less code.
Asynchronous controllers are perfect for pieces of code that run to great length. Most of the time you’ll be working with a database, so being able to make calls to the database asynchronously is a big plus for the end user.
Why should they wait?
Test drive for NEW ASP.NET MVC 4 for FREE, please visit our site at http://www.hostforlife.eu/ASPNET-45-Beta-European-Hosting.aspx.
March 26, 2012 07:51 by
Scott
In this post, I will show you three new functionalities brought by MVC4 for mobile websites.
- The mobile Application Template
- The View Switcher
- The Display mode by Browser type
Smartphone and tablet are able to read websites not optimized for tiny screen but if a user can jump automatically on an optimized version of the website, it’s better for everyone!
One interesting feature of this new version of the ASP.NET MVC framework 4 is the new Mobile Application template. With this template you’ll be able to develop quickly a website especially for mobile and tablet.
1 – Create a full-mobile Website
In Visual Studio, Create a new MVC4 project and select the “Mobile Application” template.
I consider that you’ve already develop a classic MVC application. If true, you will not be surprised by the generated project. It’s almost the same as a classic MVC desktop website.
So what the difference?
In the “content” folder you will find another JavaScript library: jQuery Mobile. ASP.NET MVC4 Mobile Template is based on the famous JavaScript framework for mobile application. You can learn a lot if you visit the jQuery mobile website.
Models and Controller are similar to a classic MVC Application.
In the view, you just have to add some tag to tell how jQuery mobile needs to display the page.
If we take a look at this code (Menu of the website generated by MVC4), you will probably recognize the Razor syntax. Nothing change when you want to develop Mobile Application with MVC4. You just have to use special attribute in your HTML.
Here, we declare a classic HTML list….and jQuery Mobile will transform it into an accessible list for mobile devices user.
<ul data-role="listview" data-inset="true">
<li data-role="list-divider">Navigation</li>
<li>@Html.ActionLink("About", "About", "Home")</li>
<li>@Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>
March 22, 2012 06:56 by
Scott
In this blog post I will show how to set up custom error pages in ASP.NET MVC 3 applications to create user-friendly error messages instead of the (yellow) IIS default error pages for both “normal” (non-AJAX) requests and jQuery AJAX requests.
In this showcase we will implement custom error pages to handle the HTTP error codes 404 (“Not Found”) and 500 (“Internal server error”) which I think are the most common errors that could occur in web applications. In a first step we will set up the custom error pages to handle errors occurring in “normal” non-AJAX requests and in a second step we add a little JavaScript jQuery code that handles jQuery AJAX errors.
We start with a new (empty) ASP.NET MVC 3 project and activate custom errors in the Web.config by adding the following lines under <system.web>:
<customErrors mode="On" defaultRedirect="/Error">
<error redirect="/Error/NotFound" statusCode="404"/>
<error redirect="/Error/InternalServerError" statusCode="500"/>
</customErrors>
Note: You can set mode=”Off” to disable custom errors which could be helpful while developing or debugging. Setting mode=”RemoteOnly” activates custom errors only for remote clients, i.e. disables custom errors when accessing via http://localhost/[...]. In this example setting mode=”On” is fine since we want to test our custom errors. You can find more information about the <customErrors> element here.
In a next step we remove the following line in Global.asax.cs file:
filters.Add(new HandleErrorAttribute());
and add a new ErrorController (Controllers/ErrorController.cs):
public class ErrorController : Controller
{
public ActionResult Index()
{
return InternalServerError();
}
public ActionResult NotFound()
{
Response.TrySkipIisCustomErrors = true;
Response.StatusCode = (int)HttpStatusCode.NotFound;
return View("NotFound");
}
public ActionResult InternalServerError()
{
Response.TrySkipIisCustomErrors = true;
Response.StatusCode = (int)HttpStatusCode.InternalServerError;
return View("InternalServerError");
}
}
In a last step we add the ErrorController‘s views (Views/Error/NotFound.cshtml and Views/Error/InternalServerError.cshtml) that defines the (error) pages the end user will see in case of an error. The views include a partial view defined in Views/Shared/Error/NotFoundInfo.cshtml respectively Views/Shared/Error/InternalServerErrorInfo.cshtml that contains the concrete error messages. As we will see below using these partial views enables us to reuse the same error messages to handle AJAX errors.
Views/Error/NotFound.cshtml:
@{
ViewBag.Title = "Not found";
}
@{
Html.RenderPartial("Error/NotFoundInfo");
}
Views/Shared/Error/NotFoundInfo.cshtml:
The URL you have requested was not found.
Views/Error/InternalServerError.cshtml:
@{
ViewBag.Title = "Internal server error";
}
@{
Html.RenderPartial("Error/InternalServerErrorInfo");
}
Views/Shared/Error/InternalServerErrorInfo.cshtml:
An internal Server error occured.
To handle errors occurring in (jQuery) AJAX calls we will use jQuery UI to show a dialog containing the error messages. In order to include jQuery UI we need to add two lines to Views/Shared/_Layout.cshtml:
<link href="@Url.Content("~/Content/themes/base/jquery.ui.all.css")" rel="stylesheet" type="text/css" />
<script src="@Url.Content("~/Scripts/jquery-ui-1.8.11.min.js")" type="text/javascript"></script>
Moreover we add the following jQuery JavaScript code (defining the global AJAX error handling) and the Razor snippet (defining the dialog containers) to Views/Shared/_Layout.cshtml:
< script type="text/javascript">
$(function () {
// Initialize dialogs ...
var dialogOptions = {
autoOpen: false,
draggable: false,
modal: true,
resizable: false,
title: "Error",
closeOnEscape: false,
open: function () { $(".ui-dialog-titlebar-close").hide(); }, // Hide close button
buttons: [{
text: "Close",
click: function () { $(this).dialog("close"); }
}]
};
$("#InternalServerErrorDialog").dialog(dialogOptions);
$("#NotFoundInfoDialog").dialog(dialogOptions);
// Set up AJAX error handling ...
$(document).ajaxError(function (event, jqXHR, ajaxSettings, thrownError)
{
if (jqXHR.status == 404) {
$("#NotFoundInfoDialog").dialog("open");
} else if (jqXHR.status == 500) {
$("#InternalServerErrorDialog").dialog("open");
} else {
alert("Something unexpected happend :( ...");
}
});
});
</ script>
<div id="NotFoundInfoDialog">
@{ Html.RenderPartial("Error/NotFoundInfo"); }
</div>
<div id="InternalServerErrorDialog">
@{ Html.RenderPartial("Error/InternalServerErrorInfo"); }
</div>
As you can see in the Razor snippet above we reuse the error texts defined in the partial views saved in Views/Shared/Error/.
To test our custom errors we define the HomeController (Controllers/HomeController.cs) as follows:
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult Error500()
{
throw new Exception();
}
}
and the corresponding view Views/Home/Index.cshtml:
@{
ViewBag.Title = "ViewPage1";
}
<script type="text/javascript">
$function () {
$("a.ajax").click(function (event) {
event.preventDefault();
$.ajax({
url: $(this).attr('href'),
});
});
});
</script>
<ul>
<li>@Html.ActionLink("Error 404 (Not Found)", "Error404")</li>
<li>@Html.ActionLink("Error 404 (Not Found) [AJAX]", "Error404", new { },
new { Class = "ajax" })</li>
<li>@Html.ActionLink("Error 500 (Internal Server Error)", "Error500")</li>
<li>@Html.ActionLink("Error 500 (Internal Server Error) [AJAX]", "Error500", new { }, new { Class = "ajax" })</li>
</ul>
To test the custom errors you can launch the project and click one of the four links defined in the view above. The “AJAX links” should open a dialog containing the error message and the “non-AJAX” links should redirect to a new page showing the same error message.
Summarized this blog post shows how to set up custom errors that handle errors occurring in both AJAX requests and “non-AJAX” requests. Depending on the project, one could customize the example code shown above to handle other HTTP errors as well or to show more customized error messages or dialogs.