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):
- enable-migrations -ContextTypeName MyProject.Models.StudentDBContext
- Creates Configuration class with Seed method
- Needs to be executed only once to setup migrations
- add-migration MyFirstMig
- Creates {DateStamp}_MyFirstMig.cs in Migrations folder
- Execute it after each change to model
- 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:
- Source: link
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
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
- Article about action filters: http://www.asp.net/mvc/tutorials/older-versions/controllers-and-routing/understanding-action-filters-cs
- Four types of 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 Type | Action Helper method | Comments |
ViewResult | View | Renders Html, derive from ViewBaseResult |
PartialViewResult | PartialView | Renders Html, derive from ViewBaseResult |
JsonResult | Json | |
JavaScriptResult | JavaScript | |
RedirectResult | Redirect | |
RedirectToRouteResult | RedirectToActionRedirectToRoute | |
FileResult | File | |
ContentResult | Content | Can be used to return pdf, xml etc. |
EmptyResult | N/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
- MSDN Link: Walkthrough: Creating and Registering a Custom HTTP Module
- Implement IHttpModule which has two method Init and Dispose
- During Init method module can register for any of HttpApplication events
- Register module
<system.web> <httpModules> <add name="HelloWorldModule" type="HelloWorldModule"/> </httpModules> </system.web>
Windows Identity Foundation
- Link: WIF Overview