ASP.NET MVC 6 Tutorial :: Creating Routes With ASP.NET MVC 6

ASP.NET MVC 6 Tutorial | When using MVC 6, you don’t create your Route collection yourself. So in this tutorial, I will show you how to create routes with ASP.NET MVC 6.

You let MVC create the route collection for you. And now, write the following code:

using Microsoft.AspNet.Builder;
using Microsoft.Framework.DependencyInjection;
namespace RoutePlay
{
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
}
public void Configure(IApplicationBuilder app)
{
app.UseMvc();
}
}
}

The ConfigureServices() method is utilized to enroll MVC with the Dependency Injection framework built into ASP.NET 5. The Configure() system is utilized to register MVC with OWIN. This is what my MVC 6 ProductsController resembles:

Notice that I have not configured any routes. I have not utilized either tradition based or property based directing, yet I don’t have to do this. If I enter the request “/products/index” into my browser address bar then I get the response “It Works!”:

When you calling the ApplicationBuilder.UseMvc() in the Startup class, the MVC framework will add routes for you automatically. The following code will show you, what the framework code for the UseMvc() method looks like:

public static IApplicationBuilder UseMvc([NotNull] this IApplicationBuilder app)
{
return app.UseMvc(routes =>
{
});
}
public static IApplicationBuilder UseMvc(
[NotNull] this IApplicationBuilder app,
[NotNull] Action<IRouteBuilder> configureRoutes)
{
// Verify if AddMvc was done before calling UseMvc
// We use the MvcMarkerService to make sure if all the services were added. MvcServicesHelper.ThrowIfMvcNotRegistered(app.ApplicationServices);
var routes = new RouteBuilder
{
DefaultHandler = new MvcRouteHandler(),
ServiceProvider = app.ApplicationServices
};
configureRoutes(routes);
// Adding the attribute route comes after running the user-code because
// we want to respect any changes to the DefaultHandler.
routes.Routes.Insert(0, AttributeRouting.CreateAttributeMegaRoute(
routes.DefaultHandler,
app.ApplicationServices));
return app.UseRouter(routes.Build());
}

The AttributeRouting.CreateAttributeMegaRoute() does all of the heavy-lifting here (the word “Mega” in its name is very appropriate). The CreateAttributeMegaRoute() method iterates through all of your MVC controller actions and builds routes for you automatically. Now, you can use convention-based routing with ASP.NET MVC 6 by defining the routes in your project’s Startup class. And here is the example code:

using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Routing;
using Microsoft.Framework.DependencyInjection;
namespace RoutePlay
{
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
}
public void Configure(IApplicationBuilder app)
{
app.UseMvc(routes =>
{
// route1
routes.MapRoute(
name: "route1",
template: "super",
defaults: new { controller = "Products", action = "Index" }
);
// route2
routes.MapRoute(
name: "route2",
template: "awesome",
defaults: new { controller = "Products", action = "Index" }
);
});
}
}
}

I hope this tutorial works for you!

HostForLIFE.eu ASP.NET MVC 6 Hosting
HostForLIFE.eu is European Windows Hosting Provider which focuses on Windows Platform only. We deliver on-demand hosting solutions including Shared hosting, Reseller Hosting, Cloud Hosting, Dedicated Servers, and IT as a Service for companies of all sizes. 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.

OWIN and Katana Hosting – Unlimited Hosting For LIFE

OWIN and Katana Hosting – The ASP.NET Framework has been around for over ten years, and the platform has enabled the development of countless Web sites and services. As Web application development strategies have evolved, the framework has been able to evolve in step with technologies like ASP.NET MVC and ASP.NET Web API. As Web application development takes its next evolutionary step into the world of cloud computing, project Katana provides the underlying set of components to ASP.NET applications, enabling them to be flexible, portable, lightweight, and provide better performance – put another way, project Katana cloud optimizes your ASP.NET applications.

f8ffa82a99fe4f628cc3f950349f9865

Unlimited Hosting For LIFE

HostForLIFE.eu is Microsoft No #1 Recommended Windows and ASP.NET 5 / ASP.NET Core 1.0 Hosting in European continent.

HostForLIFE.eu dedicated to being more than just another web hosting provider as we see them as a long-term business partner tasked with handling a critical component of your website. Combining industry-best practices and staff with cutting-edge knowledge and expertise, HostForLIFE.eu provide the stability and reliability you need to realize success in today’s modern world.

9e6f60d8d9974176b0d14296d3b29c2f

HostForLIFE.eu is the leader in ASP.NET 5 / ASP.NET Core 1.0 Hosting Technology. They have provided a wide-range of ASP.NET service, starting from the Classic ASP, ASP.NET1.1 Hosting, ASP.NET 2 Hosting, ASP.NET 3.5 Hosting, ASP.NET 4 Hosting, ASP.NET 4.5 Hosting, ASP.NET 4.5.1 Hosting, ASP.NET 4.5.2 Hosting, ASP.NET 4.6 Hosting and the latest ASP.NET 5 / ASP.NET Core 1.0 Hosting.

Unlimited Hosting For LIFE – Technical Support

Shopping-Support-IconHostForLIFE.eu allow customers to reach a real human being through support ticket. All of the support channels are available 24 hours a day, 7 days a week, so that people are able to get their problems well resolved even in the midnight. HostForLIFE.eu support representatives are picked with standard well trained, they are expected to be professional and responsive.

Unlimited Hosting For LIFE – Uptime

uptime-iconHostForLIFE.eu currently operates data centers located in Amsterdam (Netherlands), London (UK), Washington, D.C. (US), Paris (France), Frankfurt (Germany), Chennai (India), Milan (Italy), Toronto (Canada) and São Paulo (Brazil) Data Center. All their data center offers complete redundancy in power, HVAC, fire suppression, network connectivity, and security. Their data center has over 53,000 sq ft of raised floor between the two facilities, HostForLIFE has an offering to fit any need. Relibility, Stability and Performance of their servers remain their top priority. Even their basic service plans are equipped with standard service level agreements for 99.99% uptime. Advanced options raise the bar to 99.99%.

Check their cheap price, Now! By clicking on the picture below!

check-price-now-button

ASP.NET MVC 4 Tutorial :: Creating Google Column Chart With Animation

In this tutorial, we will discuss about creating Google column chart with animation on load using ASP.NET MVC4 & Jquery. A column chart is a vertical bar chart rendered in the browser using SVG or VML, whichever is appropriate for the user’s browser. Like all Google charts, column charts display tooltips when the user hovers over the data. For a horizontal version of this chart, see the bar chart.

Steps :

1 – Create New Project.

Go to File > New > Project > Select asp.net MVC4 web application > Entry Application Name > Click OK > Select Internet Application > Select view engine Razor > OK

2 – Add a Database.

Go to Solution Explorer > Right Click on App_Data folder > Add > New item > Select SQL Server Database Under Data > Enter Database name > Add.

3 – Create table for get data for chart.

Open Database > Right Click on Table > Add New Table > Add Columns > Save > Enter table name > Ok.

In this example, I have used one tables as below

4- Add Entity Data Model.

Go to Solution Explorer > Right Click on Project name form Solution Explorer > Add > New item > Select ADO.net Entity Data Model under data > Enter model name > Add.
A popup window will come (Entity Data Model Wizard) > Select Generate from database > Next >
Chose your data connection > select your database > next > Select tables > enter Model Namespace > Finish.

5 – Add a new Controller.

Go to Solution Explorer > Right Click on Controllers folder form Solution Explorer > Add > Controller > Enter Controller name > Select Templete “empty MVC Controller”> Add.

6 -Add new action into your controller for Get Method.

Here I have added “Column” Action into “GoogleChart” Controller. Please write this following code

public ActionResult Column()

{

return View();

}

7 – Add view for the Action & design.

Right Click on Action Method (here right click on form action) > Add View… > Enter View Name > Select View Engine (Razor) > Check “Create a strong-typed view” > Select your model class > Add.

8 – Add jquery code for create google animated Chart.

<script>

$(document).ready(function () {

//Load Data Here

var chartData = null;

$.ajax({

url: '/GoogleChart/GetSalesData',

type: 'GET',

dataType: 'json',

data: '',

success: function (d) {

chartData = d;

},

error: function () {

alert('Error!');

}

}).done(function () {

drawChart(chartData);

});

});

 

function drawChart(d) {

var chartData = d;

var data = null;

data = google.visualization.arrayToDataTable(chartData);

 

var view = new google.visualization.DataView(data);

view.setColumns([0, {

type: 'number',

label: data.getColumnLabel(0),

calc: function () { return 0; }

}, {

type: 'number',

label: data.getColumnLabel(1),

calc: function () { return 0; }

}, {

type: 'number',

label: data.getColumnLabel(2),

calc: function () { return 0; }

}, {

type: 'number',

label: data.getColumnLabel(3),

calc: function () { return 0; }

}]);

 

var chart = new google.visualization.ColumnChart(document.getElementById('visualization'));

var options = {

title: 'Sales Report',

legend: 'bottom',

hAxis: {

title: 'Year',

format: '#'

},

vAxis: {

minValue: 0,

maxValue: 1000000,

title: 'Sales Amount'

},

chartArea: {

left:100, top: 50, width:'70%', height: '50%'

},

animation: {

duration: 1000

}

};

 

var runFirstTime = google.visualization.events.addListener(chart, 'ready', function () {

google.visualization.events.removeListener(runFirstTime);

chart.draw(data, options);

});

 

chart.draw(view, options);

}

google.load('visualization', '1', { packages: ['corechart'] });

</script>

 

9 – Add another new action into your controller for fetch json data for Chart.

Here I have added “GetSalesData” Action into “GoogleChart” Controller. Please write this following code

public JsonResult GetSalesData()

{

List<SalesData> sd = new List<SalesData>();

using (MyDatabaseEntities dc = new MyDatabaseEntities())

{

sd = dc.SalesDatas.OrderBy(a => a.Year).ToList();

}

 

var chartData = new object[sd.Count + 1];

chartData[0] = new object[]{

"Year",

"Electronics",

"Book And Media",

"Home And Kitchen"

};

int j = 0;

foreach (var i in sd)

{

j++;

chartData[j] = new object[] {i.Year, i.Electronics, i.BookAndMedia, i.HomeAndKitchen };

}

 

return new JsonResult {Data = chartData, JsonRequestBehavior = JsonRequestBehavior.AllowGet };

}

 

Complete View

@{

ViewBag.Title = "Column";

}

 

<h2>Column Chart With Animation</h2>

 

<br />

<div id="visualization" style="width:600px; height:300px">

 

</div>

 

<script type="text/javascript" src="https://www.google.com/jsapi"></script>

@section Scripts{

<script>

$(document).ready(function () {

//Load Data Here

var chartData = null;

$.ajax({

url: '/GoogleChart/GetSalesData',

type: 'GET',

dataType: 'json',

data: '',

success: function (d) {

chartData = d;

},

error: function () {

alert('Error!');

}

}).done(function () {

drawChart(chartData);

});

});

 

function drawChart(d) {

var chartData = d;

var data = null;

data = google.visualization.arrayToDataTable(chartData);

 

var view = new google.visualization.DataView(data);

view.setColumns([0, {

type: 'number',

label: data.getColumnLabel(0),

calc: function () { return 0; }

}, {

type: 'number',

label: data.getColumnLabel(1),

calc: function () { return 0; }

}, {

type: 'number',

label: data.getColumnLabel(2),

calc: function () { return 0; }

}, {

type: 'number',

label: data.getColumnLabel(3),

calc: function () { return 0; }

}]);

 

var chart = new google.visualization.ColumnChart(document.getElementById('visualization'));

var options = {

title: 'Sales Report',

legend: 'bottom',

hAxis: {

title: 'Year',

format: '#'

},

vAxis: {

minValue: 0,

maxValue: 1000000,

title: 'Sales Amount'

},

chartArea: {

left:100, top: 50, width:'70%', height: '50%'

},

animation: {

duration: 1000

}

};

 

var runFirstTime = google.visualization.events.addListener(chart, 'ready', function () {

google.visualization.events.removeListener(runFirstTime);

chart.draw(data, options);

});

 

chart.draw(view, options);

}

google.load('visualization', '1', { packages: ['corechart'] });

</script>

}

10 – Run Application.

 

Microsoft ASP.NET Hosting :: HostForLIFE.eu VS Web Services WorldWide

HostForLIFE.eu VS Web Services WorldWide

Web Services WorldWide

WebServicesWorldwide.com provides quality web services to customers globally. Their services include Domain Registration, Shared Hosting, VPS & Dedicated Servers, Digital Certificates and Website Builder. Their servers are located in five countries, viz. India, USA, UK, Hong Kong and Turkey. They provide quick and quality support via phone, live chat and email. Their support is available 24x7x365.

HostForLIFE.eu

HostForLIFE.eu is Microsoft No #1 Recommended Windows and ASP.NET 5 / ASP.NET Core 1.0 Hosting in European Continent. All of their servers are wind powered. They’ve invested in Wind Energy to help offset server emissions. Their team of server experts are able to deploy and manage most any type of server configuration. They’re dedicated to being more than just another web hosting provider as they see themselves as a long-term business partner tasked with handling a critical component of your website. Combining industry-best practices and staff with cutting-edge knowledge and expertise, they provide the stability and reliability you need to realize success in today’s modern world.

ASP.NET Hosting – Pricing Comparison

Web Services WorldWide Windows Hosting Plans

26190cf5bbfa486893a39ac28d2ff6a2

HostForLIFE.eu Windows Shared Hosting Plans

5681b57f4c6f41eea4238e5cd8db5e64

HostForLIFE.eu VS Web Services WorldWide – ASP.NET Hosting

b707008dc43042f283ff1a3af23553f2

Web Services WorldWide

Web Services Worldwide infrastructure comprises of high availability clusters of different machines, with varied operating systems and applications, spread across multiple continents.

An effective monitoring system is extremely crucial for ensuring maximum uptime. Today, any web services company manages hundreds of servers with a large number of services running on each server. Manually checking each service on just one server 24 x 7 is extremely difficult – across a number of servers – is humanly impossible.

Companies that do not have a good monitoring system, or worse, don’t have one at all, have larger downtimes and are increasing the risk of potential damage caused due to service disruptions. An undetected minor issue can change into a major issue rapidly, increasing the amount of damage caused.

Web Services Worldwide monitoring systems and tools provide Web Services Worldwide system administrators with an all-encompassing view into the health of Web Services Worldwide globally distributed infrastructure. Web Services Worldwide monitor a large number of parameters related to the health of Web Services Worldwide servers and individual services that reside on them.

366da992b0024771b74cceef0a6dbdd9

fc3a10ba301742a886dd05176c03b97f

HostForLIFE.eu

HostForLIFE.eu offers a complete menu of services. IT professionals select only what they need – and leave behind what they don’t. The result is an optimal blend of cost and performance. HostForLIFE.eu offer IT professionals more advanced features and the latest technology – ahead of other hosting companies.

Some other hosting providers manually execute configuration requests, which can take days. Plesk completes requests in seconds. It is included free with each hosting account. Renowned for its comprehensive functionality – beyond other hosting control panels – and ease of use, Plesk Control Panel is available only to HostForLIFE’s customers.

HostForLIFE revolutionized hosting with Plesk Control Panel, a Web-based interface that provides customers with 24×7 access to their server and site configuration tools.

HostForLIFE.eu wholly own all of HostForLIFE.eu servers and network equipment, HostForLIFE.eu are profitable, debt free, and all growth is funded from revenue. Financial stability is the bedrock of a hosting provider’s ability to deliver outstanding uptime, cost-effective service plans and world-class 24×7 support. HostForLIFE.eu customers are assured of HostForLIFE.eu’s financial integrity and stability.

9e6aa0082772497485a500cb556146ed

Conclusion

We do not mean to compare to provide hosting which one is good and which one is bad. But we help to give you the ease of selecting ASP.NET hosting provider that suits your needs. Of course, each hosting has its advantages and disadvantages. In terms of price it can be concluded that the WorldWide Web Servers provide cheaper prices, but HostForLIFE.eu provides other advanced features in their hosting plan.

Best ASP.NET 4.5 Hosting :: SoftSysHosting.com VS HostForLIFE.eu

Best ASP.NET 4.5 Hosting – I Host Azure | There are so many hosting companies on the web that finding the right one for your ASP.NET 4.5 hosting can be a chore.

We have selected two of ASP.NET 4.5 hosts that perfectly complies with ASP.NET 4.5 requirements. If you do decide to go with one of the listed web hosts and click through from this page.

In ASP.NET 4.5, we can adopt an approach using which the Model can be directly bound with the DataBound controls and CRUD and pagination operations can be implemented very effectively. It incorporates concepts from the ObjectDataSource control and from model binding in ASP.NET MVC. We will see this shortly. ASP.NET 4.5 is based upon .NET 4.5 and it gets installed once you install Visual Studio 2011 preview.

Best ASP.NET 4.5 Hosting :: SoftSysHosting.com VS HostForLIFE.eu

softsys_black_background Softsys Hosting company began web hosting operations in 2006     (under domain softsys.org) and since then has become one of the     best Windows hosting providers, operating in the market. Along with the first-class shared, reseller, VPS and dedicated hosting services, they offer a full line of small business solutions, including payment gateway services, SSL certificates, domain registration, etc. All aspects of their work follow a customer-first business approach as they strive to take special care of every one of their clients – no matter how big or small they are. Customer satisfaction has always been, and always will be, their number one priority and our over 75% referral rate demonstrates this commitment.

imgHostForLIFE.eu ASP.NET 4.5 Hosting is Microsoft No #1 Recommended Windows and ASP.NET 5 / ASP.NET Core 1.0 Hosting in European continent.

They proudly announce that they are the leader in ASP.NET 5 / ASP.NET Core 1.0 Hosting Technology. They have provided a wide-range of ASP.NET service, starting from the Classic ASP, ASP.NET1.1 Hosting, ASP.NET 2 Hosting, ASP.NET 3.5 Hosting, ASP.NET 4 Hosting, ASP.NET 4.5 Hosting, ASP.NET 4.5.1 Hosting, ASP.NET 4.5.2 Hosting, ASP.NET 4.6 Hosting and the latest ASP.NET 5 / ASP.NET Core 1.0 Hosting.

Best ASP.NET 4.5 Hosting :: Feature & Pricing Battle

Best ASP.NET 4.5 Hosting – This area of consideration comes down to the following question – What makes this hosting company special? What extra incentive do they provide to make hosting your site with them just a touch more attractive? Whether it’s multiple data centers, energy-saving practices, or additional features such as regular data backups or free domain privacy, hosting companies often offer more than just servers. If you see one that offers something you need or find important, that can be a good indicator that you should look into using that company.

SoftSysHosting.com Pricing

img (2)

SoftSysHosting.com Features

img (3)

As you can see, SoftSys Hosting offer 2 GB disk space with 20 GB of Bandwidth for $9.16 per month with a lot of hosting features such as Classic ASP.NET, Silverlight, SQL Server, etc.

HostForLIFE.eu Pricing

img (4)

HostForLIFE.eu Features

img (5)

Meanwhile, HostForLIFE.eu ASP NET 4.5 Hosting offer unlimited disk space, unlimited bandwidth, and unlimited websites for only €3.00/month.

Best ASP.NET 4.5 Hosting :: Support Battle

Best ASP.NET 4.5 Hosting – In most people’s opinions, this is the big one. When your site, for some unknown reason, goes down, can you call up and get a real, live person on the phone? And, more than that, can they find out what’s wrong and fix it, or at least tell me what you need to do to get your site back online?

Before going with a host look into their reputation for customer support. See what kinds of different ways you can contact them when you need support – email, toll-free phone, chat, and so on.

Both company, SoftSys Hosting and HostForlife.eu ASP.NET 4.5 Hosting offer support via help ticket for 24/7. They extremely knowledgeable and responsive Support Representatives are available to serve you, so all issues are resolved very promptly and accurately.

Best ASP.NET 4.5Hosting :: Customer Reviews / Satisfaction

Best ASP.NET 4.5 Hosting – This is one of those factors that you’ll have to get a little creative to get the real story on. Are they easy to contact for support? What’s the average time it takes to respond to a ticket? When they find a problem with a site, what’s their course of action?

This is one of the great things about social media – ask a question about a company, and you’re more likely than not to get a few answers.

img (6)img (7)

Best ASP.NET 4.5Hosting :: Hosting Choice

Best ASP.NET 4.5 Hosting – One thing to consider about your hosting provider (and the plan you choose) is whether or not they fit into your plans for the future. In other words, what you consider adequate hosting now might not meet your needs two years from now? The choice is yours.

Cheap ASP.NET MVC 6 Hosting :: Cheap and Fast

Cheap ASP.NET MVC 6 Hosting – I Host Azure | Are you looking for cheap ASP.NET MVC 6 hosting? We know you don’t like slow websites. Neither do your visitors. If your site is slow, your visitors will just find another site to buy from or get their information from. That’s why you need cheap yet fast ASP.NET MVC 6 Hosting that suits your need.

Web hosting can seem very complicated when you first think about it. When you break it down into steps, you can understand it easier and it can make you money. Dedicated or shared hosting, which one is right for you? If you run a large website with a lot of traffic, a shared server might limit you and lead to a lot of downtime. Find a dedicated host for more space and bandwidth, even unlimited.

Cheap ASP.NET MVC 6 Hosting – Fastest ASP.NET MVC 6 Hosting

HostForLIFE.eu ASP.NET MVC 6 Hosting currently operates data center located in Amsterdam (Netherlands), London (UK), Washington, D.C. (US), Paris (France), Frankfurt (Germany), Chennai (India), Milan (Italy), Toronto (Canada) and Sao Paulo (Brazil) Data Center. All HostForLIFE.eu ASP.NET MVC 6 data center offers complete redundancy in power, HVAC, fire suppression, network connectivity, and security. Our data center has over 53,000 sq ft of raised floor between the two facilities, HostForLIFE has an offering to fit any need. The datacenter facility sits atop multiple power grids driven by TXU electric, with PowerWare UPS battery backup power and dual diesel generators onsite. Their HVAC systems are condenser units by Data Aire to provide redundancy in cooling coupled with nine managed backbone providers.

img

Cheap ASP.NET MVC 6 Hosting – Cheapest Hosting

HostForLIFE.eu ASP.NET MVC 6 Hosting is European best, cheap and erliable ASP.NET 5 / ASP.NET Core 1.0 Hosting & SQL Server Hosting with instant activation.

HostForLIFE.eu ASP.NET MVC 6 Hosting was established to cater to an under served market in the hosting industry; web hosting for customers who want excellent service. This is why HostForLIFE.eu continues to prosper throughout the web hosting industry’s maturation process.

img

Cheap ASP.NET MVC 6 Hosting – Satisfaction Guaranteed

Guarantees is a promise or assurance, especially one in writing, that something is ofspecified quality, content, benefit, etc., or that it will performsatisfactorily for a given length of time.

HostForLIFE.eu ASP.NET MVC 6 Hosting’s top priority to deliver the ultimate customer experience, and we strongly believe that you’ll love their service . If for any reason you’re unhappy in your first 30 days as a customer, you’re more than welcome to request your money back.

ASP.NET MVC 5 Tutorial :: Error Validation on Ajax

ASP.NET MVC 5 Tutorial

In computer science, data validation is the process of ensuring that a program operates on clean, correct and useful data. It uses routines, often called “validation rules” “validation constraints” or “check routines”, that check for correctness, meaningfulness, and security of data that are input to the system. The rules may be implemented through the automated facilities of a data dictionary, or by the inclusion of explicit application program validation logic.

hflnet51

If you’re developing rich web clients using Asp.net MVC on the back-end, you’ve probably come across this functionality that can be described with these conditions:

  1. client side data (may be a form),
  2. ajax posting of this data (form),
  3. controller action has strong type parameters,
  4. controller action processes data and returns anything but a full view (since it was an Ajax call)

Familiar? Then you’ve come across this problem: »What should be done when validation fails?«
Seems fairly straight forward, right? Well not so fast my fellow developer friend…

Old Fashioned

Validation in Asp.net MVC is really simple and very transparent. If you had to think about it all the time when developing Asp.net Web forms applications, you don’t have to do that with MVC anymore. Whenever your controller action takes strong type parameters and you define validation rules on the type itself, you can easily just lay back and watch the magic happen in front of your eyes.

When you don’t use Ajax (how old fashioned of you), your form will be posted back the usual way by means of browser reloading the whole page. Because browser reloads the whole page there will be some flickering since it will clear the window at a certain point to render the new response. So your application will have a master view (in terms of master/detail process), where the user could click some Add new link or button that will redirect them to the new entity view (the details view). This view presents a form where they enter relevant data and a button to submit it to server. Your controller action could look very similar to this:

[HttpPost]
public ActionResult Add(Person instance)
{
    if (!this.ModelState.IsValid)
    {
        // return the same view with validation errors
        return View(instance);
    }
    // save the new person instance and go back to master view
    Person result = this.Service.Add(instance);
    return RedirectToAction("Index");
}

Contemporary

But since we’re savvy web developers, we rather use asynchronous processing these days. Instead of asking the browser to post back data and reload the whole page, we rather issue an Ajax call. This way we avoid page flickering and even the nasty long page scroll position stays the same. Ajax FTW! All today’s desktop browsers support this functionality as well. Great way of doing it then.

The whole client process probably changed according to our advanced functionality. We’d still have the master view with the list of all entities, but clicking on the Add new link will most probably present a modal dialog box with the details form instead of redirecting the user to a whole new page. In terms of usability and interface comprehension, this is a much better experience. Something similar is frequently used in Sharepoint 2010 these days. The process would work like this:

  1. User clicks Add new link on the master view.
  2. Your javascript dims the master view and displays a dialog box with the new entity form (details view).
  3. User enters relevant data and clicks the Save link.
  4. Your javascript issues an Ajax call that posts back data.
  5. When everything goes according to the plan, server responds either with a PartialViewResult that holds visual representation of the newly created entity that can be appended to master page entity list, or JsonResult data that can be consumed for the same purpose (but you’ll have to manually transform JSON to visual HTML representation).
  6. Your javascript closes the dialog box.
  7. Master view is in full display again and your javascript adds the newly created entity to it’s list (while also providing some highlight animation).

It’s wiser to return a partial view since the same partial view can be used on the master view to display each entity item in the list, so they will be fully compatible and when you change your partial view, both functionalities still work as expected. Otherwise you’d have to change javascript code as well. Not DRY at all. This is our controller action now:

[HttpPost]
public ActionResult Add(Person instance)
{
    if (!this.ModelState.IsValid)
    {
        // we'll see this in a bit
    }
    // save the new person instance and go back to master view
    Person result = this.Service.Add(instance);
    return PartialView("Person", result); // or Json(result)
}

So what do we do, when user enters incorrect data into the form that’s not valid? You can’t just return some other partial view, because javascript expects something else. You could of course put additional functionality on the client side that would detect different HTML being returned, but that’s very prone to errors. Think of changing the partial view. Any of the two. DRY again. The best thing would actually be to return a 400 HTTP response and provide the right result in it. Why is this better?

  • Because it will keep working even when you completely redesign your views.
  • Because it’s going to be much easier to distinguish between a successful results and an erroneous one on the client.

If you’re an Asp.net MVC developer it’s highly likely that you use jQuery on the client. Distinguishing success from an error cannot be easier:

$.ajax({
    url: "Person/Add",
    type: "POST",
    data: $(this).serializeArray(), // provided this code executes in form.onsubmit event
    success: function(data, status, xhr) {
        // YAY! Process data
    },
    error: function(xhr, status, err) {
        if (xhr.status == 400)
        {
            // this is our erroneous result
        }
        else
        {
            // some other server error must have happened (most probably HTTP 5xx)
        }
    }
});

To make things reusable on the server side you have two possible (and most obvious) ways of doing it:

  1. Provide additional controller extension methods like PartialViewError, JsonError, etc. that will work very similar to their normal counterparts except they’ll also set the response status code to 400 (don’t forget to check whether this is an Ajax call, because if it’s not, don’t set status code).
  2. Provide a custom exception and an exception action filter that handles it.

The first one is quite trivial so I’ve decided to do the latter. And since I don’t use the usual pattern of displaying in-place form validation errors it also suits my needs.

Let’s first look at the code of my custom exception. It’s called ModelStateException because I throw it on invalid model state and it has a constructor that takes model state and gets the errors automatically from it. This is the code of the exception:

/// <summary>
/// This exception that is thrown when there are model state errors.
/// </summary>
[Serializable]
public class ModelStateException : Exception
{
    /// <summary>
    /// Gets the model errors.
    /// </summary>
    public Dictionary<string, string> Errors { get; private set; }
    /// <summary>
    /// Gets a message that describes the current exception and is related to the first model state error.
    /// </summary>
    /// <value></value>
    public override string Message
    {
        get
        {
            if (this.Errors.Count > 0)
            {
                return this.Errors.First().Value;
            }
            return null;
        }
    }
    /// <summary>
    /// Initializes a new instance of the <see cref="ModelStateException"/> class.
    /// </summary>
    public ModelStateException() : base()
    {
        this.Errors = new Dictionary<string, string>();
    }
    /// <summary>
    /// Initializes a new instance of the <see cref="ModelStateException"/> class.
    /// </summary>
    /// <param name="modelState">State of the model.</param>
    public ModelStateException(ModelStateDictionary modelState)
        : this()
    {
        if (modelState == null)
        {
            throw new ArgumentNullException("modelState");
        }
        //this.ModelState = modelState;
        if (!modelState.IsValid)
        {
            StringBuilder errors;
            foreach (KeyValuePair<string, ModelState> state in modelState)
            {
                if (state.Value.Errors.Count > 0)
                {
                    errors = new StringBuilder();
                    foreach (ModelError err in state.Value.Errors)
                    {
                        errors.AppendLine(err.ErrorMessage);
                    }
                    this.Errors.Add(state.Key, errors.ToString());
                }
            }
        }
    }
    /// <summary>
    /// Initializes a new instance of the <see cref="ModelStateException"/> class.
    /// </summary>
    /// <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"/> that holds the serialized object data about the exception being thrown.</param>
    /// <param name="context">The <see cref="T:System.Runtime.Serialization.StreamingContext"/> that contains contextual information about the source or destination.</param>
    /// <exception cref="T:System.ArgumentNullException">
    /// The <paramref name="info"/> parameter is null.
    /// </exception>
    /// <exception cref="T:System.Runtime.Serialization.SerializationException">
    /// The class name is null or <see cref="P:System.Exception.HResult"/> is zero (0).
    /// </exception>
    protected ModelStateException(SerializationInfo info, StreamingContext context)
        : base(info, context)
    {
        if (info == null)
        {
            throw new ArgumentNullException("info");
        }
        // deserialize
        this.Errors = info.GetValue("ModelStateException.Errors", typeof(Dictionary<string, string>)) as Dictionary<string, string>;
    }
    /// <summary>
    /// Initializes a new instance of the <see cref="ModelStateException"/> class.
    /// </summary>
    /// <param name="message">The message.</param>
    public ModelStateException(string message)
        : base(message)
    {
        this.Errors = new Dictionary<string, string>();
        this.Errors.Add(string.Empty, message);
    }
    /// <summary>
    /// Initializes a new instance of the <see cref="ModelStateException"/> class.
    /// </summary>
    /// <param name="message">The message.</param>
    /// <param name="innerException">The inner exception.</param>
    public ModelStateException(string message, Exception innerException)
        : base(message, innerException)
    {
        this.Errors = new Dictionary<string, string>();
        this.Errors.Add(string.Empty, message);
    }
    /// <summary>
    /// When overridden in a derived class, sets the <see cref="T:System.Runtime.Serialization.SerializationInfo"/> with information about the exception.
    /// </summary>
    /// <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"/> that holds the serialized object data about the exception being thrown.</param>
    /// <param name="context">The <see cref="T:System.Runtime.Serialization.StreamingContext"/> that contains contextual information about the source or destination.</param>
    /// <exception cref="T:System.ArgumentNullException">
    /// The <paramref name="info"/> parameter is a null reference (Nothing in Visual Basic).
    /// </exception>
    /// <PermissionSet>
    ///     <IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Read="*AllFiles*" PathDiscovery="*AllFiles*"/>
    ///     <IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Flags="SerializationFormatter"/>
    /// </PermissionSet>
    [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)]
    public override void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        if (info == null)
        {
            throw new ArgumentNullException("info");
        }
        // serialize errors
        info.AddValue("ModelStateException.Errors", this.Errors, typeof(Dictionary<string, string>));
        base.GetObjectData(info, context);
    }
}

The exception action filter has to intercept ModelStateException exceptions and return the error in a predefined format, so the client’s able to uniformly consume it. This is the code that I’m using:

/// <summary>
/// Represents errors that occur due to invalid application model state.
/// </summary>
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false)]
public sealed class HandleModelStateExceptionAttribute : FilterAttribute, IExceptionFilter
{
    /// <summary>
    /// Called when an exception occurs and processes <see cref="ModelStateException"/> object.
    /// </summary>
    /// <param name="filterContext">Filter context.</param>
    public void OnException(ExceptionContext filterContext)
    {
        if (filterContext == null)
        {
            throw new ArgumentNullException("filterContext");
        }
        // handle modelStateException
        if (filterContext.Exception != null && typeof(ModelStateException).IsInstanceOfType(filterContext.Exception) && !filterContext.ExceptionHandled)
        {
            filterContext.ExceptionHandled = true;
            filterContext.HttpContext.Response.Clear();
            filterContext.HttpContext.Response.ContentEncoding = Encoding.UTF8;
            filterContext.HttpContext.Response.HeaderEncoding = Encoding.UTF8;
            filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
            filterContext.HttpContext.Response.StatusCode = 400;
            filterContext.Result = new ContentResult {
                Content = (filterContext.Exception as ModelStateException).Message,
                ContentEncoding = Encoding.UTF8,
            };
        }
    }
}

Reusable End Result

All our controller actions can now take advantage of this reusable functionality. The previously shown controller action now looks like this:

[HttpPost]
[HandleModelStateException]
public ActionResult Add(Person instance)
{
    if (!this.ModelState.IsValid)
    {
        throw new ModelStateException(this.ModelState);
    }
    // save the new person instance and go back to master view
    Person result = this.Service.Add(instance);
    return PartialView("Person", result);
}

Our client side functionality can now be packed into a simple application specific jQuery plugin that does ajax error handling and can be loaded as part of the general scripts on your master (as in master template) view:

$.extend({
    appAjax: function(url, type, datagetter, onsuccess) {
        /// <summary>jQuery extension that executes Ajax calls and handles errors in application specific ways.</summary>
        /// <param name="url" type="String">URL address where to issue this Ajax call.</param>
        /// <param name="type" type="String">HTTP method type (GET, POST, DELETE, PUT, HEAD)</param>
        /// <param name="datagetter" type="Function">This parameterless function will be called to return ajax data.</param>
        /// <param name="onsuccess" type="Function">This optional function(data) will be called after a successful Ajax call.</param>
        var execSuccess = $.isFunction(onsuccess) ? onsuccess : $.noop;
        var getData = $.isFunction(datagetter) ? datagetter : function() { return datagetter; };
        $.ajax({
            url: url,
            type: type,
            data: getData(),
            error: function(xhr, status, err) {
                if (xhr.status == 400)
                {
                    alert(xhr.responseText);
                }
                else
                {
                    alert("Server error has occured.");
                }
            },
            success: function(data, status, xhr) {
                window.setTimeout(function() {
                    execSuccess(data);
                }, 10);
            }
        });
    }
});

In your page, you can simply call it this way:

$.appAjax(
    "Person/Add",
    "POST",
    function() { return $(this).serializeArray(); },
    function(data) { // consume data }
);

This is the reusable model validation in Asp.net MVC applications using Ajax calls and jQuery on the client side.

HostForLIFE.eu ASP.NET MVC 5 Hosting
HostForLIFE.eu revolutionized hosting with Plesk Control Panel, a Web-based interface that provides customers with 24×7 access to their server and site configuration tools. Plesk completes requests in seconds. It is included free with each hosting account. Renowned for its comprehensive functionality – beyond other hosting control panels – and ease of use, Plesk Control Panel is available only to HostForLIFE’s customers. They offer a highly redundant, carrier-class architecture, designed around the needs of shared hosting customers.

image