Learning new things needs an investment of time, space and energy. I am currently learning Asp.Net Core MVC 2.0. This ASP.NET Core tutorials overview states:
Razor Pages is the recommended approach to create a Web UI with ASP.NET Core
This information confused me in deciding whether I have to stop learning Asp.net Core MVC and start learning Asp.net Core Razor Pages.
Why is Razor Pages the recommended approach to create a Web UI in Asp.net Core?
Any directions are welcome.
From this article in Microsoft docs:
MVC: Using controllers and views, it was common for applications to have very
large controllers that worked with many different dependencies and view models and returned many
different views. This resulted in a lot of complexity and often resulted in controllers that didn’t follow
the Single Responsibility Principle or Open/Closed Principles effectively.
Razor Pages addresses this
issue by encapsulating the server-side logic for a given logical “page” in a web application. A Razor Page that has no server-side logic can simply consist of a Razor file (eg. “Index.cshtml”). However, most non-trivial Razor Pages will have an associated page model
class, which by convention is named the same as the Razor file with a “.cs” extension (for example, “Index.cshtml.cs”). This page model class combines the responsibilities of a Controller and a ViewModel. Instead of handling requests with controller action methods, page model handlers like “OnGet()” are
executed, rendering their associated page by default.
Razor pages simplify the process of building
individual pages in an ASP.NET Core app, while still providing all the architectural features of ASP.NET Core MVC. They are a good default choice for new page-based functionality.
When to use MVC:
If you’re building web APIs, the MVC pattern makes more sense than trying to use Razor Pages.
If your project will only expose web API endpoints, you should ideally start from the Web API project
template, but otherwise it’s easy to add controllers and associated API endpoints to any ASP.NET Core
app. You should also use the view-based MVC approach if you’re migrating an existing application
from ASP.NET MVC 5 or earlier to ASP.NET Core MVC and you want to do so with the least amount of
effort. Once you’ve made the initial migration, you can evaluate whether it makes sense to adopt
Razor Pages for new features or even as a wholesale migration.
Note:
Whether you choose to build your web app using Razor Pages or MVC views, your app will have
similar performance and will include support for dependency injection, filters, model binding, validation, etc.
Update: Some more reasons i read on this github issue commented by scott sauber:
We're using Razor Pages for a [complex] Health Insurance portal... We have 60+ pages and I can say that for Server-rendered HTML, I will never go back to MVC. It's also not just for simple things. The Health Insurance domain is inherently complex and combine this with the fact that it's a multi-tenant app (we sell the product to other insurance companies), which adds more complexity as the app is highly configurable as different insurance companies do things a bit differently.
Why use it?
Razor Pages is more secure by default. Razor Pages gives you AntiForgeryToken validation by default. Plus you opt-in to what properties you want to be model bound via [BindProperty] which limits your exposure to over-posting attacks.
Razor Pages has a better folder structure by default that scales better. In MVC, the default folder structure simply does not scale. Having separate folders for Views, Controllers, and often ViewModels when all three are ultimately tightly coupled to one another is a huge PITA to work with. You end up bouncing to all 3 folders and navigating a bunch anytime you need to add or change a feature. It's horrible. This is why I advocated for Feature Folders. With Razor Pages, your PageModel (Controller + ViewModel) are in the same folder as your View. You can just hit F7 to toggle between them which is also super convenient.
Leads to more maintainable code that scales better. With MVC it was super easy to bloat a Controller with 10+ Actions. Often, these Actions weren't even related to one another in any way (except maybe a Redirect between the two). This made navigating the Controller to find code very difficult. It got worse if there were private methods in the Controller too, further adding to the method bloat. With Razor Pages, it's nearly impossible to bloat up your Page Model with unrelated methods to your page. Everything you put in your PageModel is related to your Page.
Unit Testing is easier. With a Controller, you might have 8 Actions and some of your dependencies you inject in were only related to one or two Actions. So when unit testing a single Action either you need to mock those out unnecessarily or pass a null, both of which feels gross (this can be solved a bit with the Builder pattern). With Razor Pages, the dependencies you inject in are 100% related to GET and POST actions you're working with. It just feels natural.
Routing is easier. By default in Razor Pages, routing just matches your folder structure. This makes nesting folders way easier to accomplish. For instance, all of our HR Admin pages are under the /Administrator folder and all the Employee pages are under the /Employee folder. We can authorize an entire folder and say the person must be an Administrator to get to any subfolder of /Administrator, which was way easier to do that than with multiple Controllers that make up the Administrator features.
I think that's the big stuff.
Update 2:
This is about some complexity of MVC pattern, does not directly answer the question but can be useful: An Engineering Manager at Facebook, said (here) for their “sufficiently” large codebase and large organization, “MVC got really complicated really quickly,” concluding that MVC does not scale. The complexity of the system went exponential every time they attempted to add a new feature making the code “fragile and unpredictable.” This was becoming a serious problem for developers new to a certain codebase because they were afraid to touch the code lest they might break something. The result was MVC was falling apart for Facebook.
Razor Pages are optimized for page-based workflows and can be used in these scenarios with fewer moving parts than traditional MVC models. This is because you don't need to deal with Controllers, Actions, Routes, ViewModels, and Views (as you typically would). Instead your route is convention-based, and your PageModel serves as your Controller, Action(s), and ViewModel all in one. The page, of course, replaces the View. You also don't have to have as many folders as you would in MVC, further simplifying your project.
From ASP.NET Core - Simpler ASP.NET MVC Apps with Razor Pages, a Sept. 2017 MSDN article by Steve Smith:
[Razor Pages] provide
a simpler way to organize code within ASP.NET Core applications, keeping implementation logic and view models closer to the view implementation code.
They also offer a simpler way to get started developing ASP.NET Core apps,
That article has more information on why to use Razor Pages over MVC for page-based workflows. Obviously, for APIs, you will still want to use Controllers.
3rd party edit - disadvantages of classical MVC folder organization
ASP.NET Core - Feature Slices for ASP.NET Core MVC, an older MSDN article from Sept. 2016, describes why the classical MVC convention to organize views and controller might have disadvantages for larger projects. The article gives an example of four loosely related application concepts: Ninjas, Plants, Pirates and Zombies. The article outlines a way to structure them outside of the default folder convention by organizing files into folders by feature or area of responsibility.
Microsoft is coming back to the WebForms approach to simplify the project structure trusting in the "Convention over configuration" mantra, while hiding the configuration from developer to make things faster. But it has the disavantage that everything will be mixed again. It doesn't look like a smart move for organizing. But... Hey! Something new must catch the attention of the dev towards Microsoft.
If your page uses an MVC Web API for the REStful, it's really more easy to just use Razor pages. If not, I would recommend you to use Core MVC.
In huge projects, where the model and controller are together in the same file, maintenance will be a nightmare. It works well for clases that are just 2 properties long, but it violates the Open Close Principle of OOP. You should design and use an architecture that can grow with time (Extensible) and still be stable and logic(No reestructuring the project), just extend it using the same pattern.
As a Software Architect I use design patterns automatically. What I like a lot is the Facade design pattern. You hide everything related to Home behind a HomeController and you can do the same with Repositories.
Want to know a funny thing? A tour guide explained where the name
Facade comes from. In Amsterdam you have big houses across the waters.
From the outside they look luxureous. But from the behind they can be
messy. The facade of the house hides whats behind it. Design patterns
comes from the building world. Well whats behind in my applications
also looks good but it was nice to know from the tour guide about the
explanation.
What about support for Sharing and Grouping actions in Razor pages. If you look at MVC Controllers you can see that you can Group controller actions based on functionality. You could say the Home page is such a functionality. Then you have a HomeController with About() and Contact() in it, but with Razor Pages this would be different pages. May be you have a big HomeController with lets say 5 other Views in it. They can all be grouped in the same HomeController.
A Controller has two things a Razor Pages does not have:
Sharing: You can share Controller actions between different pages, sometimes controller actions are not bound only to one page but can be shared between several pages. Remember Controller actions can also only return Data (JSON/XML/etc). Sometimes what they return can be used by different pages too.
Grouping: You can group related Controller actions together in one Controller. Ok if you are a fan of small Controller files you won't do this. I do. I group my Controllers based on functionality. That makes navigation much easier.
What is the Razor pages way of handling this: Use of directories I think:
Grouping: If we have the HomeController, then we could make a subdirectory Home with all the Home pages in it.
Question: For a simple Home that would be enough. But lets say we have an XController that uses for all actions the same Repository. You could initialize that Repository in the Initializer function of the XController. But for pages in the X subdirectory you would have to do that for all X actions again. Is that DRY?
Sharing: You could make a "Share" subdirectory and under that, directories with functionality that should be shared between pages.
Question: If you look at my fix you can see I use directories to solve the Share and Grouping problem of Razor pages.
How would you do this?
or...are Razor pages just meant to be for simple websites, could this be the conclusion for this version of Razor pages.
Blazor server has a strange architecture. It looks like a chat application by use of SignalR. My experience with applications like that is that events can get lost. I don't want to lose events, better is they are stacked and guaranteed to be processed like mail.
Developers were on forums in 2013 asking "What does Microsoft mean, Silverlight is not the recommended ...???"
Only this time, it is that MVC is going to be pronounced dead and long live MVVM.
And you can likely expect MVC to be thrown to the scrap heap, slowly, but sped up in about 18 months from now, and any and all time you spent learning MVC will go to that same scrap heap.
Also, MVVM looks easy but it takes a year to get the hang of it and really do it right.
I am working on an web application/site and I want to do it with AngularJS, ASP.NET and Typescript.
I read about the Single Page Application concept, but I still have some question about this whole concept:
Why should I prefer a SPA (Single Page Application) before multiple pages.
I also have some questions about integrating it with ASP.NET:
In ASP.NET it standard generate a nice bootstrap layout with about 3 pages at the top. So I think that it means that I need to combine all these pages to one page. But how can I get it to work together with the routing of ASP.NET. Because you will use the routing of AngularJS, and I want to keep the login from ASP.NET (Can you maybe give an example so I can see how it works).
If I got it correctly Typescript in this concept will replace the JSON webservice. Is this correct or do I got this all wrong?
If you could answer one of my questions I would be very thankful.
SPA's are a trend, they are mostly useful to move the load on your server to the clients. Only data requests will be made to the server, rendering is done on the client machine.
There are still other benefits, but I guess this is the most relevant.
As to your questions regarding integration into ASP.NET.
Building an SPA does not mean all has to fit in one page. Look at AngularJS, it will fetch views as separate requests (see templateUrl in routingprovider). That being said, you can use ASP.NET MVC and serve ASP.NET Views as Angular Templates. This allows for a neat separation of Model, View and Controller parts.
Typescript is Microsoft's JavaScript dialect. It will not replace JSON and you will probably want to use JSON to exchange data with your server. You could use XML, but that is a little bit oldfashioned (and way more bulky).
I have no experience with TypeScript so I would not consider doing that (coffee might be a better alternative), but there are also some quicks in JavaScript you need to be aware of. I would suggest to search Douglas Crockford and Javascript on Youtube. The guy has great talks that can make you a JavaScript pro.
I have to develop an application which takes XML reports stored in File System parse it and put it into database and display the reports by querying the database in various MIME types(XML,JSON,RSS and HTML). So what I have done till now is parsed the XML reports in the file system ,setup schema for database in MongoDB,put data in database using Spring-data and also managed to have a web service which shows rough draft of reports in XML,JSON and RSS feed.Now I want to display the reports in HTML as well and my supervisor suggested me to use Backbone.js to dispaly it in HTML format by calling the web service.Kindly advice me to choose b/w Backbone.js or write another Spring MVC web service which generates reports in HTML.
Thanks in advance
Swaraj
What you are asking are two different things and choosing between them.
You have to know what your overall objective is with the webapp is and what framework is best for it.
Short answer, Spring MVC integrates with Dojo.js right out of the box, which might do what you need to do, but since your supervisor is suggesting otherwise your options are:
Use Spring MVC to construct and display the data in the HTML using what ever render of your choice.
Or
Build out your Spring MVC wepapp API so that you can use a JavaScript MVC framework, such as Backbone.js or one of the many others (see TODOMVC for samples), to interact with your spring controllers.
Option 1 might be easy enough, used in conjunction with JavaScript or jQuery and plugins
Option 2 would be good if your webapp is complex and will be mostly a SPA (single page app) that utilizes a lot of JavaScript and you want a way to organize your js code better. See JavaScript MVC diagram for an example of how it works.
I was curious how in the typical ASP.NET MVC mentality one could build a platform that others could develop plugins for. I mean, how would those plugins look like?
Like exiting user controls for WebForms, encapsulating all layers in themselves, or three different files representing the model the view and the controller. I should develop the core of a CMS, that I'd like others to build plugins for later on. Which mentality is better for that, classic Web Forms or ASP.NET MVC?
I need developers to be able to separately build components for that. Is it possible to encapsulate the MVC directory structure in a component DLL file and then when I reference the DLL file, to be able to directly access the component's model, view, or controller as part of the general MVC structure?
The most promising component techniques have come from the guys over at lostechies.com and Mvccontrib in the form of Portable Areas. Portable Areas allows an entire MVC app to be appended onto an existing application. So its not just a UI component but also provides all the work flow and screen integration as well.
Open Forum does something like this as well. I don't know how, but it is very plug and play.
For straight up plugin architecture there is an interesting screencast and source code for Rob Connery's link text. He takes advantage of the App-Code directory to slide new plugins into place without having to edit the main site.
I currently develop with Django, but want to be ready when a future client inevitably requests a site done in ASP.NET MVC. While most of the structure and flow of ASP.NET MVC is more or less identical to Django and RoR, the one part I'm not sure about is the Apps methodology Django employs to make code reuse easier.
Is there an equivalent to Django apps in ASP.NET MVC? That is, can I create a feature, like tagging, comments, calendar of events, simple blog, etc. and bundle it up, making it portable to other projects with a minimum of glue code required to integrate it? Perhaps some kind of plugin or module system?
Django doesn't follow the traditional MVC pattern, since they advocate that in the Web world, their MTV is more suitable. In the overall, I prefer Django over Rails because of the django apps. You can do almost the same in RoR with the Rails vendor plugins, but it's not the same.
ASP.NET follows RoR structure, and therefor you don't have the reusable apps. If you check the folder structure in a MVC project, you don't even find the RoR's Plugin folder, so I bet you should do it VisualStudio-Like.
Create a reusable app, as a separated project, include references for that project in your main one, and in your Route file, just redirect to the other project's controllers.
This might be of interest as well: App Areas
we've tried to do something similar, albeit from a different angle. we use compositional controllers for increased reusability in bistro, and an ndjango as the templating language. what we start to see is controllers become more granular, and as a result less dependent on where they reside - more componentizable.