155

In the default ASP.NET MVC 3 project, layout & partial cshtml files start with an underscore

  • _viewstart
  • _Layout
  • _LogOnPartial

Why this convention, and what is this used for? Do I need to follow this convention?

Does the framework give some special meaning to a .cshtml file that begins with an underscore?

Sнаđошƒаӽ
  • 16,753
  • 12
  • 73
  • 90
richb
  • 4,716
  • 5
  • 24
  • 22
  • I use NancyFX with Razor and since by default it restricts any content that's not in the Content folder. (This can be overridden in web.config or custom config) it's impossible to serve any files at all such as .cshtml directly. So I don't use "_" prepended to my view names because it's NOT necessary and ugly. – Norbert Norbertson May 19 '16 at 09:35

6 Answers6

219

Razor was developed for ASP.NET Web Pages (WebMatrix), which doesn't have the same sort of protection built in regarding Views folders and Routing that you get within MVC. Since layout pages in Web Pages are not intended to be served directly, they are prefixed with the underscore. And the Web Pages framework has been configured not to allow files with leading underscores in their names from being requested directly. Other .cshtml files within Web Pages generally need to be browsable. They are the equivalent of .asp or .php files.

The ASP.NET team have stated that Web Pages is a starting point within ASP.NET development, which should lead to migration to MVC in time (for those that want to move on). Part of that means that it should be as easy as possible to migrate from Web Pages to MVC. Consequently, it makes sense to carry over naming conventions established within Web Pages to MVC Razor files.

So there is a technical reason for prefixing the file names with an underscore - it just isn't relevant to MVC.

[UPDATE Oct 2018]

In the new ASP.NET Core Razor Pages framework (apart from in version 2.1), files with a leading underscore are ignored when routes are being generated at startup - even if they have an @page directive (which would normally make them a routeable Razor Page). That's why it makes sense to name layout and partial files with a leading underscore in a Razor Pages application if they are not intended to be browsed.

Mike Brind
  • 28,238
  • 6
  • 56
  • 88
  • 6
    Thanks. For me this is the most insightful answer. I was under the misapprehension that Razor was tied to MVC. Now I see the reason for the leading underscore is to prevent them from being served directly under ASP.NET Web Pages. – richb Jan 03 '11 at 01:53
  • 1
    A naming convention that actually has a functionality tied in, I thought MS would know better. And now it's carried over to MVC, which was supposed to be a clean slate. – Boris B. May 28 '12 at 12:39
  • Hopefully after the current .NET Framework 4.5.1 and Visual Studio 2013 releases including "One ASP.NET" functionality they can finally move away from these technical limitations/hard-coding. Of course having standard files never shared is essential as with current *.config, APP_Code and APP_Data directories. But this logic should sit in a config file somewhere (machine config as default) so it can be overridden. Also these default names of common pages should be configurable (Layout/Error/etc...). – Tony Wall Feb 07 '14 at 11:05
  • And for those files that instead of an underscore, it has a ~ symbol? So something like ~_viewStart.cshtml ? Is it maybe like files commented out? – Leo Jan 18 '18 at 10:15
  • This doesn't actually work, at least not when hosted on IIS Express. Underscored `@page` files in /Pages/Shared can be access when visiting localhost:.../Shared/_pageName. Since omitting `@page` seems to avoid direct access already, I'll be ignoring the underscore functionality as its a bit esoteric. – Daniel Oct 15 '18 at 23:02
  • @Daniel Not sure what you mean. If I try to browse to /shared/_somepage in a Razor Pages site, I get a 404, which is what I would expect. – Mike Brind Oct 16 '18 at 06:52
  • @MikeBrind I find if I navigate to any resource directly, which doesn't have the `@page` razor markup, it'll show 404. I don't need the underscore '_' to do that. – Daniel Oct 16 '18 at 21:18
  • 1
    @Daniel Oh, I see what you mean. I have edited the answer because it doesn't work as advertised. – Mike Brind Oct 17 '18 at 07:35
  • 1
    @Daniel What you are seeing is apparently a bug that surfaced in Razor Pages 2.1. It is scheduled to be fixed in 2.2. It works as I described in 2.0. – Mike Brind Oct 18 '18 at 14:45
  • @MikeBrind ah thank you. Yes i'm using 2.1 currently. – Daniel Oct 18 '18 at 18:37
  • Strangely, the default file name of a _view component_ [searched for](https://learn.microsoft.com/en-us/aspnet/core/mvc/views/view-components?view=aspnetcore-3.0#view-search-path) in ASP.NET Core is `Default.cshtml`, not `_Default.cshtml`. – Marc Sigrist Oct 22 '19 at 15:38
12

That's how Ruby on Rails does it (Partials start with a _ but the Render Partial call does not include the _), and ASP.net MVC has drawn heavy inspiration from it.

No technical reason really, just a convention to clearly show the intent to other developers (and yourself 6 months later) to say: This is a partial view.

Michael Stum
  • 177,530
  • 117
  • 400
  • 535
  • this is incorrect, as pointed out by the answer above - underscore has a security functionality. – iJungleBoy Jul 02 '17 at 11:40
  • 1
    @iJungleBoy See the accepted answer. for ASP.net MVC (which this question is about), there is no security functionality. See the web.config in the Views folder that already blocks all cshtml and aspx files, underscore or not (sets up `System.Web.HttpNotFoundHandler` for them). – Michael Stum Jul 02 '17 at 21:58
9

Pages that cannot be shown by direct requests from your browser (master pages, partial views etc) have underscore (_) in the beginning of their names.

So if you try to make the request to _Layout.cshtml (this is master page) you will get an error from server.

Its a way of distinguishing the files that can`t be browsed as stand alone pages, in Razor view engine.

Think of it this way... in MVC 2 ... you would differentiate the partial view and the mastersite with the sufix .master, .ascx, and normal pages are .aspx, on the other hand, in Razor view... all views are .cshtml, so to distinguish partial and masterpages they will have a prefix (_). its nothing mandatory, just a "convention".

Juztin
  • 157
  • 2
  • 8
  • 4
    But by that logic wouldn't ALL cs & cshtml files be prefixed with an underscore? – richb Jan 02 '11 at 01:01
  • if all files would have _ as a prefix then your site wouldnt work... files that have _prefix are rendered inside a normal page...(for partials), and the sitemaster is a template... so it must have content to be displayed. – Juztin Jan 02 '11 at 01:05
  • So I just tried this, and IIS on my box doesn't serve any files from the Views, directory. Not even static .html files. So I really don't think this is the answer. – richb Jan 02 '11 at 01:08
  • Juztin: The question is why do they begin with an underscore? If I rename _Layout.cshtm to Layout.cshtml it still works just fine. So what is the reason for this convention? – richb Jan 02 '11 at 01:11
  • Can you justify the first sentence with any evidence? – nick Jan 03 '11 at 21:15
  • @nick The evidence is in this answer: http://stackoverflow.com/questions/4576548/why-does-razor-layout-cshtml-have-a-leading-underscore-in-file-name/4577799#4577799 – bzlm Mar 06 '11 at 12:52
  • 2
    The question is about asp.net mvc, not webpages – fabspro Sep 27 '12 at 15:29
2

As far as I know this is simply a convention used to identify the intent of the file; I don't believe it will actually change the behavior of the file. In most development contexts, prepending an underscore identifies something to be meant for "private" use, whether by a class, or in this case, another template.

futureal
  • 3,025
  • 1
  • 22
  • 33
2

Right-click on the Index.cshtml file and select View In Browser. From this, we can test the index.html page in the browser(with out running the app).

Do the same for _Layout.cshtml page, it will show you error or browser will render the default page(Home/Index.cshtml).

Because the pages prefixed with _ will not be tested through browser.

We can test those pages(_Layout. cshtml) by embedding with another cshtml pages.

John Conde
  • 217,595
  • 99
  • 455
  • 496
CoCo
  • 137
  • 2
  • 8
1

I dont use MVC, but with web pages which also uses the razor syntax, the _ prefix generally siginifies that the page is not meant to be accesssed by a user but by other pages or some code. If you try to navigate to a page that contains the _prefix, asp.net would prevent access to it. Thats why its used with layout pages and other such pages since they should not be accessed directly by a user.

Something like the App_Code folder in asp.net

Travis
  • 21
  • 1
  • @MikeBrind You can't 'navigate' to/browse directly *any* of the views under `/view` in a default ASP.NET MVC project; the `/views/web.config` file is set up to prevent it. But there's *nothing* to prevent a controller action from returning `View("_Index", model);` It works just fine; I just did it by changing a view's name to _Index.cshtml and changing the action to call as I did above. – Andrew Barber Nov 26 '12 at 13:03
  • @MikeBrind This question is about MVC, not Web Pages. Granted; I did not specify that in my original comment. – Andrew Barber Nov 27 '12 at 18:16
  • @MikeBrind I was - and am - responding to *this* answer. Not yours. My initial comment was misleading (I did also mention "partials", though), so I have deleted it. My point was and is that underscores have *nothing* to do with not being able to load a view in MVC. This user even started saying, "I don't use MVC", yet this question was about MVC. I'm just making sure someone coming along later reading *this* answer doesn't somehow think that in MVC, an underscore affects the ability of a controller action to load a view. No big deal. We agree I was inartful in how I spoke. Done. – Andrew Barber Nov 27 '12 at 20:47