Showing posts with label Prof ASP.NET MVC 5. Show all posts
Showing posts with label Prof ASP.NET MVC 5. Show all posts
Sunday, May 17, 2015
Professional ASP.NET MVC 5 code download page
http://www.wrox.com/WileyCDA/WroxTitle/Professional-ASP-NET-MVC-5.productCd-1118794753,descCd-DOWNLOAD.html
Monday, May 4, 2015
chapter 12 Angular Js
(function () {
var app = angular.module("atTheMovies", []);
}());
The angular variable is the global Angular object. Just like the jQuery API is available
through a global $ variable, Angular exposes a top-level API through angular. In the previous
code, the module function creates a new module named atTheMovies, whereas the
second parameter, the empty array, declares dependencies for the module (technically this
module depends on the core Angular module “ng”, but you don’t need to list it explicitly
and you’ll see examples of other dependencies later in the chapter).
Also modify the Index view to include the new script:
@section scripts {
<script src="~/Scripts/angular.js"></script>
<script src="~/Client/Scripts/atTheMovies.js"></script>
}
<div ng-app="atTheMovies">
</div>
Notice the div element in the code now specifi es a value for the ng-app directive. The markup
instructs Angular to load atTheMovies as the application module. This allows you to configure
additional components into the module that are initialized when Angular bootstraps the application.
The application needs these additional components to achieve the first goal...
Creating Controllers, Models, and Views
Angular controllers are objects you use to govern a section of the DOM and set up a model. Angular
controllers are stateful and live as long as their associated area of the DOM is still on display. This
behavior makes controllers in Angular a little different from their counterparts in ASP.NET MVC,
where controllers process a single HTTP request and then go away
(function(app) {
var ListController = function() {
};
app.controller("ListController", ListController);
}(angular.module("atTheMovies")));
The preceding code defi nes a ListController function
The function is registered with Angular as a constructor by
calling the application module’s controller method. The first parameter is the name of the controller
(Angular looks up the controller using this name), and the second parameter is the constructor function associated with the name. Although the controller doesn’t perform any interesting behavior yet, the markup inside the Index view can now put the controller in charge of a section of the DOM (after including the new ListController.js script).
@section scripts {
<script src="~/Scripts/angular.js"></script>
<script src="~/Client/Scripts/atTheMovies.js"></script>
<script src="~/Client/Scripts/ListController.js"></script>
}
<div ng-app="atTheMovies">
<div ng-controller="ListController">
</div>
</div>
The ng-controller directive attaches the ListController to a div inside the application. Angular
finds the controller by name and creates the controller. By adding an Angular template to the
markup, you’ll see a controller, view, and model:
<div data-ng-app="atTheMovies">
<div ng-controller="ListController">
{{message}}
</div>
</div>
The controller is the ListController, the view is the HTML, and the view wants to display a piece
of information from the model using a template with the expression message inside. Making the
message available is the controller’s responsibility, which requires some additional code:
(function(app) {
var ListController = function($scope) {
$scope.message = "Hello, World!";
};
app.controller("ListController", ListController);
}(angular.module("atTheMovies")));
The $scope variable is an object constructed by Angular and passed as a parameter to the controller
function. The controller’s responsibility is to initialize $scope with data and behavior, because
$scope is ultimately the model object consumed by the view.
➤ Controllers are responsible for putting together a model by augmenting the $scope variable.
Controllers avoid manipulating the DOM directly. Instead, changes in the UI are propagated
by updating information in the model that the view consumes.
➤ The model object is unaware of the view and controller. The model is only responsible for
holding state as well as exposing some behavior to manipulate the state.
➤ The view uses templates and directives to gain access to the model and present information.
This separation of concerns in an Angular application is closer to the Model View View
Model (MVVM) design pattern in XAML-based applications than it is to a true MVC design
pattern. Some additional abstractions are still available with Angular, including the concept of services. The ListController must use a service to retrieve the movies from the server.
var app = angular.module("atTheMovies", []);
}());
The angular variable is the global Angular object. Just like the jQuery API is available
through a global $ variable, Angular exposes a top-level API through angular. In the previous
code, the module function creates a new module named atTheMovies, whereas the
second parameter, the empty array, declares dependencies for the module (technically this
module depends on the core Angular module “ng”, but you don’t need to list it explicitly
and you’ll see examples of other dependencies later in the chapter).
Also modify the Index view to include the new script:
@section scripts {
<script src="~/Scripts/angular.js"></script>
<script src="~/Client/Scripts/atTheMovies.js"></script>
}
<div ng-app="atTheMovies">
</div>
Notice the div element in the code now specifi es a value for the ng-app directive. The markup
instructs Angular to load atTheMovies as the application module. This allows you to configure
additional components into the module that are initialized when Angular bootstraps the application.
The application needs these additional components to achieve the first goal...
Creating Controllers, Models, and Views
Angular controllers are objects you use to govern a section of the DOM and set up a model. Angular
controllers are stateful and live as long as their associated area of the DOM is still on display. This
behavior makes controllers in Angular a little different from their counterparts in ASP.NET MVC,
where controllers process a single HTTP request and then go away
(function(app) {
var ListController = function() {
};
app.controller("ListController", ListController);
}(angular.module("atTheMovies")));
The preceding code defi nes a ListController function
The function is registered with Angular as a constructor by
calling the application module’s controller method. The first parameter is the name of the controller
(Angular looks up the controller using this name), and the second parameter is the constructor function associated with the name. Although the controller doesn’t perform any interesting behavior yet, the markup inside the Index view can now put the controller in charge of a section of the DOM (after including the new ListController.js script).
@section scripts {
<script src="~/Scripts/angular.js"></script>
<script src="~/Client/Scripts/atTheMovies.js"></script>
<script src="~/Client/Scripts/ListController.js"></script>
}
<div ng-app="atTheMovies">
<div ng-controller="ListController">
</div>
</div>
The ng-controller directive attaches the ListController to a div inside the application. Angular
finds the controller by name and creates the controller. By adding an Angular template to the
markup, you’ll see a controller, view, and model:
<div data-ng-app="atTheMovies">
<div ng-controller="ListController">
{{message}}
</div>
</div>
The controller is the ListController, the view is the HTML, and the view wants to display a piece
of information from the model using a template with the expression message inside. Making the
message available is the controller’s responsibility, which requires some additional code:
(function(app) {
var ListController = function($scope) {
$scope.message = "Hello, World!";
};
app.controller("ListController", ListController);
}(angular.module("atTheMovies")));
The $scope variable is an object constructed by Angular and passed as a parameter to the controller
function. The controller’s responsibility is to initialize $scope with data and behavior, because
$scope is ultimately the model object consumed by the view.
➤ Controllers are responsible for putting together a model by augmenting the $scope variable.
Controllers avoid manipulating the DOM directly. Instead, changes in the UI are propagated
by updating information in the model that the view consumes.
➤ The model object is unaware of the view and controller. The model is only responsible for
holding state as well as exposing some behavior to manipulate the state.
➤ The view uses templates and directives to gain access to the model and present information.
This separation of concerns in an Angular application is closer to the Model View View
Model (MVVM) design pattern in XAML-based applications than it is to a true MVC design
pattern. Some additional abstractions are still available with Angular, including the concept of services. The ListController must use a service to retrieve the movies from the server.
Thursday, October 23, 2014
Prof ASP.NET MVC 5 Ch 4 Notes
Page 78
Visual Studio has a useful snippet for creating auto-implemented properties
(properties implemented with the { get; set; } syntax shown in the previous
code.) To quickly create an auto-implemented property, type prop and press
the Tab key twice to expand the snippet and set the cursor selection on the property
type text. The default property value for this snippet is int; if you need to
change it (for example, to string, decimal, and so on) you can just type in the
new value. Next, press Tab twice to advance to the property name. After typing
that in, you can press the Enter key to advance to the end of the line. This snippet
comes in handy when you create new model classes.
www.it-
Page 80
What Is Scaffolding?
In the Adding a View section of Chapter 3, you saw that the Add View dialog allows you to select a
template, which is then used to create view code for you. This code generation is known as scaffolding,
and it can do a lot more than just create views.
Scaffolding in ASP.NET MVC can generate the boilerplate code you need for create, read, update,
and delete (CRUD) functionality in an application.
Page 84
Domain-driven design (DDD) is
one approach that teams use to tackle complex applications. Command-query
responsibility segregation (CQRS) is also a pattern gaining mindshare among teams
wrestling with diffi cult applications.
Some of the popular design patterns used in DDD and CQRS include the repository
and unit of work design patterns. For more information on these design patterns,
see http://msdn.microsoft.com/en-us/library/ff714955.aspx. One of
the advantages to the repository pattern is that you can create a formal boundary
between the data access code and the rest of your application. This boundary can
improve the ability to unit test your code, which is not one of the strengths of the
code generated by the default scaffolding (because of hard-coded dependencies on
the Entity Framework).
Page 86 book is different from VS2013 update3

Page 88
A QUICK INTRODUCTION TO ENTITY FRAMEWORK
DATA MIGRATIONS (this book is short of this section, I added below)
http://azure.microsoft.com/en-us/documentation/articles/web-sites-dotnet-deploy-aspnet-mvc-app-membership-oauth-sql-database/
PM> Enable-Migrations More than one context type was found in the assembly 'ProMVC5Ch4'. To enable migrations for 'ProMVC5Ch4.Models.ApplicationDbContext', use Enable-Migrations -ContextTypeName ProMVC5Ch4.Models.ApplicationDbContext. To enable migrations for 'ProMVC5Ch4.Models.ProMVC5Ch4DB', use Enable-Migrations -ContextTypeName ProMVC5Ch4.Models.ProMVC5Ch4DB. PM> Enable-Migrations -ContextTypeName ProMVC5Ch4.Models.ProMVC5Ch4DB Checking if the context targets an existing database... Code First Migrations enabled for project ProMVC5Ch4. PM> Update-Database Specify the '-Verbose' flag to view the SQL statements being applied to the target database. No pending explicit migrations. Unable to update database to match the current model because there are pending changes and automatic migration is disabled. Either write the pending model changes to a code-based migration or enable automatic migration. Set DbMigrationsConfiguration.AutomaticMigrationsEnabled to true to enable automatic migration. You can use the Add-Migration command to write the pending model changes to a code-based migration. PM> Add-Migration cmdlet Add-Migration at command pipeline position 1 Supply values for the following parameters: Name: Initial Scaffolding migration 'Initial'. The Designer Code for this migration file includes a snapshot of your current Code First model. This snapshot is used to calculate the changes to your model when you scaffold the next migration. If you make additional changes to your model that you want to include in this migration, then you can re-scaffold it by running 'Add-Migration Initial' again. PM> Update-Database Specify the '-Verbose' flag to view the SQL statements being applied to the target database. Applying explicit migrations: [201410241500330_Initial]. Applying explicit migration: 201410241500330_Initial. Running Seed method. PM>
Put seed method in file below:
E:\Projects\test\ProMVC5Ch4\ProMVC5Ch4\Migrations\Configuration.cs
namespace ProMVC5Ch4.Migrations
{
using System;
using System.Data.Entity;
using System.Data.Entity.Migrations;
using System.Linq;
using ProMVC5Ch4.Models;
internal sealed class Configuration : DbMigrationsConfiguration<ProMVC5Ch4.Models.ProMVC5Ch4DB>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
}
protected override void Seed(ProMVC5Ch4.Models.ProMVC5Ch4DB context)
{
// This method will be called after migrating to the latest version.
// You can use the DbSet<T>.AddOrUpdate() helper extension method
// to avoid creating duplicate seed data. E.g.
//
// context.People.AddOrUpdate(
// p => p.FullName,
// new Person { FullName = "Andrew Peters" },
// new Person { FullName = "Brice Lambson" },
// new Person { FullName = "Rowan Miller" }
// );
//
context.Artists.Add(new Artist { Name = "Al Di Meola" });
context.Genres.Add(new Genre { Name = "Jazz" });
context.Albums.Add(new Album
{
Artist = new Artist { Name = "Rush" },
Genre = new Genre { Name = "Rock" },
Price = 9.99m,
Title = "Caravan"
});
base.Seed(context);
}
}
}
To publish to Azure, need to check setting in publish to make sure it can connect to Azure SQL db
Visual Studio has a useful snippet for creating auto-implemented properties
(properties implemented with the { get; set; } syntax shown in the previous
code.) To quickly create an auto-implemented property, type prop and press
the Tab key twice to expand the snippet and set the cursor selection on the property
type text. The default property value for this snippet is int; if you need to
change it (for example, to string, decimal, and so on) you can just type in the
new value. Next, press Tab twice to advance to the property name. After typing
that in, you can press the Enter key to advance to the end of the line. This snippet
comes in handy when you create new model classes.
www.it-
Page 80
What Is Scaffolding?
In the Adding a View section of Chapter 3, you saw that the Add View dialog allows you to select a
template, which is then used to create view code for you. This code generation is known as scaffolding,
and it can do a lot more than just create views.
Scaffolding in ASP.NET MVC can generate the boilerplate code you need for create, read, update,
and delete (CRUD) functionality in an application.
Page 84
Domain-driven design (DDD) is
one approach that teams use to tackle complex applications. Command-query
responsibility segregation (CQRS) is also a pattern gaining mindshare among teams
wrestling with diffi cult applications.
Some of the popular design patterns used in DDD and CQRS include the repository
and unit of work design patterns. For more information on these design patterns,
see http://msdn.microsoft.com/en-us/library/ff714955.aspx. One of
the advantages to the repository pattern is that you can create a formal boundary
between the data access code and the rest of your application. This boundary can
improve the ability to unit test your code, which is not one of the strengths of the
code generated by the default scaffolding (because of hard-coded dependencies on
the Entity Framework).
Page 86 book is different from VS2013 update3
Page 88
A QUICK INTRODUCTION TO ENTITY FRAMEWORK
DATA MIGRATIONS (this book is short of this section, I added below)
http://azure.microsoft.com/en-us/documentation/articles/web-sites-dotnet-deploy-aspnet-mvc-app-membership-oauth-sql-database/
PM> Enable-Migrations More than one context type was found in the assembly 'ProMVC5Ch4'. To enable migrations for 'ProMVC5Ch4.Models.ApplicationDbContext', use Enable-Migrations -ContextTypeName ProMVC5Ch4.Models.ApplicationDbContext. To enable migrations for 'ProMVC5Ch4.Models.ProMVC5Ch4DB', use Enable-Migrations -ContextTypeName ProMVC5Ch4.Models.ProMVC5Ch4DB. PM> Enable-Migrations -ContextTypeName ProMVC5Ch4.Models.ProMVC5Ch4DB Checking if the context targets an existing database... Code First Migrations enabled for project ProMVC5Ch4. PM> Update-Database Specify the '-Verbose' flag to view the SQL statements being applied to the target database. No pending explicit migrations. Unable to update database to match the current model because there are pending changes and automatic migration is disabled. Either write the pending model changes to a code-based migration or enable automatic migration. Set DbMigrationsConfiguration.AutomaticMigrationsEnabled to true to enable automatic migration. You can use the Add-Migration command to write the pending model changes to a code-based migration. PM> Add-Migration cmdlet Add-Migration at command pipeline position 1 Supply values for the following parameters: Name: Initial Scaffolding migration 'Initial'. The Designer Code for this migration file includes a snapshot of your current Code First model. This snapshot is used to calculate the changes to your model when you scaffold the next migration. If you make additional changes to your model that you want to include in this migration, then you can re-scaffold it by running 'Add-Migration Initial' again. PM> Update-Database Specify the '-Verbose' flag to view the SQL statements being applied to the target database. Applying explicit migrations: [201410241500330_Initial]. Applying explicit migration: 201410241500330_Initial. Running Seed method. PM>
Put seed method in file below:
E:\Projects\test\ProMVC5Ch4\ProMVC5Ch4\Migrations\Configuration.cs
namespace ProMVC5Ch4.Migrations
{
using System;
using System.Data.Entity;
using System.Data.Entity.Migrations;
using System.Linq;
using ProMVC5Ch4.Models;
internal sealed class Configuration : DbMigrationsConfiguration<ProMVC5Ch4.Models.ProMVC5Ch4DB>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
}
protected override void Seed(ProMVC5Ch4.Models.ProMVC5Ch4DB context)
{
// This method will be called after migrating to the latest version.
// You can use the DbSet<T>.AddOrUpdate() helper extension method
// to avoid creating duplicate seed data. E.g.
//
// context.People.AddOrUpdate(
// p => p.FullName,
// new Person { FullName = "Andrew Peters" },
// new Person { FullName = "Brice Lambson" },
// new Person { FullName = "Rowan Miller" }
// );
//
context.Artists.Add(new Artist { Name = "Al Di Meola" });
context.Genres.Add(new Genre { Name = "Jazz" });
context.Albums.Add(new Album
{
Artist = new Artist { Name = "Rush" },
Genre = new Genre { Name = "Rock" },
Price = 9.99m,
Title = "Caravan"
});
base.Seed(context);
}
}
}
To publish to Azure, need to check setting in publish to make sure it can connect to Azure SQL db
Wednesday, October 22, 2014
Asp.net Mvc 5 Ch 1-3 notes
Page 12 Claim-based authentication
page 45 Httputility.htmlencode
page 56
To avoid needing to specify a fully qualifi ed type name for the model, you can make use of the @using declaration.
@using MvcMusicStore.Models @model IEnumerable<Album> <ul>
www.it-ebooks.info
Strongly Typed Views ❘ 57
@foreach (Album p in Model) { <li>@p.Title</li> } </ul>
An even better approach for namespaces, which you’ll end up using often in views, is to declare the namespace in the web.config file within the Views directory.
<system.web.webPages.razor> …
<pages pageBaseType="System.Web.Mvc.WebViewPage">
<namespaces>
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
<add namespace="MvcMusicStore.Models" />
</namespaces> </pages> </system.web.webPages.razor>
page 56
To avoid needing to specify a fully qualifi ed type name for the model, you can make use of the @using declaration.
@using MvcMusicStore.Models @model IEnumerable<Album> <ul>
www.it-ebooks.info
Strongly Typed Views ❘ 57
@foreach (Album p in Model) { <li>@p.Title</li> } </ul>
An even better approach for namespaces, which you’ll end up using often in views, is to declare the namespace in the web.config file within the Views directory.
<system.web.webPages.razor> …
<pages pageBaseType="System.Web.Mvc.WebViewPage">
<namespaces>
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
<add namespace="MvcMusicStore.Models" />
</namespaces> </pages> </system.web.webPages.razor>
To see the previous
two examples in action, use NuGet to install the Wrox.ProMvc5.Views
.AlbumList package into a default ASP.NET MVC 5 project,
as follows:
Install-Package
Wrox.ProMvc5.Views.AlbumList
This places the two
view examples in the \Views\Albums folder and the controller code in the \
Samples\AlbumList
folder. Press Ctrl+F5 to run the project and visit /albums/listweaklytyped
and /albums/liststronglytyped to see the result of
the code.
Page 65
following Razor snippet?
@{ string rootNamespace = " MyApp"; }
< span >@ rootNamespace.Models </ span >
In this particular case, the hoped-for output was: < span > MyApp.Models </ span > Instead, you get an error that there is no Models property of string. In this admittedly edge case, Razor couldn’t understand your intent and thought that@ rootNamespace.Models was the code expression. Fortunately, Razor also supports explicit code expressions by wrapping them in parentheses: < span >@( rootNamespace). Models </ span > This tells Razor that.Models is literal text and not part of the code expression. While we’re on the topic of code expressions, we should also look at the case where you intend to show an e-mail address. For example, consider the following e-mail address: < span > support@ megacorp.com </ span >
Page 67
@{ string rootNamespace = " MyApp"; }
< span >@ rootNamespace.Models </ span >
In this particular case, the hoped-for output was: < span > MyApp.Models </ span > Instead, you get an error that there is no Models property of string. In this admittedly edge case, Razor couldn’t understand your intent and thought that@ rootNamespace.Models was the code expression. Fortunately, Razor also supports explicit code expressions by wrapping them in parentheses: < span >@( rootNamespace). Models </ span > This tells Razor that.Models is literal text and not part of the code expression. While we’re on the topic of code expressions, we should also look at the case where you intend to show an e-mail address. For example, consider the following e-mail address: < span > support@ megacorp.com </ span >
But, of course, what
if you really did mean for this to be an expression? For example, going back to
an earlier example in this section, what if you had the following list items:
<li>Item_@item.Length</li>
In this particular
case, that expression seems to match an e-mail address, so Razor will print it
out verbatim. But it just so happens that you expected the output to be
something like:
<li>Item_3</li>
Once again,
parentheses to the rescue! Any time there’s an ambiguity in Razor, you can use
parentheses to be explicit about what you want. You are in control.
<li>Item_@(item.Length)</li>
As mentioned earlier,
you can escape the @ sign with an @@
sign. This comes in handy when you need to display some Twitter handles, which
conventionally start with an @ sign:
<p>
You should follow
@aspnet </p>
Well, Razor is going
to attempt to resolve those implicit code expressions and fail. In the case
where you need to escape the @ sign, you can do so by using an @@
sign. Thus, this view becomes:
<p>
You should follow
@@aspnet </p>
Fortunately, the extra parentheses and escape
sequences are rarely needed. Even in very large applications these extra bits
of sequences might not be used at all. Rest assured that the Razor view engine
was designed with terseness in mind and that you won’t have to fight it to get
what you want, how you want it.
HTML Encoding
Given that many cases
exist where a view is used to display user input, such as a blog post comment
or a product review, the potential always exists for cross-site script
injection attacks (also known as XSS, which Chapter 7 covers in more detail).
The good news is that Razor expressions are automatically HTML encoded.
@{
string message =
"<script>alert('haacked!');</script>";
}
<span>@message</span>
This code does not
result in an alert box popping up but instead renders the encoded HTML:
<span><script>alert('haacked!');</script></span>
However,
in cases where you intend to show HTML markup, you can return an instance of System
.Web.IHtmlString
and Razor will not encode it. For example, all the view helpers discussed later
in this section return instances of this interface because they want HTML to be rendered
to the page. You can also create an instance of HtmlString
or use the Html.Raw convenience method:
@{
string message = "<strong>This is
bold!</strong>";
}
<span>@Html.Raw(message)</span>
This results in the
message being displayed without HTML encoding:
<span><strong>This
is bold!</strong></span>
Page 67
When setting variables
in JavaScript to values supplied by the user, using JavaScript string encoding
and not just HTML encoding is important. Use the @Ajax.JavaScriptStringEncode
to encode the input. Here’s the same code again using this method to better
protect against XSS attacks:
<script
type="text/javascript">
$(function () {
var message = 'Hello
@Ajax.JavaScriptStringEncode(ViewBag.Username)';
$("#message").html(message).show('slow'); });
</script>
Page 69
Unencoded Code Expression
In some cases, you
need to explicitly render some value that should not be HTML encoded. You can
use the Html.Raw method to ensure that the value is not
encoded.
<span>@Html.Raw(model.Message)</span>
Mixing Code and Plain Text
Mixing Code and Plain Text
Razor looks for the
beginning of a tag to determine when to transition from code to markup.
However, sometimes you want to output plain text immediately after a code
block. For example, the following sample displays some plain text within a
conditional block.
@if
(showMessage) {
<text>This is plain text</text>
} or
@if
(showMessage) { @:This is plain text. }
Server-Side Comment
Razor includes a nice
syntax for commenting out a block of markup and code.
@*
This is a
multiline server side comment.
@if
(showMessage) {
<h1>@ViewBag.Message</h1> }
All of this
is commented out.
*@
Calling a Generic Method
And as you’ve learned,
angle brackets cause Razor to transition back to markup unless you wrap the
whole expression in parentheses. @(Html.SomeMethod<AType>())
Page 70-72
Layouts
Layouts in Razor help
maintain a consistent look and feel across multiple views in your application.
If you’re familiar with Web Forms, layouts serve the same purpose as master
pages, but offer both a simpler syntax and greater flexibility.
SiteLayout.cshtml:
<!DOCTYPE
html>
<html>
<head><title>@ViewBag.Title</title></head>
<body>
<h1>@ViewBag.Title</h1>
<div
id="main-content">@RenderBody()</div> <footer>@RenderSection("Footer")</footer>
</body>
</html>
Option 1
<footer>@RenderSection("Footer",
required: false)</footer>
Option 2
<footer>
@if (IsSectionDefined("Footer")) {
RenderSection("Footer");
}
else {
<span>This is the default
footer.</span>
}
</footer>
@{
Layout =
"~/Views/Shared/SiteLayout.cshtml";
ViewBag.Title = "The Index!"; }
<p>This
is the main content!</p>
Page 73
When you create a
default ASP.NET MVC project, you’ll notice a _ViewStart.cshtml
fi le is already in the Views directory. It specifi es a default layout:
@{
Layout =
"~/Views/Shared/_Layout.cshtml"; }
SPECIFYING
A PARTIAL VIEW
The partial view
itself looks much like a normal view, except it doesn’t specify a layout:
<h2>@ViewBag.Message</h2>
Install-Package
Wrox.ProMvc5.Views.SpecifyingViews
This adds a sample
controller to your project in the samples directory with multiple action
methods, each specifying a view in a different manner. To run each sample
action, press Ctrl+F5 on your project and visit:
➤ /sample/index
➤ /sample/index2
➤ /sample/index3
➤ /sample/partialviewdemo
Subscribe to:
Posts (Atom)