Study Notes for Microsoft Exam: Developing ASP.NET MVC Web Applications (70-486)

Study Notes for Microsoft Exam: Developing ASP.NET MVC Web Applications (70-486)

Took Microsoft Exam 70-486 which part of MCSD certification. I spend about 2 weeks studying the material and took some notes which are posted here. Notes are not complete in the sense that they don’t cover the full syllabus – half of my notes are scattered in different places which will be incorporated here later (hopefully).

Code First Migrations:

Three step process (use Package Manager Console):

  1. enable-migrations -ContextTypeName MyProject.Models.StudentDBContext
    • Creates Configuration class with Seed method
    • Needs to be executed only once to setup migrations
  2. add-migration MyFirstMig
    • Creates {DateStamp}_MyFirstMig.cs in Migrations folder
    • Execute it after each change to model
  3. update-database
    • Execute it to apply changes to database

Data Annotations:

  • [Required]
  • [Range(5, 10)]
  • [StringLength(5)]
  • [DataType(DataType.Date)]        (enum DataType { CreditCard, Currency, Custom, Date, DateTime, Duration, EmailAddress, Html, ImageUrl, MultilineText, Password, PhoneNumber, PostalCode, Text, Time, Upload, Url, })
  • [DisplayFormat(DataFormatString = “{0:d}”)]

Model Validation:

  • In Controller’s Create or Edit action (server):
[HttpPost]
public ActionResult Create(Movie movie)
{
   if (ModelState.IsValid)
   {
      db.Movies.Add(movie);
      db.SaveChanges();
      return RedirectToAction("Index");
   }

   return View(movie);
}
  • In view (browser):
<div class="editor-field">
   @Html.EditorFor(model => model.Title)     
   @Html.ValidationMessageFor(model => model.Title)
</div>

Cross Site Scripting Attack

  • Add @AntiForgeryToken() in view inside form element
  • Add [ValidateAntiForgeryToken] attribute on form post actions

Asynchronous Programming with async and await:

image001

Bundling and Minification

  • Good Article: Link
  • Most browsers limit the number concurrent requests to the same domain to six
  • To disable
<system.web>
    <compilation debug="true" />
    <!-- Lines removed for clarity. -->
</system.web>
  • Can be overwritten in code
BundleTable.EnableOptimizations = true;
  • Creating script bundle
bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
                 "~/Scripts/jquery-{version}.js"));
  • Creating style bundle
bundles.Add(new StyleBundle("~/Content/themes/base/css").Include(
          "~/Content/themes/base/jquery.ui.core.css",
          "~/Content/themes/base/jquery.ui.resizable.css",
          "~/Content/themes/base/jquery.ui.selectable.css",
          "~/Content/themes/base/jquery.ui.accordion.css" ));
  • Adding reference to bundles in view
@Styles.Render("~/Content/themes/base/css", "~/Content/css")
@Scripts.Render("~/bundles/modernizr")

<script src='@Scripts.Url("~/bundles/modernizr")' async> </script>

 

  • Can use ‘*’ wildcard and IncludeDirectory function
bundles.Add(new StyleBundle("~/jQueryUI/themes/baseAll")
    .IncludeDirectory("~/Content/themes/base", "*.css"));
  • .min files are selected for release (jquery-1.7.1.min.js)
  • -vsdoc files are ignored (they are for intellisense)
  • Bundle Transformation
    • Implement IBundleTransform
using System.Web.Optimization;

public class LessTransform : IBundleTransform
{
    public void Process(BundleContext context, BundleResponse response)
    {
        response.Content = dotless.Core.Less.Parse(response.Content);
        response.ContentType = "text/css";
    }
}
  • Add transformation
var lessBundle = new Bundle("~/My/Less").IncludeDirectory("~/My", "*.less");
lessBundle.Transforms.Add(new LessTransform());
lessBundle.Transforms.Add(new CssMinify());
bundles.Add(lessBundle);

Using OAuth providers with MVC:

  • Register your site with provider and Receive parameters (such as key or id, and secret)
  • Register your application as Provider’s client: RegisterFacebookClient(            appId: “111111111111111”,            appSecret: “a1a1aa111111111a111a111aaa111111”);

Interaction among View, Layout page (_Layout.cshtml) and other pages

@RenderBody()Called from _Layout.cshtml to render the body of the requested page at the right place within layout.
@RenderSection(“scripts”, required: false)Called from _Layout.cshtml to rendor a section if defined in the requested page.- Section definition is optional if required is false- Section definition on requested page

@section Scripts {

   @Scripts.Render(“~/bundles/jqueryval”)

}

@RenderPage(“MyView.cshtml”, MyModel)Renders the specified page as part of the requested page. Similar to @Html.Partial(“MyView”)

 

WCF vs ASP.Net Web API

image002

Others

  • Don’t use HTTP GET request for delete, edit or create options as they open security holes (link)
  • Fiddler, a web debugging tool which logs all HTTP / HTTPS traffic. (http://www.telerik.com/fiddler/)

Authorization

  • [Authorize(Roles=”Admin,PowerUser“, Users=”Mark“)]
    • Implements IAuthorizationFilter which has one method OnAuthorization
  • AuthorizeAttribute.AuthorizeCore method: When overridden, provides an entry point for custom authorization checks.
  • [AllowAnonymous] This attribute on Action will override the Authroize on Controller and wise versa

 

Browser / Feature Detection and Compatibility

  • Video tab with fall backs
<video>
<source src="video.mp4" type='video/mp4' />
<source src="video.webm" type='video/webm' />
<object type="application/x-silverlight-2">
<param name="source" value="http://url/player.xap">
<param name="initParams" value="m=http://url/video.mp4">
</object>
Download the video <a href="video.mp4">here</a>.
</video>

 

  • Display modes (by default we have regular mode and Mobile mode)
    • Mobile.cshtml will be used instead of Index.cshtml automatically when page is accessed through a mobile
    • Add new DefaultDisplayMode (WP7.cshtml)

 

DisplayModeProvider.Instance.Modes.Insert(0, new DefaultDisplayMode("WP7")
  {
      ContextCondition = ctx => ctx.GetOverriddenUserAgent().Contains("Windows Phone OS")
  });

 

  • Setting viewport to device width <meta name=”viewport” content=”width=device-width” />
  • CSS @media query

 

@media only screen and (max-width: 850px) {
    .site-title {
        color: #c8c8c8;
    }
}

@media (min-width: 768px) and (max-width: 979px) and (orientation:portrait) {…

 

  • Check if user is on mobile device: Browser.IsMobileDevice
  • CSS Vendor Prefixes
    • -ms-, -mso- (Mircosoft); -moz- (Mozilla); -webkit- (Apple, Google); -o-, xv- (Opera)
    • Example: -moz-border-radius: 18px;

 

Razor View Templates

 

  • EditorFor template (used with @Html.EditorFor() helper)
    • Path: ~/Views/ControllerName/EditorTemplates/Article.cshtml

 

@model MyMVCApplication1.Article
@if (Model != null)
{
    @Html.TextBox("", Model.Title)
    @Html.TextBox("", Model.Body)
}
else
{
    @Html.TextBox("", string.Empty)
    @Html.TextBox("", string.Empty)
}

 

  • DisplayTemplate (used with @Html.DisplayFor() helper)
    • Path: ~/Views/ControllerName/DisplayTemplates/<Type Name>.cshtml

 

Action Filters

 

    • Authorization filters – Implements the IAuthorizationFilter attribute.
    • Action filters – Implements the IActionFilter attribute.
    • Result filters – Implements the IResultFilter attribute.
    • Exception filters – Implements the IExceptionFilter attribute.
  • Authorization filters are always executed before action filters
  • Filter’s Order parameter can be used to control the order in which filters of same type are executed
  • Filter’s AllowMultiple parameter can be used to run filter only once
  • ActionFilterAttributeimplements bothIActionFilter andIResultFilter and drives fromActionFilterAttribute
    • It has methods: OnActionExecuting, OnActionExecuted, OnResultExecuting, OnResultExecuted
  • Add filter globally to all actions Add(new RequireHttpsAttribute());
    • filters is GlobalFilters.Filters passed as parameter to FilterConfig
  • Useful Fitlers: HandlerError, OutputCache, Authorize

 

Web Accessibility Initiative-Accessible Rich Internet Applications (WAI-ARIA)

  • aria-labelledby=”name_label” This attribute on input field can an link it to the label which can deliver meaning otherwise delivered visually
  • aria-required defines a mandatory input field

 

Search Engine Optimization

  • txt file – create robot exclusion rules (list pages that should be indexed by search engine)
  • Have meaningful url. Rather than com/1, use mysite.com/<record title>

 

Globalization

  • Accept-Language: en-US,en;q=0.8 (Request Header presented to server)
  • en is Language, US is Locale. Language is at a higher level than locale.
  • <globalization culture=”auto” uiculture=”auto” enableclientbasedculture=”true”/> (enable client based culture in Web.Config)
  • Thread.CurrentThread.CurrentUICulture (find current culture)
  • Use resource files
    • keeps strings in resource files (.resx)
    • create separate files for each language (MyResFile.resx, MyResFile.es-MX.resx)
    • access string using MyResFile.MyLabel1
  • An Alternative to resource files is to use localized views
  • There no way to determine culture in javascript (server has to send it back)
  • Setting culture for jQuery in browser (use anyone of the two)
    • <script>preferCulture(language);</script>
    • $.global.preferCulture(language)
  • Manually set culture on server (may be based on user selection)
    • CurrentThread.CurrentUICulture = new CultureInfo(“es-MX”);
  • Create satellite assemblies (dll) to separate culture specific resouces (only required resources are loaded in memory)

 

Action Attributes (other than filters and attributes covered in else where)

  • RequireHttps
  • ValidateInputTo exclude a field [ValidateInput(true, Exclude = “ArbitraryField”)]
  • AllowHtml
  • ActionName
  • ChildActionOnly (action can’t be accessed directly by client, has to be called from a view using @Html.Action(“MyView”) or RenderAction )

 

Error Handling

  • [HandleError(ExceptionType=typeof(NullReferenceException), View=”MyErrorView”)]
    • Action attribute for handling exception
    • Implements IExceptionFilter that has OnException method
    • By default MVC display ~/Views/Shared/Error
  • Application_Error method in global.asax class (for unhandled exception that makes through the stack)
  • IsCustomErrorEnabled

Action Results

  • All action results derive from ActionResult class
Action Result TypeAction Helper methodComments
ViewResultViewRenders Html, derive from ViewBaseResult
PartialViewResultPartialViewRenders Html, derive from ViewBaseResult
JsonResultJson
JavaScriptResultJavaScript
RedirectResultRedirect
RedirectToRouteResultRedirectToActionRedirectToRoute
FileResultFile
ContentResultContentCan be used to return pdf, xml etc.
EmptyResultN/A (return null)

 

  • A custom action result can be created by inheriting from ActionResult class and overriding void ExecuteResult(ControllerContext ctx) method

Model Binders

  • DefaultModelBinder Maps a browser request to a data object
  • LinqBinaryModelBinder Maps a browser request to a LINQ object
  • Creating a custom model binder
  • Implement IModelBinder interface with one method: public object BindModel(ControllerContextcontrollerContext,ModelBindingContextbindingContext)
  • Setting custom binder for a model class
[ModelBinder(typeof(MyModelBinder))]
public class MyModel
{       ...     }
  • Another way of doing it

ModelBinders.Binders.Add(typeof(MyModel),newMyModelBinder())

 

  • Extending DefaultModelBinder class
    • public class MyBinder : DefaultModelBinder
  • Extend BindProperty method (loops through every model property one by one)
    • protected override void BindProperty(ControllerContext contContext, ModelBindingContext bindContext, PropertyDescriptor propDesc)
    • can be used to override default behavior for certain properties e.g. combine date and time from two fields into one property
    • call base.BindProperty for properties you want to bind using default binding
  • Registor the new binder

ModelBinders.Binders.DefaultBinder =newMyBinder();

 

  • Weakly typed model, all parameter with login prefix will map to LoginUser model

public ActionResult Login([Bind(Prefix=”login”)]LoginUser user)

  • Exclude / Include paramters for Bind

public ActionResult Save([Bind(Exclude = “Salary”)]Employee emp)

 

  • Four value providers: FormsValueProvider, QueryStringValueProvider, HttpFileCollectionValueProvider, RouteDataValueProvider
  • Three types of model binding: Strong, Weak and using ValueProvider.

 

Routes

  • Defining routes (IgnoreRoute should come before MapRoute)
public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
            routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new
            {
                controller = "Home",
                action = "Index",
                id = UrlParameter.Optional
            },
            constraints: new { id = @"\d+" }
            );
        }

 

  • In case of Areas, providing a link to action

@Html.ActionLink(“Exam Detail”, “Exam”, “Detail”, new { area=”ExamSite”}, null)

 

  • Extending default MvcRouteHandler
    • public class MyCustomRouteHandler : MvcRouteHandler
    • Override protected override IHttpHandler GetHttpHandler(RequestContext reqContext)
    • Registering route handler
routes.MapRoute(
                "Home",
                "{controller}/{action}",
                new { controller = "Home", action = "Index" }
                ).RouteHandler = new MyCustomRouteHandler();
  • Implementing IRouteHandler (has one method GetHttpHandler)
    • Registration is bit different from above

Route customRoute = new Route(“custom/{name}”, new MyRouteHandler(“My Route”));

routes.Add(“route-name”, customRoute);

ControllerFactory

  • For custom controller factory, implement IControllerFactory which has three methods: CreateController, ReleaseController, and GetControllerSessionBehavior.
  • Register controller factory in the Global.asax Application_Start method: ControllerBuilder.Current.SetControllerFactory(typeof(MyControllerFactory());
  • Link: Deep Drive into IControllerFactory

View Engine

  • Both RazorViewEngine and Web Forms engine derive from VirtualPathProviderViewEngine which in turn implements IViewEngine
  • IViewEngine has three methods: FindView, FindPartialView and ReleaseView
  • The two find methods return ViewEngineResult object which contains IView
  • IView has one method public void Render(ViewContext viewContext, System.IO.TextWriter writer)

MVC Life Cycle

  • Request
  • UrlRoutingModule selects the Route object
  • Based on the route, UrlRoutingModule obtains an object that implements IRouteHandler (typically it is MvcRouteHandler)
  • MvcRouteHandler creates an instance of MvcHandler which implements IHttpHandler
  • MvcHandler obtains reference to IControllerFactory (typically DefaultControllerFactory)
  • MvcHandler create Controller instance by help of IControllerFactory
  • MvcHandler calls controller’s Execute method
  • ControllerActionInvoker object associated with Controller determines which action method to call
  • Response
  • Controller action create ViewResult
  • ViewResult calls ViewEngine
  • ViewEngine calls View
  • View renders the Response

HTTP Handlers

  • Implement IHttpHandler which has a method ProcessRequest and a property IsReusable
  • Register handler
      <system.web>
        <httpHandlers>
          <add verb="*" path="SampleHandler.new" type="SampleHandler" />
          <add verb="*" path="*.SampleFileExtension" type="SampleHandler2 " />
        </httpHandlers>
      </system.web>

Http Modules

    <system.web>
      <httpModules>
        <add name="HelloWorldModule" type="HelloWorldModule"/>
      </httpModules>
    </system.web>

Windows Identity Foundation

Leave a Reply

Your email address will not be published.