European ASP.NET MVC Hosting

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

ASP.NET MVC 5 Hosting - HostForLIFE.eu :: Friendly Errors In MVC 5

clock July 20, 2018 08:51 by author Peter

In this article, I will be explaining 3 different ways to handle exceptions and display a friendly error page to the end user. Friendly Error Pages are the pages that you design to show the end user when any kind of not handled exception happens in your application and your expected result is not achieved. So, instead of presenting your end user with technical information regarding the exception, you show him a friend page. Also, presenting your end user with technical information is not a security best practice.

So, let's see the three ways.

Method 1: Custom Exception Filter
Custom Exception Filter

It is a filter that is called every time an exception occurs in the applied methods.

Why would I use a custom exception filter?


Because with a custom exception filter, you can handle in a generic way every kind of exception thrown by your actions and/or controllers. You may use custom exception filters to log your exceptions.

Steps to achieve this:
Step 1

Create a new class named CustomExceptionFilter.
public class CustomExceptionFilter : FilterAttribute, IExceptionFilter   
{   
    public void OnException( ExceptionContext filterContext )   
    {   
        filterContext.Result = new RedirectResult( "Home/About" );   
        filterContext.ExceptionHandled = true;   
    }   
}   

What this custom exception does is to redirect to your About action in your Home Controller. Do not forget to set the ExceptionHandled equal to true; otherwise it will not take effect.

Step 2
Apply your custom exception filter to your controller/action.
public class HomeController : Controller 

    [CustomExceptionFilter] 
    public ActionResult Index() 
    { 
        throw new Exception(); 
        return View(); 
    } 
 
    public ActionResult About() 
    { 
        ViewBag.Message = "Your application thrown an exception"; 
 
        return View(); 
    } 
 
    public ActionResult Contact() 
    { 
        ViewBag.Message = "Your contact page."; 
        throw new Exception(); 
        return View(); 
    } 


You can see that the exception filter is applied only to your Index Action so if you access your Contact action, you will be able to see the non-handled exception page.

Method 2: Web.Config configuration
Why would I handle an exception by web.config configuration?

It is easy to configure and useful when you do not need to log or work on the exception.

Steps to achieve this:

Step 1
Include this in your web.config inside the system.web tag.
<customErrors defaultRedirect="Error.cshtml" mode="On"></customErrors> 

Step 2
Update your Controller.
public class HomeController : Controller 

    [HandleError] 
    public ActionResult Index() 
    { 
        throw new Exception(); 
        return View(); 
    } 
 
    public ActionResult About() 
    { 
        ViewBag.Message = "Your application description page."; 
 
        return View(); 
    } 
 
    public ActionResult Contact() 
    { 
        ViewBag.Message = "Your contact page."; 
        throw new Exception();
        return View(); 
    } 


Observation - Like the custom exception filter, you may choose if you want to handle the exceptions at the Controller or Action level. Also, here, the handled exception is applied only to your Index action, you may see the non-handled error in the Contact View.

Method 3: Global.Asax Application_error
What is the Application_error?

It is to override the global exception handler of the application.

Why would I handle an exception by global.asax Application_error?
You do not need to set the places that you would like to handle the errors like before where you had to set the actions and controllers to be handled. Here, every exception will hit and be handled.

Steps to Achieve this:

Step 1
Update  your global.asax.
protected void Application_Error( object sender, EventArgs e ) 
  { 
      Exception exception = Server.GetLastError(); 
      Server.ClearError(); 
      Response.Redirect( "/Home/About" ); 
  } 


Like the custom exception handlers, it is very important to ClearError() in the Server. What is done here is the redirection of non-handled exceptions to the About action in the Home Controller. Congratulation, you just learned three good ways of handling exceptions in your application and presenting friendly error pages to your end users.



ASP.NET MVC 5 Hosting - HostForLIFE.eu :: List Of Users With Roles In ASP.NET MVC Identity

clock July 13, 2018 11:21 by author Peter

In this article, we will learn how to list all users with Associated Roles in ASP.NET MVC 5 using Identity. ASP.NET MVC 5 does not come with an inbuilt feature to list users with associated roles by default. However ASP.NET MVC have inbuilt UserManager, SignManager and RoleManager to assist this.

We need this feature in each of our applications as users are to be maintained along with their associated roles. We can apply a number of ideas to do this. In this article, we will learn a very simple way to list users with their associated RoleName as in the figure below.

Step 1
Create a View Model as Users-in-Role_ViewModel
public class Users_in_Role_ViewModel 
    { 
        public string UserId { get; set; } 
        public string Username { get; set; } 
        public string Email { get; set; } 
        public string Role { get; set; } 
    } 


Step 2
Add a new method called UsersWithRoles inside ManageUsersController and add the following codes.
public ActionResult UsersWithRoles() 
        { 
            var usersWithRoles = (from user in context.Users 
                                  select new 
                                  { 
                                      UserId = user.Id,                                       
                                      Username = user.UserName, 
                                      Email = user.Email, 
                                      RoleNames = (from userRole in user.Roles 
                                                   join role in context.Roles on userRole.RoleId  
                                                   equals role.Id 
                                                   select role.Name).ToList() 
                                  }).ToList().Select(p => new Users_in_Role_ViewModel() 
  
                                  { 
                                      UserId = p.UserId, 
                                      Username = p.Username, 
                                      Email = p.Email, 
                                      Role = string.Join(",", p.RoleNames) 
                                  }); 
  
  
            return View(usersWithRoles); 
        } 


Note - context.Users represents the table AspNetUsers which has navigation property roles which represent the AspNetUserInRoles table.

Step 3
Now, let’s add a View of UsersWithRoles method of ManageUsersController.
@model IEnumerable<MVC5Demo.UI.ViewModels.Users_in_Role_ViewModel> 
@{ 
    ViewBag.Title = "Users With Roles"; 
    Layout = "~/Views/Shared/_Layout.cshtml"; 

  
<div class="panel panel-primary"> 
    <div class="panel-heading"> 
        <h3 class="box-title"> 
            <b>Users with Roles</b> 
        </h3> 
    </div> 
    <!-- /.box-header --> 
    <div class="panel-body"> 
        <table class="table table-hover table-bordered table-condensed" id="UsersWithRoles"> 
            <thead> 
                <tr> 
                    <td><b>Username</b></td> 
                    <td><b>Email</b></td> 
                    <td><b>Roles</b></td> 
                </tr> 
            </thead> 
            @foreach (var user in Model) 
            { 
                <tr> 
                    <td>@user.Username</td> 
                    <td>@user.Email</td> 
                    <td>@user.Role</td> 
                     
                </tr> 
            } 
        </table> 
    </div> 
  
    <div class="panel-footer"> 
        <p class="box-title"><b>Total Users till @String.Format("{0 : dddd, MMMM d, yyyy}", DateTime.Now)  : </b><span class="label label-primary">@Model.Count()</span></p> 
    </div> 
</div> 
  
  
@section scripts{ 
    <script> 
        $(function () { 
            $('#UsersWithRoles').DataTable({ 
                "paging": true, 
                "lengthChange": true, 
                "searching": true, 
                "ordering": true, 
                "info": true, 
                "autoWidth": true 
            }); 
        }); 
    </script> 


Now, the above method and View will return the users to their roles.

n



European ASP.NET MVC 5 Hosting - UK :: Tips Improving Your ASP.NET MVC Codebase

clock October 27, 2014 10:05 by author Scott

Some of you sometimes think why your application eat up until 1 GB-2GB memory on production server. After looking through the code, doing some profiling, maybe shaking your head a bit, you've figured out what the issue is and now you need to give some feedback.

In this tutorial, I will show some tips that you can follow to reduce your memory usage on production server and keep your ASP.NET MVC codebase working as you’d expect.

1. Understand the queries in your problem domain

The root cause of the support ticket I received was a simple case of fetching too much data from the database, causing obscene amounts of memory usage.

It's a common enough issue. You're building a simple blog, it has posts and it has media (images, videos, attachments). You put a Media array onto your Post domain object. Your Media domain object has all the image data stored in a byte array. Since you're using an ORM, there's a certain way you need to design your domain model to play nice; we've all experienced this.

public class BlogPost {
    public ICollection<BlogMedia> Media { get; set; }
}
public class BlogMedia {
    public byte[] Data { get; set; }
    public string Name { get; set; }
}

There's nothing absolutely wrong with this design. You've modeled your domain accurately. The problem is, when you issue a query through your favorite ORM, it eagerly loads all the data associated with your blog post:

public IList<BlogPost> GetNewestPosts(int take) {
    return _db.BlogPosts.OrderByDescending(p => p.PostDate).Take(take).ToList();
}

A seemingly innocuous line (unless you've been bitten), a sneaky monster is lying in wait with big consequences if you haven't disabled lazy loading or didn't tell your ORM to ignore that big Data property on blog media.

It's important to understand how your ORM queries and maps objects and make sure you only query what you need (for example using projection).

public IList<PostSummary> GetNewestPosts(int take) {
    return _db.BlogPosts.OrderByDescending(p => p.PostDate).Take(take).Select(p => new PostSummary() {
        Title = p.Title,
        Id = p.Id
    }).ToList();
}

This ensures we only grab the amount of data we really need for the task.

It's OK to have more than 5 methods on a repository; be as granular as you need to be for your UI.

2. Don't call your repositories from your views

Consider this line in an MVC view:

@foreach(var post in Model.RelatedPosts) {
    ...
}

It seems innocent enough. But if we take a look at what exactly that model property is hiding:

public class MyViewModel {

    public IList<BlogPost> RelatedPosts {
        get { return new BlogRepository().GetRelatedPosts(this.Tags); }
    }

}

Your "view model" has business logic in it on top of calling a data access method directly. Now you've introduced data access code somewhere it doesn't belong and hidden it inside a property. Move that into the controller so you can wrangle it in and populate the view model conciously.

This is a good opportunity to point out that implementing proper unit tests would uncover issues like this; because you definitely can't intercept calls to something like that and then you'd realize injecting a repository into a view model is probably not something you want to be doing.

3. Use partials and child actions to your advantage

If you need to perform business logic in a view, that should be a sign you need to revisit your view model and logic. I don't think it's advisable to do this in your MVC Razor view:

@{
    var blogController = new BlogController();
}

<ul>
@foreach(var tag in blogController.GetTagsForPost(p.Id)) {
    <li>@tag.Name</li>
}
</ul>

Putting business logic in the view is a no-no, but on top of that you're creating acontroller! Move that into your action method and use that view model you made for what it's intended for. You can also move that logic into a separate action method that only gets called inside views so you can cache it separately if needed.

//In the controller:

[ChildActionOnly]
[OutputCache(Duration=2000)]
public ActionResult TagsForPost(int postId) {
    return View();
}

//In the view:

@{Html.RenderAction("TagsForPost", new { postId = p.Id });}

Notice the ChildActionOnly attribute. From MSDN:

Any method that is marked with ChildActionOnlyAttribute can be called only with the Action or RenderAction HTML extension methods.

This means people can't see your child action by manipulating the URL (if you're using the default route).

Partial views and child actions are useful tools in the MVC arsenal; use them to your advantage!

4. Cache what matters

Given the code smells above, what do you think will happen if you only cached your view model?

public ActionResult Index() {
    var homepageViewModel = HttpContext.Current.Cache["homepageModel"] as HomepageViewModel;

    if (homepageViewModel == null) {
        homepageViewModel = new HomepageViewModel();
        homepageViewModel.RecentPosts = _blogRepository.GetNewestPosts(5);

        HttpContext.Current.Cache.Add("homepageModel", homepageViewModel, ...);

    }

    return View(homepageViewModel);
}

Nothing! There will not be any performance gain because you're accessing the data layer through a controller variable in the view and through a property in the view model... caching the view model won't help anything.

Instead, consider caching the output of the MVC action instead:

[OutputCache(Duration=2000)]
public ActionResult Index() {
    var homepageViewModel = new HomepageViewModel();

    homepageViewModel.RecentPosts = _blogRepository.GetNewestPosts(5);

    return View(homepageViewModel);
}

Notice the handy OutputCache attribute. MVC supports ASP.NET Output Caching; use it to your advantage when it applies. If you are going to cache the model, your model needs to essentially be a POCO with automatic (and read-only) properties... not something that calls other repository methods.

Conclusion

I hope with tutorial above, it will help you to minimize your memory usage on the server.

 



European ASP.NET MVC 5 Hosting - UK :: ASP.NET MVC 5 Scaffolding

clock October 13, 2014 07:28 by author Scott

In this article, I will show you how to use Scaffolding With your ASP.net MVC 5 Application. I assume that you all know about scaffolding and I don’t need to explain it again. In our previous post, we have also explained about Scaffolding with the Repository Pattern in ASP.NET MVC 3.

In this article, we will be more focus in adding scaffolded item to ASP.net MVC 5.

1. Let's create an ASP.net MVC 5 web application in Visual Studio 2013 and name it as ScaffoldingMVC5.

2. Right click your Controllers folder and Add New Scaffolded Item is as below.

3. From the Add Scaffold window, select the MVC 5 Controller with views,using Entity Framework scaffold template.

4. Add a controller. Please see the below screenshot

Then, please fill a name for your Data context as below, for example DataContext

5. You have done great job and this is the result

Testing the Result

Index Page

Create Page

Details Page

Edit Page

Delete Page

All above CRUD operations were generated according to our Model class Pet.

Pet.cs

Key points of the above code

  • [ScaffoldColumn(false)] means,the property which it declared will not use for scaffolding.In other words, that property will not be shown on the UI (i.e. Created property will not be shown).
  • Data validations of the form elements are happening ,according to the above model's Data Annotation values.
  • Let's explore it.

If you click the Create button, without entering anything.What will happen ?

What if you try to enter a wrong data type ?

 


Calender has been shown, if it's a DateTime property.

Great, right?



European ASP.NET MVC 5 Hosting - UK :: MVC Controllers with Visual Studio 2013 and ASP.NET MVC 5

clock August 6, 2014 09:14 by author Onit

Introduction

Before we start this article we will give you a quick reviews about MVC there are three parts to MVC.

Models: Part of the application that handles the application logic and contains classes representing data structure.

Views: Part of the application that handles the generation of HTML responses

Controllers: Part of the application that handles user interaction and incoming browser requests, retrieves model data and specify views

In Getting Started with Visual Studio 2013 and ASP.NET MVC 5 we created a new MVC application and took a look at some of the basics.

In this blog post we will take a look at Controllers and how they can be used

Controller in MVC

Adding a new controller The ASP.NET MVC framework maps URLs to classes that are referred to as controllers. Controllers process incoming requests, handles user input, interactions and executes appropriate application logic. A controller class typically calls a separate view component to generate the HTML mark-up for the request. The base class for all controllers is the ControllerBase class. The Controller class inherits from the ControllerBase and is the default implementation of a controller. In an MVC application, the Controller handles the following areas:

  1. Locating and validating the necessary action method.
  2. Getting any values used in the action method’s arguments.
  3. Handling any errors that occurs.
  4. Providing the deault WebFormViewEngine class for rendering views.

Using the solution we built in our previous post let’s add a new controller using these steps.

  • In the Solution explorer right click on the Controllers folder, select Add and then Controller as shown in the following screenshot.

  • In the Add Scaffold box select MVC 5 Controller – Empty and then click Add as shown in the following screenshot.

  • In the Add Controller dialog box in the Controller name field enter TopicController and then select Add as shown in the following screenshot.

  • Validate in the Solution Explorer in the Controllers folder that you have the new TopicController.cs file, in the Views folder you should also have the Topic folder as shown in the following screenshot.

 

** Note! there is a folder in the Views, while it is not required Views and Controllers are usually tied together. When you name a new Controller with the suffix “Controller”, Visual Studio will create the View folder automatically
In the Project explorer make sure that you have the TopicController.cs selected and in the code window replace it with the following code.

using System.Web;
using System.Web.Mvc;
 
namespace MvcMovie.Controllers
{
    public class TopicController : Controller
    {
        //
        // GET: /Topic/
 
        public string Index()
        {
            return "This is the <b>default</b> action...";
        }
 
        //
        // GET: /Topic/Welcome/
 
        public string Welcome()
        {
            return "This is the Welcome action method...";
        }
    }
}

Accessing the Controller

If the traditional ASP.NET Web Form application have user interactions organized around pages, raising and handling events from these pages and their form controls, then MVC applications are organized around controllers and action methods. A controller contains actions methods that typically have a one-to-one mapping with user interactions. For example, entering a URL into a browser causes a request to the server. The MVC application uses routing rules defined in the Global.asax file to parse the URL and to determine the path of the controller. The controller then determine the appropriate action method to call to handle the request.

By default a web request in an MVC application is treated as a sub-path that includes the controller names followed by the action name. For example is a user enters the

URL:http://www.yourdomain.com/product/category/1

The sub path evaluated is product/category/1. The default routing rule will treat product as the prefix name of the controllers (which must end in Controller). It will treat Category as the name of the action. In this case the routing rule will invoke the category method of the product controller in order to process the request. By default the value of 5 in the URL will be passed to the Detail method as a parameter.

Take a look at how this works with our application.

  • Press F5 to start the application and validate that you see a similar URL as shown in the following screenshot

  • Append the URL of the application with the string /Topic and then refresh the screen as shown in the following screenshot

  • Append the URL of the application with the string /Topic/Welcome and then refresh as shown in the following screenshot

 



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