Monday, April 21, 2014

MVA Course: Developing ASP.NET MVC 4 Web Applications Jump Start (Modules 3 & 4)

Cover writing controllers and views.  Visual Studio has a lot of tools to help make this very easy. With some practice should be possible to deploy applications very fast with scaffolding and templates and such.




Note Dump:

*******************************************************************************************
MODULE 3
*******************************************************************************************

Lesson 1: Writing Controllers and Actions
- Responding to User Requests
- Writing Controller Actions
- Using Parameters
- Passing Information to Views
- Demonstration
- Filters

Responding to User Requests
When an MVC web application receives a user request, the following events occur:
MVCHandler creates a controller factory.
'-> Controller factory creates a Controller object and MVCHandler calls the Execute
    method.
    '-> ControllerActionInvoker  examines RequestContext and determines the action to
        call.
        '-> ControllerActionInvoker determines the values to be passed to the action as
            parameters.
'-> ControllerActionInvoker runs the action.

// don't panic, this isn't something we need every day
// users in MVC don't navigate to a page, instead they are making calls against a
// controller.  Calling a method on a class basically.

Question: What is the condition that you must follow while creating controllers?
Answer: You should ensure that controller names end with “Controller”. Otherwise, you
will receive unexpected 404 errors and controllers will not work as intended. If you
create a custom controller factory, you can define your own naming convention for
controller classes.
You can discuss controller factories in this module because students should know how to
create controller classes. However they will be discussed in full later in this lesson,
in the final topic.
The code example on the slide includes a simple action called Index. When you create a
controller in Microsoft Visual Studio, this action method is included automatically,
even when you choose the Empty controller template.

Writing Controller Actions
Writing a Controller action includes:
- Create public method
- Return a class that derives from ActionResult
- Add parameters to the method
- Insert code to perform the operation and return the result // do stuff
// a controller action can be returned as a string as well.

Using Parameters
http://www.adventureworks.com/session/getsessionbytitle?title=MVC101
                                                      |
                                              DefaultModelBinder
                                                     /
public ActionResult GetSessionByTitle(string title){
   var query = from s in context.Sessions
        where s.Title == title
        select s
   Photo session = query.FirstOrDefault();
   return View("Details", session);
}
// helper method finds the right view
// specifying that we want a view called "Details", passing it the object session

Question: How does DefaultModelBinder pass parameters?
Answer: The DefaultModelBinder locates parameters in a posted form, the routing values,
the query string, or in the posted files. When it finds a parameter in the action
method that matches the name and type of a parameter from the request, the action
method is called and the parameter is passed from the request.
Remind the students that the DefaultModelBinder class was discussed in the last module
along with the controller action invoker. It provides a very flexible and easy-to-use
method of binding parameters to the right action method, and this method should be used
whenever possible.

Passing Data to the View
Model
- View(data)
- Strongly typed, can be more flexible
- More complex
// going to get intellisense and compile errors
// this is the best way to pass data
// well organized
ViewBag
- Dynamic object for storing basic pieces of information
- Alias for ViewData
- Perfect for sending messages to the view
- Only available for that action
    - Redirects cause the ViewBag to be emptied
// good if you want to just pass one little peice of data rather than a whole
// complex data object
TempData
- Just like the ViewBag, but it’s also available on the next page
// hangs around after redirect
// rachel appel has a blog post about all these

[DEMO]
// Ctrl+M, Ctrl+C is shortcut to create a controller.
// templates available to simplify creating a controller with specific operations already
// in place.
// Index() is typically the default, usually just lists something.
// Can find views two ways - either pass a name, or leave blank and MVC will look for a
// view matching the name of the action, so Index() will look for the view called "Index"
// "create" or creating entries works much differently than web forms.
// we have a "GET" method and a "POST" method, the GET create returns the view that
// is used to create entries, and the POST method is used to actually write the data
// we want to keep the user informed on what is happening
// Before we write anything, we should check that the data entered is valid, check with
// (!ModelState.IsValid), also pass back the data so the user can see what was not valid
// Model aware controls can use a controler action to get its data
// Some web forms features carry over because the ASP.NET team works on everything
// You can display error to user with ModelState.AddModelError("Error",e.message)
// If we are creating the same methods over and over, we can centralize in one spot and
// inherit every time we need it. Using genarics is helpful
// scaffolding can give you a huge amount of code (demo writes it by hand so we can see
// how it works)
// database context gives us an interface to the database. Entity Framework actually
// creates the database.

What are Filters?
Some requirements cut across logical boundaries are called cross-cutting concerns.
Examples include:
- Authorization
- Logging
- Caching
There are four different types of filters:
- Authorization filters run before any other filter and before the code in the action
  method
- Action filters run before and after the code in the action method
- Result filters run before and after a result is returned from an action method.
- Exception filters run only if the action method or another filter throws an exception.

MVC filters can cause confusion for students who are familiar with request and response
filters in ASP.NET Web Forms applications, which can perform transformation operations
of the request and response streams. If you have advanced ASP.NET students in the
class, ensure that they are clear about these entirely different kinds of filters.
You will see how to configure authentication and authorization, and how to use the
Authorize attribute on controllers and actions, in Module 11.
Question: Which filter type will you use for the following actions?
Intercepting an error
Modifying a result
Authorizing users
Inspecting a returned value
Answer: The following filter types can be used to perform the actions.
Intercepting an error – Exception filters
Modifying a result – Result filters
Authorizing users – Authorizing filters
Inspecting a returned value – Action filters
// action is based on the route, and routes can change. Filtes let us change how
// our code behaves.
// Can add an annotation to our method to require authorization
// [Authorize()] - just have to be logged in
// [Authorize(Roles = "Administrators")] only admins have access to action
// uses built in authorization filter
// this can be on a class or an action method. If on a class, then everthing in the
// controller has the filter applied to it
// FilterConfig in App_Start is where we apply our global filters.
// Filters live in the Filters folder
// Question: what about ViewModels? Models don't have to map to a database, possible to
// create a metaclass that pulls information from multiple places. ViewModel bundles up
// data and passes it to the view

*******************************************************************************************
MODULE 4
*******************************************************************************************

Lesson 1: Creating Views with Razor Syntax

// controllers and models are behind the scenes, getting the data to users involves
// using a view
// Razor is basically HTML that allows you to drop in C#

Adding Views
 - Applying Styles to ASP.NET MVC 4 Web Applications.
Question: You are using the Razor view engine and Visual Basic to create views. You
right-click the Delete action in the CustomerController.vb file. What is the name of the
view file that Visual Studio will create by default?
Answer: The file name will be Delete.vbhtml unless you specify another name. It will be
created in the Views/Customer folder.
// right click, add "View" while in an action result to create a view for it

Features of Razor Syntax
A sample code block displaying the features of Razor.
@* Some more Razor examples *@
<span>
Price including Sale Tax: @Model.Price * 1.2 // this would display $1.50 * 1.2
</span>
<span>
Price including Sale Tax: @(Model.Price * 1.2) // this would display $1.80
</span>

@if (Model.Count > 5)
{
 <ol>
   @foreach(var item in Model)
   {
      <li>@item.Name</li>
   }
 </ol>
}
Point out to the students that Razor easily differentiates content from code. For
example, even within a Razor code block, when you add an HTML element such as <div>,
Razor interprets the text as content. You do not usually need to use the @: delimiter to
make this explicit.
Discuss the example code on the slide. Ensure that students understand the HTML that
Razor will render.
Question: You want to describe a code block to developers in your view file. You do not
want your description to be passed to the browser. What syntax should you use?
Answer: Declare the description as a Razor comment by enclosing it in @* *@ delimiters.
// Razor generally does a good job picking out the code versus the HTML
// Key to writing Razor is not to overthink it

Binding Views to Model Classes and Displaying Properties
You can use strongly-typed views and include a declaration of the model class. Visual
Studio helps you with additional IntelliSense feedback and error-checking as you write
the code.
Binding to Enumerable Lists:

@model IEnumerable<MyWebSite.Models.Product>
<h1>Product Catalog</h1>
@foreach (var Product in Model)
{
   <div>Name: @Product.Name</div>
}

You can use dynamic views to create a view that can display more than one model class.
The code example in the slide shows how to use a strongly-typed view when the action
controller passes a list of objects of a specific model class.
Question: You want to write a view that displays ten objects of the Photo model class.
What model declaration should you use?
Answer: Use a declaration in the following form: @model
IEnumerable<projectname/Models/Photo>
// when we are using strongly typed views, we aren't doing a bunch of casting, we
// get Intellisense, compile errors instead of runtime errors

[DEMO]
// have to build before we can scaffold, because we need to create the models to use in
// the scaffolding process.
// If we didn't already have a context, we could tell VS to create a context for us.
// Creates action results for Index, Details, Create, Edit, Delete as well as Views for
// each.
// Doesn't display primary key (apparently it has a bit of sense)
// Ajax validation can be spoofed, so it's important to have server side validation
// annotations on model make it simple to keep client side and server side validation
// in sync
// @Html.EditorFor() html helper goes back to annotations on model to create the
// appropriate controls to edit the field
// MVC4 has responsive design built in

Differentiating Server Side Code from HTML
Razor identifies server-side code by looking for the @ symbol.
In Razor syntax, the @ symbol has various uses. You can:
- Use @ to identify server-side C# code
- Use @@ to render an @ symbol in an HTML page.
- Use @: to explicitly declare a line of text as content and not code.
- Use <text>to explicitly declare several lines of text as content and not code.
To render text without HTML encoding, you can use the Html.Raw() helper.
// automatically does Html encoding, so it should be safe from XSS attack
// validation checks data on way into database, should also check it on the way out.
// can't take for granted that what is in the database is safe

Lesson 2: Using HTML Helpers
- Using Action Helpers
- Using Display Helpers
- The Begin Form Helper
- Using Editor Helpers
- Using Validation Helpers
- Demonstrations
If you have students who are familiar with Web Forms, you might like to contrast MVC HTML
helpers with Web Forms server controls. Helpers perform an analogous role in MVC to the
role that server controls play in Web Forms. However, helpers are simpler and
lighter-weight. They do not render large blocks of HTML and JavaScript code or ViewState
data. Also, they do not support event handlers.

***Using Action Helpers***
Html.ActionLink()
@Html.ActionLink("Click here to view photo 1",
   "Display", new { id = 1 })
<a href="/photo/display/1">
   Click here to view photo 1
</a>
// generates a full anchor tag

Url.Action()
<img alt="This image came from an action"
   src="@Url.Action("GetImage", new { id = 1 })" />
<img
   alt="This image came from an action"
   src="/photo/getimage/1" })"
/>
// just generates the URL, not the whole anchor tag

The action helpers described in this topic examine the routes defined in your web
application to render the correct URLs. Students have not yet learned about the routing
engine or how to modify routes. They will learn about routing in Module 7.
Question: You want to render an HTML5 <audio> tag to play a sound file from an action.
Would you use the Html.ActionLink() helper or the Url.Action() helper?
Answer: You would use the Url.Action() helper because you are rendering an attribute
within the <audio> tag, and not a complete <a> element.


***Using Display Helpers***
Html.DisplayNameFor()
@Html.DisplayNameFor(model => model.CreatedDate)
Created Date
// reads out the label for data

Html.DisplayFor()
@Html.DisplayFor(model => model.CreatedDate)
03/12/2012
// reads out the data itself

Question: You want to ensure that a view displays “This product was last changed on”
before the ModifiedDate property. This text is declared in the class with the DisplayName
annotation. What code would you write in the view?
Answer: @Html.DisplayNameFor(model => model.ModifiedDate)

***The Begin Form Helper***
Html.BeginForm()
@using (Html.BeginForm("Create", "Photo",
FormMethod.Post,
   new { enctype = "multipart/form-data" }))
{
   @* Place input controls here *@
}
<form action="/Photo/Create" method="post“
   enctype="multipart/form-data">

</form>
// writes out a begin and end tags for a form, plus attributes
// @Html.AntiForgeryToken() prevents spoofing the form. Two part thing: token must be
// written, and the action result much confirm that the token is correct.
// Why use Html Helpers? The metadata helps Razor display everything correctly. If we
// have to change something, we do it once on the class instead of running around and
// changing HTML all over the place

Question: You have created a form with a file selector control that uses the GET method.
You have set the enctype attribute to multipart/form-data but when you try to access the
file in the action method, an exception is thrown. What have you possibly done incorrectly?
Answer: You must use the POST method to upload files.

***Using Editor Helpers***
Html.LabelFor()
@Html.LabelFor(model => model.ContactMe)
<label for="ContactMe">
  Contact Me
  </label>
// throws in a label for us
 
Html.EditorFor()
@Html.EditorFor(model => model.ContactMe)
<input type="checkbox"
   name="Description">
// creates control based on datatype.

Question: You have a property in the Product model class named ProductID. You want to
include this in the HTML page so that client-side script can use the ProductID value.
However, you do not want the value to be displayed to users. In the model class, you have
annotated the ProductID property with the [HiddenInput(DisplayValue=false)] attribute.
How will the Html.EditorFor() helper render this property?
Answer: The Html.EditorFor() helper renders the following HTML:
<input name="ProductID" type="hidden" value="id">

***Using Validation Helpers***
Html.ValidationSummary()
@Html.ValidationSummary()
<ul>
  <li>Please enter your last name</li>
  <li>Please enter a valid email address</li>
</ul>
// gives us a list of what is not valid

Html.ValidationMessageFor()
@Html.ValidationMessageFor(model => model.Email)
Please enter a valid email address
// displays the actual error messages

Remind the students that they learned how to set validation requirements in model classes
by using validation data annotations such as [Required] in Module 3. They have also
learned how to check the validity of user data in a controller action by testing the
ModelState.IsValid property in Module 4.

[DEMO] Create a Create Page

Lesson 3: Reusing Code in Views
// Layout acts like a master page
// partial view is similer to a user controll
// underscore beginning name is convention for views that can't be served directly

Creating Partial Views
You can use partial views to render the same HTML content in different locations in your
web application

Creating and Naming Partial Views:
- Create a partial view by using the Add View dialog
- Name partial views with an underscore prefix to keep to convention
Strongly-typed and dynamic partial views:
- Create strongly-typed partial views if you are certain that  the partial view will  
  always display the same model class.
- Create dynamic partial views if you are not sure if the partial view will always display
  the same model class.
 
In this topic, the contents of partial views, which do not render complete webpages, are
contrasted with the contents of other views, which include <body> and <head> tags for a
complete webpage. If you use template views, <body> and <head> tags appear in the
template, and not in the view file. In such web applications the content of views and
partial views can appear similar. However, students do not learn about template views
until Module 8- Applying Styles to ASP.NET MVC 4 Web Applications. Do not introduce
template views in this module because this might confuse students.
Question: You want to create a partial view that displays a list of comments. The
comments partial view will be called by actions in the PhotoController and the
HomeController. In which folder should you create the partial view file?
Answer: You should create the partial view in the /Views/Shared folder so that multiple
controllers can access it.

Using Partial Views
Using HTML helpers, you can use partial views within other views in a web application:
- To pass the same model object to a partial view from the parent view, use Html.Partial()
- To pass a model object to a partial view, which is different from the parent view or
  of a different model class, use Html.Action()

Use the ViewBag and ViewData collections to share data between the controller action,
parent view, and partial view

Question: You want to display user reviews of a product to each product page. You have
created a _ReviewsForProduct partial view. Would you use Html.Partial() or Html.Action()
to render this view?
Answer: You would use Html.Action() to render this view so that you can pass a different
model object, in this case, a collection of reviews, to the partial view.

[DEMO] Creating Partial Views

No comments:

Post a Comment