Windows 2012 Hosting - MVC 6 and SQL 2014 BLOG

Tutorial and Articles about Windows Hosting, SQL Hosting, MVC Hosting, and Silverlight Hosting

ASP.NET Core Hosting :: Which is Better? ASP.NET Core Razor Pages or MVC?

clock March 4, 2019 10:50 by author Jervis

With the release of new ASP.NET Core 2 framework, Microsoft and its community has provided us with a brand new alternative for the MVC (Model-View-Controller) approach. Microsoft has named it Razor Pages, and while it’s a little bit different approach, but it’s still similar to MVC in some ways.

In this article, we are going to cover following important points of ASP.NET Razor Pages.

  • Razor Pages — what is it exactly?
  • Drawbacks of Using ASP.NET MVC
  • Advantages of Using Razor Pages
  • A Quick Comparison of How Requests Are Handled in Both

Razor Pages — What is It Exactly?

A Razor Page is very similar toASP.NET MVC’s view component. It has basically same syntax and functionality as MVC.

The key difference between Razor pages and MVC is that the model and controller code is also included within the Razor Page itself.

In simple terms, it is much like am MVVM (Model-View-View-Model) framework. It provides two-way data binding and a simpler development experience with isolated concerns.

Though MVC works fine with web apps that have large amount of dynamic server views, single page apps, REST APIs, and AJAX calls, but Razor Pages are perfect for simple pages that are read-only or do basic data input.

Now, the ASP.NET MVC has been extremely popular for web applications development, and it definitely has its benefits. In fact, the ASP.NET WebForms was specifically designed as an MVVM solution in MVC.

But, the new ASP.NET Core Razor Pages is the next evolution of ASP.NET WebForms.

Drawbacks of ASP.NET MVC

As most of you probably know, MVC stands for Model-View-Controller. It is an architectural pattern used in software development for implementing UI (user interfaces).

While MVC is one of the most popular framework and is being used by millions of web developers worldwide, but it still has its drawbacks. Let’s look at the two most important of them.

#1 — Complexity

In ASP.NET MVC, there are piles of concepts such as TempData, RouteCollection, ViewData, Linq to SQL, Controller Action, Lambda Expression, Custom Route, and HTML Helpers, all of which tie the Model, View, and Controller.

Now, you cannot build a web application using ASP.NET MVC until you learn all these basic concepts. Plus, even if you’ve learned them, you will still face complexity issues at times, especially when you’re building large-scale applications.

#2 — Cost of Frequent Updates

In ASP.NET MVC, web developers cannot completely ignore the view of the model even when both are separated. The reason is because when the model is changed frequently, the views of your application could be flooded with update requests.

Views are basically graphical displays which takes some time to render depending on the complexity of your application. And if your application is complex and the model has been changed a lot, then the view may fall behind update requests. So, the developers then need to spend extra time fixing this situation, resulting into higher costs.

Advantages of Using Razor Pages

We’ve been providing ASP.NET MVC development services for about 10 years now. In fact, we’re certified Microsoft Gold Partner. So, based on our knowledge, experience, and expertise, there are two main benefits of using ASP.NET Core razor pages instead of MVC.

#1 — Razor Pages is Better Organized

If you’ve ever used MVC for any kind of web development, then you probably know that how much time it takes to code an entire app. Creating dynamic routes, naming things properly, and hundred other stuff consumes a lot of time.

Razor Pages, on the other hand, is more organized compared to MVC.

In Razor Pages, the files are basically more organized. You have a Razor View and the entire code behind a file, same way the old ASP.NET WebForms did.

#2 — Single Responsibility

Again, if you have ever used an MVC framework before, you have probably seen that there are some huge controller classes which are generally filled with a lot of various actions. These classes are like a virus which grows bigger and bigger as new things are added.

But, in Razor Pages, each app page is self-contained with its own view and code organized together, which as a results, is less complex than the MVC.

Overall, ASP.NET Core is a Modular Web Framework.

In MVC, if you add new things, then the .NET framework will force you to release a new version.

For example, Microsoft released routing in MVC 4, and later, they released Attribute routing for which they again had to release another new framework MVC 5.

In ASP.NET Core, on the other hand, everything is managed using the NuGet package, which means it is easier than MVC to upgrade existing framework without releasing new .net framework version every time new things are added.

Additionally, In .NET Core, any community can release an update for new NuGet package version, and you can receive the latest changes by just updating your NuGet packages.

A Quick Comparison of How Requests Are Handled in Both

We explained in above points that building a web application using ASP.NET Core Razor Pages is less complex than the MVC. Here, we will demonstrate that with action.

Let’s start with MVC

Here’s a quick overview of how MVC handles the requests.

 

As you can see, routing is the key to how MVC decides to handle requests. The default configuration for routing is the combination of action and controller names.

So if you request for /staff/index, then it will route you the action named Index on the StaffController class.

But, it can be customized or configured to route any request to any controller with a block of code.

Now Compare the Same with Razor Pages

Here’s a quick overview of how Razor Pages handle the requests.

The difference between the two is that in Razor Pages, when you make a request, the default routing configuration will find a Razor Page for that specific request in the Pages folder.

Suppose you make a request for /contact/, then ASP.NET Core will look for a page having same name that you used in request and will route you directly to it.

That means, a request to /contact/ will route you to Contact.cshtml

And for any .cshtml file to be considered as a Razor Page, it must be placed in the Pages folder and also contain @Page in its markup.

This way, the Razor Page will then act as a controller action. Now comparing this to MVC, the configuring the custom route will be less complex as there will no extra coding involved.

In Conclusion

Razor Pages seem like a promising start for modern web app development with less complexity in 2018. And as the comparison has shown that it provides the benefit of containing everything related to a particular request at one place, where in MVC requires spreading pieces all around your app like a giant puzzle which you will then have to put back together with extra efforts of coding.



ASP.NET MVC Hosting - ASPHostPortal :: Session State Performance Issue in ASP.NET MVC

clock January 15, 2016 20:54 by author Jervis

I cannot recall any real Web Application that doesn’t make use of the Session State feature, the one that is capable to store data that are available across multiple requests from the same browser. More over, in this very modern times, Web Applications tends to make extensive use of Ajax requests to the server, in order to avoid page refreshes. So the question here is, have you ever noticed performance issues while making multiple ajax requests to an ASP.NET MVC action when using Session data?

Put Session into the Context

Before demonstrating the real problem with coding, let’s find out the basics on how Session works. When a new request is arrived to the server for the first time, which means no session cookie is contained, the server will create a new session identifier accessible through the

System.Web.HttpContext.Current.Session.SessionID

Though, this does not mean that from now on all requests back to server will contain a session cookie. Instead, this will happened only if a specific request store some data in the Session. In other words,ASP.NET Framework adds the session cookie to the response at the first time some data is stored in the session. So how is this related to performance issues? Well, normally ASP.NET can process multiple requests from the same browser concurrently which means for example, multiple Ajax requests can be processed simultaneously.

The above schema works only when no session cookie is contained in browser’s request or in other words, server hasn’t yet stored any data into the Session. If server does store some data into the session and hence adds a session cookie in the response, then all subsequent requests using the same session cookie are queued and proccessed sequentially.

This is actually a normal behavior, cause consider for example that multiple requests may modify or read the same Session key value simultaneously. That would certainly result in inconsistent data.

Code time

Create an ASP.NET Empty Web Application checking the MVC option and add the following HomeController.

[OutputCache(NoStore = true, Duration = 0)]
    public class HomeController : Controller
    {
        public List<string> boxes = new List<string>() { "red", "green", "blue", "black", "gray", "yellow", "orange" };
        // GET: Home
        public ActionResult Index()
        {
            return View();
        } 

        public string GetBox()
        {
            System.Threading.Thread.Sleep(10);
            Random rnd = new Random();
            int index = rnd.Next(0, boxes.Count); 

            return boxes[index];
        } 

        public ActionResult StartSession()
        {
            System.Web.HttpContext.Current.Session["Name"] = "Jervis"; 

            return RedirectToAction("Index");
        }
    }

The controller has a GetBox which returns a random color from a list of colors defined in the class. We will use it’s value to add a div element in the view having the background-color property set accoarding the returned value. More over, has a StartSession action which simply stores a session value and hence it’s the point that the server adds a session cookie into the response. You will need to add the Index view so right click in the index method, add it and paste the following code.

<!DOCTYPE html>
<html lang="en" ng-app="asyncApp">
<head>
    <title>Troubleshooting ASP.NET MVC Performance Issues</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap-theme.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.js"></script>
    <link href="~/Content/Site.css" rel="stylesheet" />
</head>
<body ng-controller="asyncCtrl" ng-init="getBoxes()">
    <nav role="navigation" class="navbar navbar-default navbar-fixed-top">
        <div class="container-fluid">
            <!-- Brand and toggle get grouped for better mobile display -->
            <div class="navbar-header">
                <button type="button" data-target="#navbarCollapse" data-toggle="collapse" class="navbar-toggle">
                    <span class="sr-only">Toggle navigation</span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
            </div>
            <!-- Collection of nav links and other content for toggling -->
            <div id="navbarCollapse" class="collapse navbar-collapse">
                <ul class="nav navbar-nav">
                    <li class="active"><a href="#">Performace testing</a></li>
                    <li>
                        @Html.ActionLink("Start Session", "StartSession")
                    </li>
                    <li>
                        <a class="links" ng-click="getBoxes()">Not resolved</a>
                    </li>
                    <li>
                        <a class="links" ng-click="getBoxes(true)">Resolved</a>
                    </li>
                    <li>
                        <form class="navbar-form">
                            <label class="checkbox" style="margin-top:5px">
                                @Html.CheckBox("isSessionNewChk", Session.IsNewSession, new { @disabled = "disabled" })
                                Is Session New
                            </label>
                        </form>
                    </li>
                </ul>
                <ul class="nav navbar-nav navbar-right">
                    <li><a href="#">{{boxes.length}} Boxes</a></li>
                </ul>
            </div>
        </div>
    </nav>
    <br /><br /><br />
    <div class="container">
        <div class="row">
            <div id="boxesContainer" ng-repeat="color in boxes track by $index">
                <div class="box" ng-class="color" />
            </div>
        </div>
        <br />
        <div class="row">
            <div id="timeOccured" ng-show="showResults" class="alert" ng-class="isResolved()" ng-bind="timeElapsed"></div>
        </div>
    </div>
    <script src="~/Scripts/app.js"></script>
</body>
</html>

Add a Content folder in the root of your application and create the following css stylesheet.

.box {
    height: 15px;
    width: 15px;
    margin: 2px;
    float:left;
} 

#timeOccured {
    clear:both;
} 

.links {
    cursor:pointer;
} 

.red {
    background-color: red;
} 

.green {
    background-color: green;
} 

.blue {
    background-color: blue;
} 

.black {
    background-color: black;
} 

.gray {
    background-color: gray;
} 

.yellow {
    background-color: yellow;
} 

.orange {
    background-color: orange;
}

You will have noticed that I make use of simple AngularJS code but that’s OK if you aren’t familiar with it. Add a Scripts folder and create the following app.js javascript file.

angular.module('asyncApp', [])
    .value('mvcuri', 'http://localhost:49588/home/getbox')
    .value('mvcurisessionresolved', 'http://localhost:49588/SessionResolved/getbox')
    .controller('asyncCtrl', function ($http, $scope, mvcuri, mvcurisessionresolved) { 

        $scope.boxes = [];
        $scope.showResults = false;
        var uri; 

        $scope.getBoxes = function (resolved) {
            var start = new Date();
            var counter = 300; 

            if (resolved)
                uri = mvcurisessionresolved;
            else
                uri = mvcuri; 

            // Init variables
            $scope.boxes = [];
            $scope.showResults = false;
            $scope.timeElapsed = ''; 

            for (var i = 0; i < 300; i++) {
                $http.get(uri)
                    .success(function (data, status, headers, config) {
                        $scope.boxes.push(data);
                        counter--; 

                        if (counter == 0) {
                            var time = new Date().getTime() - start.getTime();
                            $scope.timeElapsed = 'Time elapsed (ms): ' + time;
                            $scope.showResults = true;
                        }
                    })
                        .error(function (error) {
                            $scope.timeElapsed = error.Message;
                        }).finally(function () {
                        });
            }
        }; 

        $scope.isResolved = function () {
            return uri == mvcuri ? 'alert-danger' : 'alert-success';
        } 

    });

Make sure you replace the localhost:port with yours. Before explain all application’s functionality let’s add a new MVC controller named SessionResolvedController.

[OutputCache(NoStore = true, Duration = 0)]
    public class SessionResolvedController : Controller
    {
        public List<string> boxes = new List<string>() { "red", "green", "blue", "black", "gray", "yellow", "orange" }; 

        public string GetBox()
        {
            System.Threading.Thread.Sleep(10);
            Random rnd = new Random();
            int index = rnd.Next(0, boxes.Count); 

            return boxes[index];
        }
    }

At this point you should be able to fire your application.

So what is happening here? When the application starts, 300 Ajax calls are sent to the HomeController’sGetBox action and foreach color returned a respective box is added to the view.

<body ng-controller="asyncCtrl" ng-init="getBoxes()"> 

<div id="boxesContainer" ng-repeat="color in boxes track by $index">
     <div class="box" ng-class="color" />
 </div>

Every time you refresh the Page you will notice that the Is Session New checkbox is checked, which means that there isn’t yet a session cookie sent to the browser. All Ajax requests are processed concurrently as expected and the time elapsed to complete all the ajax calls is displayed in a red box under all boxes. The Start Session button will simply store a session value as follow.

System.Web.HttpContext.Current.Session["Name"] = "Jervis";

Press the button and notice the difference in the elapsed time for displaying all the 300 boxes. Also notice that the checkbox isn’t checked anymore.

Now that there is a Session cookie in each request to the server, all requests are proccessed sequentially as described previously. That’s why we need twice the time we needed before storing a session variable. You can repeat the same ajax requests without refreshing the page by clicking the Not Resolved button.

Solution

At the moment, if you press the Resolved button you will get the same results calling theSessionResolvedController’s GetBox() action.

<a class="links" ng-click="getBoxes(true)">Resolved</a>

Notice that we don’t read or modify any Session state data when calling the GetBox() actions, so the question is, is there anything that we can do to prevent our requests being processed sequentially despite the fact that they contain a cookie session? The answer is YES and it’s hidding in the SessionState attribute that can be applied in the controller’s class as follow:

[SessionState(SessionStateBehavior.Disabled)]
    public class SessionResolvedController : Controller
    {
        public List<string> boxes = new List<string>() { "red", "green", "blue", "black", "gray", "yellow", "orange" }; 

        public string GetBox()
        {
            System.Threading.Thread.Sleep(10);
            Random rnd = new Random();
            int index = rnd.Next(0, boxes.Count); 

            return boxes[index];
        }
    }

Applying this attribute to the controller will make all requests targeting this controller processed concurrently. Build, run your application and repeat what we did before. Notice that the Resolved button now finishes at the half time which was the time needed when no session cookie existed in the request.

I run the application without debugging in order to get better results. If you run with debugging you will get higher delays but that should not be a problem, the differences will be still noticeable.

And following is a complete demonstration of what we have done till now. When I fired the application for the first time, it tooked 928 milliseconds to complete all 300 Ajax requests. Then I clicked to create a Session cookie and that caused an important performance issue increasing the delay to 2201 milliseconds! When I requested the data through the SessionResolvedController the delay was almost the same when there wasn’t any Session cookie.

I have also used the

[OutputCache(NoStore = true, Duration = 0)]

to the MVC Controllers which will result to ask the browser (client) not to store the content retrieved from the server. This way the test is even more reliable.



About ASPHostPortal.com

We’re a company that works differently to most. Value is what we output and help our customers achieve, not how much money we put in the bank. It’s not because we are altruistic. It’s based on an even simpler principle. "Do good things, and good things will come to you".

Success for us is something that is continually experienced, not something that is reached. For us it is all about the experience – more than the journey. Life is a continual experience. We see the Internet as being an incredible amplifier to the experience of life for all of us. It can help humanity come together to explode in knowledge exploration and discussion. It is continual enlightenment of new ideas, experiences, and passions

 photo ahp banner aspnet-01_zps87l92lcl.png

Author Link

Corporate Address (Location)

ASPHostPortal
170 W 56th Street, Suite 121
New York, NY 10019
United States

Sign in