Monday, December 10, 2012

Intro to MVC

URLS have the default format: /domain/controller/method/ID

Controller

They are generally light, or that should be the goal. (I need to verify this comment)

Class must end in Controller suffix and implement IController interface. However, we usually inherit from the Controller class since it inherits from IController and provides more common code we need. It cannot be abstract and cannot use generic parameters.

index() is the name of the Action Method for the default method that will be called.

Unless a method says otherwise, it looks in the Views folder. It then looks for a folder named the same as the class (minus the suffix Controller). Then it looks for the page with the name that matches the method name.

Action Methods can be overloaded, but also have attributes that determine how it is used.

Requirements to be an Action method:

  • Public (and not static)
  • Must be defined on System.Object or Controller
  • Cannot be a special method
  • Cannot have a NonAction attribute.


Security Warning: Anybody on the internet can invoke any public Method in your controller unless decorated as NonAction. However, you would usually only include methods that should be invoked based on a url.

Use the [ActionName("MyNewActionNameHere")] attribute on the Action method to change how it is used in the url. This changes what is matched for routing the request.

HttpGet, HttpPost, HttpPut, HttpDelete attributes to affect what overloaded method is called based on how it is being called. The verb is based on the verb in the current request.

use HandleUnknownAction() method to change what happens when a bad url is passed (i.e. 404 error). We could redirect to error page for example.

Controllers should be simple. Logic should be in the model. A controller's job is to translate user's actions to the model, then provide a response.

It is not uncommon to directly reference the Model (including the Entity Framework) here using Linq. If you do, it is best to instantiate the Entity Framework model in the action method rather than creating it at the controller level.

Action Filters

Implemented as attributes that can be used on Action Methods in the controller or the controller itself. Can use more than one, and specify order.
AsyncTimeout, NoAsyncTimeout, Authorize, ChildActionOnly, HandleError, OutputCache, RequiresHttps, ValidateAntiforgeryToken, ValidateInput

View

use Html.RenderPartial() to render a user control

<%: ... %> will automatically html encode (if not already) what is being rendered. This is a better choice than <% ... %>

Should be as simple as possible. No calculations, etc. Logic and calculations should be in the Model.

Give the View the raw data, let it format it the way the user should see it.

Can use open source view engines such as: Spark, Nvelocity, Brail, Nhaml

Generally will want to put files, etc in the Content directory.

Use ContentResult object as a return type in the Action to send a file to the browser.

Use ViewData object for use with strongly-typed model and Dictionary (name/value pairs). Allows code nuggets (<% %>)
Code Nuggets: <% %>

<%= %> not recommended anymore, use <%: %> due to data not being encoded.

<%: %> always use instead of = nuggest since it will do same thing, but safely encode content.

HTML Helper Methods help with writing tedious common html. They are really just shortcuts to generate HTML. Examples: Html.Label(), Html.LabelFor(), Html.TextBox(), Html.TextBoxFor(), Html.BeginForm(), Html.ValidationSummary(), Html.ValidateMessageFor(), Html.ActionLink(), Html.RenderPartial(), Html.TextArea(), Html.Hidden(), Html.RouteLink(), Html.Action()

Partial Views (implemented as user Controls). They allow you to reuse html and view code. They can be handy for Create and Edit views that share nearly all the html. Generally they should be in the Views/Shared if they will be used by multiple controllers. If they will be used by one controller, but multiple views then put it in the Views/<Controller Folder>. use the Html.RenderPartial() to include the partial view on the part of the page you want it to display. Shares data with parent model by default, but this can be changed to use a different model by passing different model via Html.RenderPartial(). Partial views can be nested.

Use RenderAction() to call controller action methods from a view and display the result of that action method. useful to show data that is not part of the model of the view. Similar to using a RenderPartial(), but instead of inserting a partial view, you can insert virtually anything because most anything you return from an Action method. Beware of using this too often because the calls between controller and views becomes difficult to maintain. Only use it when needed.

HtmlHelper - AntiForgeryToken(), Encode(), EnableClientValidation(), AttributeEncode(), HttpMethodOverride(). 3 classes of helpers: 1. Untyped or regular helper methods, 2. Strongly typed helper methods, 3. templated helper methods. Lots of overloads. Searches for fields in the following order: ModelState, ViewData, and view model. Can put @ before a custom attribute that is passed to a helper. You can also use a Dictionary.
The Html.Label() helper method will use the Display() attribute from the Model to determine what text to display.

There are some high level helpers for Grids and Charts. For those, check out, WebGrid() with getHtml() and Chart with AddTitle(), AddSeries(). These are used with Razor.

Can supply a default value via an extra parameter on helper methods.

Most common Templated Helper Methods

  • Display, DisplayFor, DisplayForModel
  • Edit, EditorFor, EditorForModel

Models

Most any kind of technology or conventions can be used here. This would include things like Entity Framework, etc.
Encapsulates data and business rules, logic, validation, calculations, etc. This is where all the heavy lifting is done.
Use directly in conrollers and views
It is NOT required to add the suffix Model to the classes, but it does generally make it easier to follow in code.

No comments: