European ASP.NET MVC Hosting

BLOG about Latest ASP.NET MVC Hosting and Its Technology - Dedicated to European Windows Hosting Customer

European ASP.NET MVC 3 Hosting :: RenderPage And Data in ASP.NET MVC 3 Web Pages

clock December 6, 2011 07:16 by author Scott

When you’re working with MVC, you sometimes work with partial views. With the new Razor view engine, partial views can be called through the RenderPage method. RenderPage renders the content of one page within another page. What isn’t obvious from the beginning is how to access data that is passed into the partial page. I thought I’d do a quick article and show you how. This code also works in WebMatrix if you're using it.

Before moving on, you need to download ASP.NET MVC 3.
Click here to download and install it using the Microsoft Web Platform Installer.

Open studio 2010 and create a new ASP.NET MVC 3 Web Application (Razor) project. For this example, my model will be a list of processes running on your machine. I want to pass that model into the view, and then pass that model into the partial page. When you’re working with partial views, you need to specify a path to the view, then an optional array of data to the page being rendered. The array of data can be accessed by using the
System.Web.WebPages.WebPageBase.PageData property. Here’s the model for the view.



And here’s the view.



I’m going to create a partial view called _DisplayProcess and call it via the RenderPage method. When I create partial views I always prefix them with an underscore so they can only be rendered as a partial view. By default ASP.NET won’t render files beginning with an underscore. The second parameter for RenderPage is the array of data. To use this, you can use the PageData property.



If you only had a single object being passed into the page, you would reference it like this.



To me it wasn’t obviously the first time I used partial views in Razor, so hopefully if you get stuck like me, this helps you out.



European ASP.NET MVC 3 Hosting :: DropDownList in ASP.Net MVC 3 Razor with Entity Framework

clock December 5, 2011 08:42 by author Scott

In this application I will create a Blog post with post comments application. This application will be Object Class Mapping using Entity Framework. That means with the mapping of classes the database and table will be created automatically.

Step 1:

Create a new ASP.Net MVC 3 application with an empty web application. While creating the project, check the radio button for "UnitTest".

Step 2:

Now under the "Model" Folder create two classes.

·         Blog

·         Comments



Step 3:

Now In the Blog Class copy the following code:

public class Blog
    {
       
        [Key]      
        public int BlogId { get; set; }
 
        [Required(ErrorMessage = "BlogName is required")]
        public string BlogName { get; set; }
 
        [Required(ErrorMessage = "Description is required")]
        [StringLength(120, ErrorMessage = "Description Name Not exceed more than 120 words")]
        public string Description { get; set; }
        public string Body { get; set; } 
        public virtual  List<Comments > Comments_List { get; set; }
    }


See here we did the Validation of each property. And also hold the list of comments. That means 1 blog contains many posts. So that is a one to many relationship.
The "Virtual" keyword means it will make the relationship.

Step 4:

Now in the Comments class write the following code:

public class Comments
    {
        [Key ]
        public int CommentId { get; set; }
          public string Comment { get; set; }
        //[ForeignKey]
          public int BlogId { get; set; }
          public virtual Blog Blog { get; set; } 
    }

See here also we have the object reference of the "Blog" class. Before that I have used the virtual keyword.

Step 5:

Now it's time to make the entity class by which the database and the table will create.

Create the "DatabaseContext" folder under the project. After that create a class named "BlogDbContext.cs" under the folder. This class is an entity class.

Step 6:

Now add a Reference for the Entity Framework by clicking "Add New Reference" under the project.



In my project I already added the reference. Without this dll the table will not be created in the database by object class mapping.

Now in the "BlogDbContext" class paste the following code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
using blogmvc3.Models;
 
namespace blogmvc3.DatabaseContext
{
    public class BlogDbContext:DbContext
    {
        public DbSet<Blog> Blog { get; set; }
        public DbSet<Comments> Comments { get; set; }
    }
}

See here in the Dbset we are passing a blog class and comments class. The Dbset table will be created automatically with a relation in the database.
The Namespace "System.Data.Entity;" is very important for that.

Step 7:

Now we have to configure the "web.config" file for the connection string. The web.config file is under
the Main Solution Project. Not the Project web.config file.



Now paste the following connection string into the web.config file.





Step 8:

Now create a Controller Class named "HomeController" under the "ControllerFolder. After that check the
"Add action for create.update,delete.." so it will automatically create the action method in the Controller class.





Step 9:

Now in the "HomeController" class first create the object of class "BlogDbContext":

    BlogDbContext _db = new BlogDbContext();

After that in the Index Method write the following code:

public ActionResult Index()
        {
            var GenreLst = new List<string>();
 
            var GenreQry = from d in _db.Blog
                           orderby d.BlogName
                           select d.BlogName;
            GenreLst.AddRange(GenreQry.Distinct());
            ViewBag.movieGenre = new SelectList(GenreLst);
 
            return View(_db.Comments .ToList ());
 
        }

See here I selected all the Blog Name from and after that adding into the list.

Then through "ViewBag" I am passing the GenreLst.

Step 10:

Now create a master page in the razor engine under the "shared" folder. Give the Name "_LayoutPage1.cshtml".



After that paste the following code there:

<!DOCTYPE html>
 
<html>
<head>
    <title>@ViewBag.Title</title>
    <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
    <script src="@Url.Content("~/Scripts/jquery-1.4.4.min.js")" type="text/javascript"></script>
   @* <script src="../../Scripts/jquery-ui-1.8.11.custom.min.js" type="text/javascript"></script>
    <link href="../../Content/jquery-ui-1.8.11.custom.css" rel="stylesheet" type="text/css" />*@
</head>
 
<body>
    <div class="page">
 
        <div id="header">
            <div id="title">
                <h1>Blog Post</h1>
            </div>
 
            <div id="logindisplay">
                @*@Html.Partial("_LogOnPartial")*@
            </div>
 
            <div id="menucontainer">
 
                <ul id="menu">
                   @* <li>@html.actionlink("home", "index", "home")</li>*@
                    @*<li>@Html.ActionLink("About", "About", "Home")</li>*@
                   <li>@Html.ActionLink("home", "index", "home")</li>
                     <li>@Html.ActionLink("Article Post", "CreateLogin", "Article")</li>
                     @*<li>@Html.ActionLink("BookCab", "CreateLogin", "Cab")</li> *@
                </ul>
 
            </div>
             <script type="text/javascript"><!--                 mce: 0--></script>
        </div> 
        <div id="main">
            @RenderBody()
            <div id="footer">
            </div>
        </div>
    </div>
</body>
</html>

Step 11:

Now go the "Home controller". Right-click the Index Method and add view. It will look like:



Please check "Create Strongly-typed Views".

Choose Model Class "Comments" under DropDownList.

Select "Scaffold Template" list. After that press the "Add" Button. It will automatically create a view named "Index" under the "Home" folder.

Step 12:

See the Index View Engine will create the code for the list view automatically.

Paste the following code there.

@model IEnumerable<blogmvc3.Models.Comments>
 
@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_LayoutPage1.cshtml";
}
 
<h2>Index</h2>
 
<p> 
    @Html.ActionLink("Create New", "Create")
</p>
<table>
    <tr>
        <@*th>@Html.ActionLink("Search Blog", "SearchIndex")</th>*@
        <th>
            Blog Name :
        </th>
        <th></th>
        <th>
           Description :
        </th>
        <th></th>
        <th>
           Body
        </th>
        <th></th>
        <th>
            Comment :
        </th>
        <th></th>
        <th>
        BlogNAme List: @Html.DropDownList("movieGenre", "All"); 
       </th>       
    </tr>
 
@foreach (var item in Model) {
    <tr>
        <td>
            @Html.ActionLink("Edit", "Edit", new { id=item.CommentId }) |
            @Html.ActionLink("Details", "Details", new { id=item.CommentId }) |
            @Html.ActionLink("Delete", "Delete", new { id=item.CommentId })
        </td>
       
        <td> @item.Blog.BlogName</td>
         <td> @item.Blog.Description</td>
          <td> @item.Blog.Body</td>      
        <td>
            @item.Comment
        </td>       
    </tr>
}
</table>

Now see the code BlogNAme List: @Html.DropDownList("movieGenre", "All");

Here "Html.DropDownList" is accepting the MovieGenre which I passed through view bag and 2nd parameter is to display all the list.




Now run the Code it will look like the following figure:



European ASP.NET MVC 3 Hosting :: Error handling in ASP.NET MVC3

clock November 23, 2011 07:42 by author Scott

In ASP.NET MVC (versions 1 to 3) we have the [HandleError] attribute, that will allow us to handle errors in a very easy way.

Just by decorating an action (or controller if we want to extend HandleError behaviour to all actions on that controller) with the HandleError attribute and enabling “CustomErrors” in web.config, we get a nice redirection to a friendly view in case an unhandled error raises.

Internally, we could have a look at the implementation of OnException method inside HandleError using Reflector to see how it works:



As we can see, the unhandled exception will be handled if it hasn't been already marked as "handled" and if custom error handling is enabled .

Web.config customErrors section

The CustomErrors section allow us to define automatic error handling behaviour. If it doesn't exists, it must be created inside system.web section. as shown here:




Posible values for mode are "Off | On | RemoteOnly". This will allow us to easy define behaviour for development and production scenarios :

·         On: custom error handling enabled

·         Off: custom error handling disabled. If an error is raised, we will see the yellow screen of death of ASP.NET

·         RemoteOnly: if we launch the application in the local server (targeting http://localhost ), we won't see custom errors. If we access the application from other machine, we will see custom erros. This option is used by developers to debug applications. If there is an error, you can always (among other things) RD to your server and launch the application in a local browser so you see the exception in a first seat.

Behaviour:

·         If we use the HandleError attribute and CustomErrors is enabled, when an unhandled error raises, the MVC runtimewill look for a “Errors.aspx” view in the context of the HttpRequest being processed (current view folder associated to controller or shared view folder), and will render it. In this case the "defaultredirect" and "redirect" CustomErrors attributes are ignored

·         If we don't use the HandleError attribute and CustomErrors is enabled , we will get an HTTP redirection to the url defined on the "redirect" and "defaultredirect" attributes, within the CustomErrors section in web.config (in our case, /Error/General

Important: ASP.NET MVC3, registers the HandleError attribute globally (for all controllers) !! (see image). Take that into account so you don't think your MVC3 controlleris not using the HandleError attribute (by default it is). In previous versions of  ASP.NET MVC, where we didn't have global filters, the HandleError attribute had to be defined manually for each action or controller.



Also important: If you have enabled CustomErrors=On , also added the [HandleError ] and still get a yellow screen of death please make sure the Error.aspx has no errors (check master page and the errors.aspx code) , it may have an error (this is pretty common scenario and difficult to debug).You can check if this is happening simple by temporaly removing all Error.aspx code and replacing by a text (más información).

To avoid showing ASP.NET yellow screen of death if your Error.aspx has errors, use "redirect" CustomErrros attribute to show a static  html page.



Controller OnException

Alternatively to HandleError, we can also override the OnException  method of a controller (or all of them if we use a base controller class).

An example of exception handling, logging and redirection to friendly message would be:



Note: the OnException event is executed independly of the use of HandleError in the controler.

Using Elmah to intercept, log and notify of unhandled errors

Elmah is a fantastic library that help us to intercept, register (in the desired format: database, text file, xml, etc) and optionally deliverunhandled errors ocurred in our application, so we keep everything in control at all times. It also provieds a web interface so you can access the error records remotely, and a RSS feed so you can subscribe with your favorite RSS reader.



With NuGet , a library package manager, available with ASP.NET MVC3, install Elmah is a pretty straightforward process. First step is launching NuGet:



Then, we search for "Elmah":



and proceed to install it. NuGet will handle for us the necessary steps required to install and configure it (in previous versions of ASP.NET MVC we had to do it manuall). NuGet does for us:

·         downloads the last version from the oficial repository

·         adds the assembly reference to our project

·         modifies the web.config to add the proper configuration parameters

In our case, Elmah needs some parameters and configuration sections (httpModules,httpHandlers, etc)  in order to work del web.config :



If we want Elmah to record errors or events in XML files inside a certain directory , we have to indicate it::



And that's it.. When an unhandled error is raised, Elmah will be able to intercept it and record it, and also send an email to the administrator. 

Registering with Elmah custom events and errors

Elmah offers an API so we can record or own events or exceptions . We can use that funcionality to log exceptions that we have already handled with our code. Example:



Elmah and HandleError


Elmah works perfectly with unhandled exceptions (yellow screen of death), but won't be able to intercept exceptions that are being handled by the [HandleError] attribute.

To fix this, we need to create a custom HandleError attribute and add a custom behaviour to the new attribute.



More details and source code here: 
http://stackoverflow.com/questions/766610/how-to-get-elmah-to-work-with-asp-net-mvc-handleerror-attribute 

Filtering unwanted events in Elmah

If Elmah is logging too many stuff, (ex: 404 errors looking for favicon.ico), I have the posibility of applying custom filters to those unwanted events .

First, we must add the Elmah ErrorFilter module to web.config:



Once registered, we implement the following events on Global.asax.cs, defining the filtering rules I want to apply:



Final notes

In my particular experience, I found the best practice to use the custom HandleError as shown in the last part of this article (having the HandleError applied globaly) with CustomErrors enabled, helped by Elmah to handle, register and send unhandled exceptions . When necessary, I use the Elmah signal capabilities for those handled exceptions I want to log.



European ASP.NET MVC 3 Hosting :: RenderBody, RenderPage and RenderSection in ASP.NET MVC 3

clock November 11, 2011 05:27 by author Scott

Everybody knows Razor is the new view engine ASP.NET Web Pages, so I thought I’d write about some Razor syntax you may not be aware of. The three methods I’ll be focusing on today are RenderBody, RenderPage and RenderSection. You’ll need to understand how each of these work if you want to get know the Razor syntax intimately. This code also works in WebMatrix if you're using it.

Before moving on, you need to download ASP.NET MVC 3.
Click here to download and install them using the Microsoft Web Platform Installer.

Open studio 2010 and create a new ASP.NET MVC 3 Web Application (Razor) project. Now it's time to start coding! I’ll begin with the RenderBody method.

RenderBody

The RenderBody method resides in the master page, or in Razor this is commonly referred to as the Layout page. There can only be one RenderBody method per Layout page. If you’re from Web Forms world, the easiest way to think of RenderBody is it’s like the
ContentPlaceHolder server control. The RenderBody method indicates where view templates that are based on this master layout file should “fill in” the body content.



RenderPage

Layout pages can also contain content that can be filled by other pages on disk. This is achieved by using the RenderPage method. This method takes either one or two parameters. The first is the physical location of the file, the second is an optional array of objects that can be passed into the page. Add a new cshtml file to the Shared folder and call it _Header.cshtml. I've prefixed this file with an underscore because I don't want this file to be called outside of RenderPage. By default, ASP.NET will not serve pages beginning with an underscore. Here's the code I'm adding to the _Header.cshtml page.


<h1>Header Here</h1>

And to use this in the layout, it's as easy as this.



RenderSection


Layout pages also have the concept of sections. A layout page can only contain one RenderBody method, but can have multiple sections. To create a section you use the RenderSection method. The difference between RenderSection and RenderPage is RenderPage reads the content from a file, whereas RenderSection runs code blocks you define in your content pages. The following code illustrates how to render a footer section.



RenderSection expects one parameter and that is the name of the section. If you don’t provide that, an exception will be thrown. Views can add data to sections by using the following code.



If you ran the website now it’ll run without error. If on the other hand you don’t include the section footer in the view, you’ll get an error.



That’s because by default, sections are mandatory. To make sections optional, just add the second parameter, which is a Boolean value.



Now things will run just fine.

These three methods you will use time and time again when you're using the Razor view engine. This code works both for ASP.NET MVC 3 and also WebMatrix. Have fun!



European ASP.NET MVC 3 Hosting :: How to Integrate ASP.NET MVC 3 with ASP.NET 4 Web Forms Application

clock November 8, 2011 06:59 by author Scott

The easiest way to add ASP.NET MVC 3 to an upgraded ASP.NET 2.0 WebForms application:

- Run the Upgrade Wizard (open the  Visual Studio2008 Web Application in Visual Studio 2010)
- Create a default ASP.NET MVC application for reference (you'll throw it away later)
- Use a differencing tool like
Beyond Compare to integrate the new web.config entries from the ASP.NET MVC sections into the upgraded ASP.NET WebForms application

Upgrading an ASP.NET 2.0 WebForms Application



Now, open this application in Visual Studio 2010. You'll get the Conversion/Upgrade Wizard



Then click Next until Finish. You will get prompt to upgrade the 2.0 application to .NET Framework 4. Click Yes.



Here's the same WebForms application, now upgraded in Visual Studio 2010. It still runs and it's still WebForms. Or, more accurately, it continues to  be ASP.NET.



I'm going to take a new default ASP.NET MVC 3 application and Beyond Compare and compare the upgraded app with the default app.



I'll copy over these folders and files:

- Content
- Controllers
- Models
- Scripts
- Views
- Global.asax, Global.asax.cs

Now, here's the before and after references from the upgraded application. You’ll see the old one on image_6 and the new one on the image_7.



Here's the references I added.

1. Microsoft.CSharp - (as this was a C# app)

2. System.Web.Mvc  - From \Program Files (x86)\Microsoft ASP.NET\ASP.NET MVC 3\Assemblies

3. System.Web.WebPages and System.Web.Razor - From \Program Files (x86)\Microsoft ASP.NET\ASP.NET Web Pages\v1.0\Assemblies

4. System.ComponentModel.DataAnnotations

Next, add these sections to the Web.config. Again, it's easier to use a diff tool and you might have a little trial and error.

Thought: This might be a nice
NuGet package for someone to make...

Add these settings in appSettings:

<appSettings>
   <add key="ClientValidationEnabled" value="true"/>
   <add key="UnobtrusiveJavaScriptEnabled" value="true"/>
</appSettings>

Add these assembly elements under compilation:

<compilation debug="true" targetFramework="4.0">
  <assemblies>
    <add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    <add assembly="System.Web.Helpers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    <add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    <add assembly="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    <add assembly="System.Web.WebPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
  </assemblies>
</compilation>

Add these namespaces in pages

<system.web>
  <pages>
     <namespaces>
       <add namespace="System.Web.Helpers" />
       <add namespace="System.Web.Mvc" />
       <add namespace="System.Web.Mvc.Ajax" />
       <add namespace="System.Web.Mvc.Html" />
       <add namespace="System.Web.Routing" />
       <add namespace="System.Web.WebPages"/>
     </namespaces>
   </pages>
</system.web>

If you're running IIS7 at some point, which I'm sure you will, add these:

<system.webServer>
  <validation validateIntegratedModeConfiguration="false"/>
  <modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>


And finally add this assembly binding redirect, just in case you've got ASP.NET MVC 1 or 2 assemblies in your Global Assembly Cache (GAC).

<configuration>
 <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="3.0.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>


Also, make sure you merge in the Global.asax.cs so that your Routes are registered at application startup.

public class SomeHybrid: System.Web.HttpApplication
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new HandleErrorAttribute());
    }

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            "Default", // Route name
            "{controller}/{action}/{id}", // URL with parameters
            new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
        );

    }

    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        RegisterGlobalFilters(GlobalFilters.Filters);
        RegisterRoutes(RouteTable.Routes);
    }
}

Now, at this point I can visit both pages. The WebForms page is a file on disk, so ASP.NET routing passes requests directly on to this page when I /default.aspx. The ASP.NET Routing engine is engaged so I can also hit /Home/Index.


If I want to get fancy, I can add a PageRoute so I have pretty URLs when visit my WebForms pages as well. Just add a route in the Global.asax like this. Make sure that simple routes like these come first, as the default ASP.NET MVC route is very "greedy" and would gobble up a simple URL like /calculator

routes.MapPageRoute("WebFormThing", "Calculator", "~/Default.aspx");

Now I can visit /Calculator and the request is routed to /Default.aspx. And of course, my ASP.NET MVC 3 Razor pages like /Home/Index work also.



Finally, just to make the point, here's the Default.aspx from the WebForms part of my new app next to the source for a Razor page



Enjoy it.



European ASP.NET MVC 3 Hosting :: The Reason You Should Use ViewModels

clock October 14, 2011 08:02 by author Scott

This is the reason why you should use View Models:

1. Remove logic from your Views

When you start working with ASP.NET MVC, you’ll most likely ask yourself why you should use a View Model. Using your domain model or entity model works perfectly fine. And it does. For a while. But as you continue to use your Models, you’ll discover that you have to add some adaptations in your Views. Here is a typical usage adaptation (using the Razor View engine):

Hello @model.UserName

Your age: @(model.Age != 0 ? model.Age.ToString() : "n/a")

Not so bad, is it? The problem is that you have introduced logic into your View, which is bad for two reasons:

1. You can not unit test that code, and the only way to make sure that it works is user testing.
2. You need to repeat that code for every View that intends to use your Model (code duplication = code smell).

All those small adaptations will lead to a big mess eventually.

2. Security

One of the biggest advantages with View Models is removing security risks. Your database objects or domain objects will most likely contain properties that the user should not be able to change. It can be a property called IsAdmin or Reputation.


All those properties will automatically be changed by the model binder if they exist in the model (and are posted in the FORM, which is quite easy to do if you know HTML). Simply remove them from the View Model and they’ll never be changed.

3. Loose coupling

By using domain models or entity models, you are adding coupling between your lower layers and the presentation layer, and that is seldom good. Google “loose coupling” to find out more.

Basically, it means that if you change your domain/entity model, you have to change all your Views that use that Model. If you use a ViewModel, you only have to change the code that maps between an entity/domain model and the View Model.



European ASP.NET MVC 3 Hosting :: How to Add ELMAH in your ASP.NET MVC Application

clock October 6, 2011 10:12 by author Scott

In this tutorial, you will find a step by step instruction how to add ELMAH (Error Logging Modules and Handlers for ASP.NET) to your existing ASP.NET MVC application. ELMAH (Error Logging Modules and Handlers) is an application-wide error logging facility that is completely pluggable. It can be dynamically added to a running ASP.NET web application, or even all ASP.NET web applications on a machine, without any need for re-compilation or re-deployment.

I've tested the steps below with ASP.NET MVC 2 and ASP.NET MVC 3 applications, but they may work also for other types of ASP.NET applications.

First you have to download ELMAH from the
download page. After adding a reference to Elmah.dll in your project, all you have to do is to add the ELMAH configuration to your Web.config.

The example configuration shown above includes two customizings I found very useful for web applications:

- If the server returns a status code between 400 (included) and 500 (excluded), ELMAH ignores the exceptions.
- A remote access to the /elmah.axd web interface is enabled for specific (admin) users.

<configSections>
  [...]
  <sectionGroup name="elmah">
    <section name="security" requirePermission="false"
type="Elmah.SecuritySectionHandler, Elmah" />

    <section name="errorLog" requirePermission="false" type="Elmah.ErrorLogSectionHandler, Elmah" />
    <section name="errorMail" requirePermission="false" type="Elmah.ErrorMailSectionHandler, Elmah" />
    <section name="errorFilter" requirePermission="false" type="Elmah.ErrorFilterSectionHandler, Elmah" />
  </sectionGroup>
  [...]
</configSections> 

<system.web>
  [...]
  <httpHandlers>
    <add verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" />
  </httpHandlers>
  <httpModules>
    <add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah" />
    <add name="ErrorMail" type="Elmah.ErrorMailModule, Elmah" />
    <add name="ErrorFilter" type="Elmah.ErrorFilterModule, Elmah" />
  </httpModules>
  [...]
</system.web> 

<system.webServer>
  <modules runAllManagedModulesForAllRequests="true">
    <add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah" />
  </modules>
  <handlers>
    <add name="Elmah" verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" />
  </handlers>
</system.webServer> 

<elmah>
  <security allowRemoteAccess="1" />
  <errorLog type="Elmah.XmlFileErrorLog, Elmah" logPath="~/App_Data" />
  <errorMail from="[FROM_ADDRESS]" to="[TO_ADDRESS]" subject="[SUBJECT]" async="true" smtpPort="25" smtpServer="[SMTP_SERVER]"/>
  <errorFilter>
    <test>
      <and>
        <greater binding="HttpStatusCode" value="399" type="Int32" />
        <lesser binding="HttpStatusCode" value="500" type="Int32" />
      </and>
    </test>
  </errorFilter>
</elmah> 

<location path="elmah.axd">
  <system.web>
    <authorization>
      <allow users="[ALLOWED_ADMIN_USERS]" />
      <deny users="*" />
    </authorization>
  </system.web>
</location>



European ASP.NET MVC 3 Hosting :: ASP.NET MVC 3 Model Metadata Providers

clock October 5, 2011 09:37 by author Scott

There are different types of filters in MVC. Depending on the type of the Filter, and the scope of the Filter, the order of the execution also changes.

You may already aware that there are different types of filters within MVC framework. They are listed below.

1. Authorization filters
2. Action filters
3. Response/Result filters
4. Exception filters

The above list is ordered as exactly the order they executes within MVC framework. The Authorization filters always run first, and the Exception filters run at the end.

Specifying the Order property for Filters

Within each filter, you may specify the Order property. (All filters are derived from the abstract class FilterAttribute, and this class has an Order property). This property will ensure the filter runs in a specific Order. For an example, let’s say we have 2 Authorization filters, AuthorizationFilterA and AuthorizationFilterB and they are implemented as below.


public class AuthorizationFilterA : AuthorizeAttribute
{
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        Debug.WriteLine("OnAuthorization : AuthorizationFilterA");
    }
}

public class AuthorizationFilterB : AuthorizeAttribute
{
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        Debug.WriteLine("OnAuthorization : AuthorizationFilterB");
    }
}

Now, if I want these two filters to run in a specific order - AuthorizationFilterB to run first, and AuthorizationFilterA to run second, I can simply specify the execution order as below.


[AuthorizationFilterA(Order=2)]
[AuthorizationFilterB(Order=1)]
public ActionResult Index()
{
    return View();
}

When you run the code, the Output window should display that AuthorizationFilterB runs first, AuthorizationFilterA runs second.

OnAuthorization : AuthorizationFilterB

OnAuthorization : AuthorizationFilterA

Filter Scope

Within each filter type, you can define a scope. For an example, I could scope all my Authorization Filters to run within the Controller Scope, and all Action Filters to run in Global scope (Every Action within the MVC application).

FilterScope.Global is a new scope which was introduced in MVC 3. The existing scopes are First, Controller, Action, and Last. The complete enumeration is defined as below.

namespace System.Web.Mvc {
    public enum FilterScope
        First = 0,
        Global = 10,
        Controller = 20,
        Action = 30,
        Last = 100,
    }
}

By default, the filters with the lowest scope runs first. For an example, scope Global (10) executes first and scope Controller (20) executes second.


Filter Scope with explicit Ordering

Below example shows, how explicit filter ordering (using Order property) and scope of the filters determine their correct run order.

Let’s add the scope to our existing Authorization Filters – AuthorisationFilterA and AuthorisationFilterB. Please note that we haven’t changed the usage of Order property.

AuthorizationFilterA(Order 2) has the scope Global.

AuthorizationFilterB(Order 1) has the scope Action.

public class AuthorizationFilterA : AuthorizeAttribute
{
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        Debug.WriteLine("OnAuthorization : AuthorizationFilterA (Order: 2) in scope : Global");
    }
}

public class AuthorizationFilterB : AuthorizeAttribute
{
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        Debug.WriteLine("OnAuthorization : AuthorizationFilterB (Order: 1) in scope : Action");
    }
}


[AuthorizationFilterB(Order = 1)]
public ActionResult Index()
{
    return View();
}

GobalFilters.Filters.Add(new AuthorizationFilterA() { Order = 2});

According to the above Filter Scope enumeration, if we were to specify only the scope but not the Order property, then we would expect AuthorizationFilterA (in Global scope) to run first, and AuthorizationFilterB (in Action scope) to run second. Since we are explicitly specifying the Order property for both filters, AuthorizationFilterB (in Action scope – Order 1) runs first and AuthorizationFilterA (in Global scope – Order 2) runs second.


Output:

OnAuthorization : AuthorizationFilterB (Order: 1) in scope : Action

OnAuthorization : AuthorizationFilterA (Order: 2) in scope : Global

Now let’s add another Authorization filter (AuthorizationFilterC) to Global scope. Also note that we have not specified the Order property.

public class AuthorizationFilterC : AuthorizeAttribute
    {
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            Debug.WriteLine("OnAuthorization : AuthorizationFilterC (no Order defined) in scope : Global");
        }
    }

GlobalFilters.Filters.Add(new AuthorizationFilterC());

After running all three filters, you can see the output as below. 

Output

OnAuthorization : AuthorizationFilterC (no Order defined) in scope : Global

OnAuthorization : AuthorizationFilterB (Order: 1) in scope : Action

OnAuthorization : AuthorizationFilterA (Order: 2) in scope : Global

For same Filter type, the filters without the explicit ordering (i.e AuthorizationFilterC) take precedence over the filters with explicit ordering (AuthorizationFilterB, AuthorizationFilterA).

Now let’s remove the Order property from both AuthorizationFilterB and AuthorizationFilterA

[AuthorizationFilterB]
public ActionResult Index()
{
    return View();
}

GlobalFilters.Filters.Add(new AuthorizationFilterA());

Output:

OnAuthorization : AuthorizationFilterA (no order defined) in scope : Global

OnAuthorization : AuthorizationFilterC (no order defined) in scope : Global

OnAuthorization : AuthorizationFilterB (no order defined) in scope : Action

As we would expect, the filters with scope Global (AuthorizationFilterA and AuthorizationFilterC) run first and second in order, the scope Action filter (AuthorizationFilterC) runs at the end. 2 Global filters (AuthorizationFilterA and AuthorizationFilterC) run order relies on the order which they were added to the Global Filter collection. In this example AuthorizationFilterA which was added prior to AuthorizationFilterC , runs first.

For the same filters, when determine the run order, first it sorts them by their order (lowest numbers first), and then by their scope (also lowest numbers first).

Controller as a Filter

In MVC the Controller itself is also a Filter. Controller implements all filters, so Controller can subscribe to all filter events.

public abstract class Controller : ControllerBase,
IActionFilter, IAuthorizationFilter, IDisposable,
IExceptionFilter, IResultFilter

MVC framework ensures, the Controller always runs first, before any other filters get executed. It has been accomplished by specifying the scope as the First and the order property as Int32.MinValue. By default, an MVC filter has the value for the Order -1. Therefore Int32.MinValue along with the Scope First together ensures the Controller always runs first.

public class ControllerInstanceFilterProvider : IFilterProvider {
        public IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor) {
            if (controllerContext.Controller != null) {
               
// Use FilterScope.First and Order of Int32.MinValue to ensure controller instance methods always run first
                yield return new Filter(controllerContext.Controller, FilterScope.First, Int32.MinValue);
            }
        }
    }

Forward Filter Order and Reverse Filter Order

So far we have discussed the order of filters which get executed based on the explicit ordering (using Order property) and the scope which they can be belong to. However, MVC filters run order, do not only rely only by these two factors. Sometimes filters run in forward order and sometimes filters run in reverse order. Let’s see the below example.

Let’s say I have three Action filters (ActionFilter1, ActionFilter2, ActionFilter3), one Authorization filter (AuthorizationFilter) and two Exception filters (HandleErrorA, HandleErrorB). They are implemented as below.

public class ActionFilter1 : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        Debug.WriteLine("Forward Order - OnActionExecuting : ActionFilter1 (Scope Global)");
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        Debug.WriteLine("Reverse Order - OnActionExecuted : ActionFilter1 (Scope Global)");
    }

    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        Debug.WriteLine("Forward Order - OnResultExecuting : ActionFilter1 (Scope Global)");
    }

    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        Debug.WriteLine("Reverse Order - OnResultExecuted : ActionFilter1 (Scope Global)");
    }
}


public class ActionFilter2 : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        Debug.WriteLine("Forward Order - OnActionExecuting : ActionFilter2 (Scope Controller)");
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        Debug.WriteLine("Reverse Order - OnActionExecuted : ActionFilter2 (Scope Controller)");
    }

    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        Debug.WriteLine("Forward Order - OnResultExecuting : ActionFilter2 (Scope Controller)");
    } 

    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        Debug.WriteLine("Reverse Order - OnResultExecuted : ActionFilter2 (Scope Controller)");
    }
}

public class ActionFilter3 : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        Debug.WriteLine("Forward Order - OnActionExecuting : ActionFilter3 (Scope Action)");
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        Debug.WriteLine("Reverse Order - OnActionExecuted : ActionFilter3 (Scope Action)");
    } 

    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        Debug.WriteLine("Forward Order - OnResultExecuting : ActionFilter3 (Scope Action)");
    }

    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        Debug.WriteLine("Reverse Order - OnResultExecuted : ActionFilter3 (Scope Action)");
    }
}    


public class AuthorizationFilter : AuthorizeAttribute
{
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        Debug.WriteLine("Forward Order - OnAuthorization : AuthorizationFilter (Scope Controller)");
    }
}   


public class HandleErrorA : HandleErrorAttribute
{
    public override void OnException(ExceptionContext filterContext)
    {
        Debug.WriteLine("Reverse Order - OnException : HandleErrorA (Scope Action)");
    }
}

public class HandleErrorB : HandleErrorAttribute
{
    public override void OnException(ExceptionContext filterContext)
    {
        Debug.WriteLine("Reverse Order - OnException : HandleErrorB (Scope Action)");
    }
}

We will register the above filters as below…


ActionFilter1 has the scope Global, ActionFIlter2 has the scope Controller, ActionFIlter3 has the Scope Action, AuthorizationFilter has the scope Controller, HandleErrorA has the scope Global, and HandleErrorB has the scope Action.

At the beginning of this article I mentioned that the run order of different types of filters. First Authorization filters, then Action Filters, followed by Result filters and at the end the Exception filters. This is true, however within each type of filters, some executes in reverse order and some executes in forward order.

The best way to explain is to examine the generated output.

Forward Order - OnAuthorization : AuthorizationFilter (Scope Controller)

Forward Order - OnActionExecuting : ActionFilter1 (Scope Global)

Forward Order - OnActionExecuting : ActionFilter2 (Scope Controller)

Forward Order - OnActionExecuting : ActionFilter3 (Scope Action)

Home Controller, Index Action

Reverse Order - OnActionExecuted : ActionFilter3 (Scope Action)

Reverse Order - OnActionExecuted : ActionFilter2 (Scope Controller)

Reverse Order - OnActionExecuted : ActionFilter1 (Scope Global)

Forward Order - OnResultExecuting : ActionFilter1 (Scope Global)

Forward Order - OnResultExecuting : ActionFilter2 (Scope Controller)

Forward Order - OnResultExecuting : ActionFilter3 (Scope Action)

Reverse Order - OnResultExecuted : ActionFilter3 (Scope Action)

Reverse Order - OnResultExecuted : ActionFilter2 (Scope Controller)

Reverse Order - OnResultExecuted : ActionFilter1 (Scope Global)

Reverse Order - OnException : HandleErrorB (Scope Action)

Reverse Order - OnException : HandleErrorA (Scope Global)

-
There is only one Authorization Filter in Controller scope and it runs first as expected.

-
The Action Filters run at second. Notice that OnActionExecuting event runs in an order where the order of filter execution is determined by their scope (lowest number first in the enumeration). As you see, Action Filters OnActionExecuting event runs in a forward order.

-
Home Controller’s Index Action executes.

-
Action Filters do not always run in forward order. As you see during OnActionExecuted event, they run in a reverse order.

-
Very similar to OnActionExecuted event, OnResultExecuted event runs in reverse order.

-
Error Handler filters run at last. For each Error Handler filter, OnException event runs in  reverse order. Prior to MVC 3, ErrorHandler’s OnException event ran in forward order. This approach makes MVC exception filters more aligned with .NET exception handlers.

Summary

There are multiple factors involved when deciding the run order of MVC filters. This includes the explicit ordering, the scope they belong to, and the type of the filter. Controller itself is a filter and always run first. By design, MVC executes certain filters in specific order. Some are run in forward order and some are run in reverse order.

 



European ASP.NET MVC 3 Hosting :; ExtJS and ASP.NET MVC 3

clock September 21, 2011 07:10 by author Scott

This short tutorial will walk though the implementation of DataGrid using ExtJS 3.3.1 and ASP.NET MVC 3. In this tutorial I focus more on the integration of the front-end, so you will not find any database code. Whenever we deal with data we usually create, read/retrieve, update or delete them. ExtJS provides a great data grid component and the ability to perform CRUD operation with very little coding. I used JSON as data format in the example below.



Let’s start with the server-side by developing the data model and controller.

Controller:

public class ContactController : Controller 
{ 
    // 
    // GET: /Contact/ 
    public ActionResult Index() 
    { 
        return View(); 
    } 
    public JsonResult Load() 
    { 
        var contact = new List<Contact> { 
            new Contact("Smith","95746325","[email protected]"), 
            new Contact("Adam","87291034","[email protected]"), 
            new Contact("Eve","98271345","[email protected]"), 
            new Contact("Chun Li","81728312","[email protected]") 
        }; 
        return Json(new
        { 
            total = contact.Count, 
            data = contact, 
        }, JsonRequestBehavior.AllowGet); 
    } 
    [HttpPost] 
    public JsonResult Create(List<Contact> data) 
    { 
        //insert Create code 
        return Json(new
        { 
            data = new Contact(data[0].Name, data[0].Phone, data[0].Email), 
            success = true, 
            message = "Create method called successfully"
        }); 
    } 
    [HttpPost] 
    public JsonResult Update(List<Contact> data) 
    { 
        //insert Update code 
        return Json(new
        { 
            success = true, 
            message = "Update method called successfully"
        }); 
    } 
    [HttpPost] 
    public JsonResult Delete(List<string> data) 
    { 
        //insert Delete code 
        return Json(new
        { 
            success = true, 
            message = "Delete method called successfully"
        }); 
    } 
}

Data Model:

public class Contact 
{ 
    public string Id { get; set; } 
    public string Name { get; set; } 
    public string Phone { get; set; } 
    public string Email { get; set; } 
    public Contact(string pName, string pPhone, string pEmail) 
    { 
        this.Id = System.Guid.NewGuid().ToString(); 
        this.Name = pName; 
        this.Phone = pPhone; 
        this.Email = pEmail; 
    } 
    public Contact() { } 
}

ExtJS:

Now, you move on to the view and work on the ExtJS. First, you define the record type which matches the server-side object.

var Contact = Ext.data.Record.create([ 

    { 
        name: 'Id', 
        type: 'string'
    }, { 
        name: 'Name', 
        type: 'string'
    }, { 
        name: 'Phone', 
        type: 'string'
    }, { 
        name: 'Email', 
        type: 'string'
    } 
]);

Now you need to setup the Writer and Reader

var writer = new Ext.data.JsonWriter({ 

    encode: false, 
    listful: true, 
    writeAllFields: true
}); 
var reader = new Ext.data.JsonReader({ 
    totalProperty: 'total',
    successProperty: 'success', 
    idProperty: 'Id', 
    root: 'data', 
    messageProperty: 'message'  // <-- New "messageProperty" meta-data 
}, Contact);

Then, setup a proxy to define the connection to the controller.

var proxy = new Ext.data.HttpProxy({ 

   api: { 
       read: '/Contact/Load', 
       create: '/Contact/Create', 
       update: '/Contact/Update', 
       destroy: '/Contact/Delete'
   }, 
   headers: { 'Content-Type': 'application/json; charset=UTF-8' } 
});

Hooks the above components (reader, writer, proxy) to the store.

var store = new Ext.data.Store({ 

   id: 'user', 
   proxy: proxy, 
   reader: reader, 
   writer: writer, 
   autoSave: false
});

Add the data grid declaration

var grid = new Ext.grid.GridPanel({ 

    store: store, 
    columns: [ 
        { header: "Name", 
            width: 170, 
            sortable: true, 
            dataIndex: 'Name', 
            editor: { 
                xtype: 'textfield', 
                allowBlank: false
            } 
        }, 
        { header: "Phone No.", 
            width: 160, 
            sortable: true, 
            dataIndex: 'Phone', 
            editor: { 
                xtype: 'textfield', 
                allowBlank: false
            } 
        }, 
        { header: "EMail", 
            width: 170, 
            sortable: true, 
            dataIndex: 'Email', 
            editor: { 
                xtype: 'textfield', 
                allowBlank: false
            } 
        } 
    ], 
    plugins: [editor], 
    title: 'Contacts DataGrid', 
    height: 300, 
    width: 510, 
    tbar: [{ 
        iconCls: 'icon-user-add', 
        text: 'Add Contact', 
        handler: function () { 
            var e = new Contact({ 
                Name: 'New Friend', 
                Phone: '(65) 89182736', 
                Email: '[email protected]'
            }); 
            editor.stopEditing(); 
            store.insert(0, e); 
            grid.getView().refresh(); 
            grid.getSelectionModel().selectRow(0); 
            editor.startEditing(0); 
        } 
    }, { 
        ref: '../removeBtn', 
        iconCls: 'icon-user-delete', 
        text: 'Remove Contact', 
        handler: function () { 
            editor.stopEditing(); 
            var s = grid.getSelectionModel().getSelections(); 
            for (var i = 0, r; r = s[i]; i++) { 
                store.remove(r); 
            } 
        } 
    }, { 
        iconCls: 'icon-user-save', 
        text: 'Save All Modifications', 
        handler: function () { 
            store.save(); 
        } 
    }]
});

Some observations:


-
When submitting data as JSON, set the headers “Content-Type” to “application/json” in the proxy object and set the encoding to false in the JsonWriter. If not, it will be treated as form submission.

-
Since I set the auto save to false. DataGrid will submit list of contact when there are 2 or more changes, however it will send a single object when there is 1 change. In order to make it consistent to send as list, set list full to true in the JsonWriter.

-
ASP.NET MVC 3 able to recognize the JSON without additional coding.



European ASP.NET MVC 3 Hosting :: How to Use BCrypt with ASP.NET MVC 3 and C#

clock September 12, 2011 08:58 by author Scott

I was just reading today about yet another site that stored their user’s passwords in plain text. Of course the issue is if you get hacked you expose everyone’s passwords to the world, passwords they might be using on other sites, etc. There is a lot of debate of how you should go about encrypting/hashing/obscuring passwords and with a little research I found a lot of people seem to think BCrypt is the way to go. Check out this article.

I won’t debate on what you should use for your website, you need to make that decision. I played with a
BCrypt C# library I found on Google Code. Today I’ll build a simple ASP.NET MVC 3 app that will use it to show how easy it is to work with in a project.

Open up Visual Studio 2010 and make sure you have the
ASP.NET MVC 3 package installed. Create a new project: File -> New Project -> ASP.NET MVC 3 Web Application and call it MvcBCrypt. For the project template select Empty. Make sure for the View Engine you pick Razor.



Right-click on the Controllers folder and select Add -> Controller

Name the new Controller HomeController.



When the code shows up right-click on the Index() and choose Add View. Use the default settings (see below) and then click Add.



Modify the code in the Index.cshtml file to look like this:

@{
    ViewBag.Title = "Home Page";
}   

<p>Password: @ViewBag.Password</p>
<p>Hashed Password: @ViewBag.HashedPassword</p>
<p>(Use a wrong password) Is the password correct?: @ViewBag.HashedPasswordChecked1</p>
<p>(Use the correct password) Is the password correct?: @ViewBag.HashedPasswordChecked2

Its time to bring in the
BCrypt code now. Go to this link and copy the source code. Create a new folder in your project called Utility and create a new class file in there called BCrypt.cs.



Note: Yes, there are better places to put this new BCrypt class file but for simplicity its just going to live in a Utility folder for this demonstration.

Make sure to paste in the code and save the file. When you do this make sure to fix the namespace and remove the following:

[assembly: System.Reflection.AssemblyVersion("0.3")]

Go back to the HomeController file and modify it like so:

using MvcBCrypt.Utility;

Add the new code to test out the BCrypt class:

public ActionResult Index()
{
    string password = "myPassword1";
    string wrongPassword = "wrongPasswOrd1";   

    string hashedPassword = BCrypt.HashPassword(password, BCrypt.GenerateSalt(12));
    bool doesItMatch1 = BCrypt.CheckPassword(wrongPassword, hashedPassword);
    bool doesItMatch2 = BCrypt.CheckPassword(password, hashedPassword);   

    ViewBag.Password = password;
    ViewBag.HashedPassword = hashedPassword;
    ViewBag.HashedPasswordChecked1 = doesItMatch1;
    ViewBag.HashedPasswordChecked2 = doesItMatch2;   

    return View();
}

Save and run the project.



Note: Using the new Library Package Manager I did see another BCrypt library out there so you might want to experiment with that one as well.



About HostForLIFE

HostForLIFE 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 offered the latest Windows 2019 Hosting, ASP.NET 5 Hosting, ASP.NET MVC 6 Hosting and SQL 2019 Hosting.


Month List

Tag cloud

Sign in