Quantcast
Channel: ASP.NET Blog
Viewing all 7144 articles
Browse latest View live

Azure Web Site now supports WebSockets

$
0
0

If you missed the announcement the other day, WebSockets are now supported in Windows Azure Web Sites.

Let's try it with a sample SignalR application.

Create an Azure Web Site

  1. Login to http://manage.windowsazure.com/
  2. Select New, Compute, Web Site, Quick Create
    • Type a URL and click Create Web Site
    image
  3. Go to Dashboard of your new website, click Download the publish profile, and save *.PublishSettings file on your local hard drive
    clip_image001

Create a Visual Studio Project associated to an Azure Web Site

  1. Install Azure SDK for Visual Studio 2013
  2. Open Visual Studio 2013
  3. On Menu: select File, New, Project, Visual C#, Web, ASP.NET Web Application
    • On Name, type "AzureWebSiteWithWebSockets", click OK
    • Select Empty, click OK
  4. In the Solution Explorer, right-click on your project and select Publish
    image
    • Click Import, select Import from a publish profile file, click Browse
    • Find the *.PublishSettings file and click OK
    • Click Validate Connection
    • Click Publish

Add SignalR Stock Ticker Sample

  1. In the Solution Explorer, right-click on your project, select Manage NuGet Packages
    • Select Online
    • On search box, type Microsoft.AspNet.SignalR.Sample
    • Click Install
    • On License Acceptance window, click I Accept
    • Click Close
  2. In the Solution Explorer, right-click on your project, select Add, New Item
    • Select Web, OWIN Startup class
    • On Name, type "Startup.cs"
    • Click Add
  3. On Startup.cs file, add this line of code inside method
    "public void Configuration(IAppBuilder app)"

    Microsoft.AspNet.SignalR.StockTicker.Startup.ConfigureSignalR(app);

  4. On SignalR.Sample/SignalR.StockTicker.js file, add this line of code before "$.connection.hub.start()"

    $.connection.hub.logging = true;

  5.          
  6. In the Solution Explorer, right-click SignalR.Sample/StockTicker.html and select View in Browser
    image
  7. Click Open Market. You should see animations on the table.
    clip_image002

Publish your local changes to Azure Web Site

  1. Right click project, select Publish
    • Click Publish
  2. On Browser, open http://[YourWebSite].azurewebsites.net/SignalR.Sample/StockTicker.html
  3. Click F12 to open the Web Developer Console
  4. Refresh page
  5. Your browser does not connect using websockets. It connects with another transport like Server Sent Events, Forever Frame, or Long Polling.
    clip_image003

Enable WebSocket on Azure Web Site

  1. On Azure Portal, select Web Sites, select your Web Site, select Configure
  2. Find Web Sockets and turn it on
    clip_image004
  3. Click Save
  4. On Browser, open http://[YourWebSite].azurewebsites.net/SignalR.Sample/StockTicker.html
  5. Click F12 to open the Web Developer Console
  6. Refresh page
  7. Your browser now connects using websockets!
    clip_image005 

ASP.NET Performance: Prefetch and Multi-Core Jitting

$
0
0

Editor note: This blog is originally published by Jose Reyes - ASP.NET on 02-29-2012 in Web Performance Blog, which will be obsolete soon.  Future ASP.NET related performance blogs will be posted here.

Introduction.

A couple of new features are introduced in ASP.NET 4.5 to improve startup time of web apps. Both features use a flag on the web.config to enable them. The features don’t do any magic by themself. They just enable features available on the operating system underneath or in the CLR APIs.

Prefetch feature

The prefetch feature only works on Windows 8 Server or newer OS. It requires the Os to be configured and the enablePrefetchOptimization flag on the <system.web/compilation> section of web.config to be set. The flag only has effect at the app level. No subdirectory config or location tag makes sense here. The setting is set to false by default, so users must explicitly set it to true in order for it to work.

To enable the feature, run the Enable-MMAgent power shell command:

    powershell Enable-MMAgent -OperationAPI

The SuperFetch service might need to be started. Verify is running:

C:\>sc query sysmain

 

SERVICE_NAME: sysmain

        TYPE               : 20  WIN32_SHARE_PROCESS

        STATE              : 4  RUNNING

                                (STOPPABLE, NOT_PAUSABLE, ACCEPTS_SHUTDOWN)

        WIN32_EXIT_CODE    : 0  (0x0)

        SERVICE_EXIT_CODE  : 0  (0x0)

        CHECKPOINT         : 0x0

        WAIT_HINT          : 0x0

Prefetch Implementation.

The features simple uses the operation recorder API. See OperationStart and OperationEnd APIs on msdn. This APIs require an integer used as an Id of the operation. We use a hash code of the app domain app id, which is a string.

string domainId = HttpRuntime.AppDomainAppId;

int operationId = domainId.GetHashCode();

 

The OperationStart call is made the first time the app domain is created. The OperationEnd API is called at the end of the request in which we called OperationStart. A .pf file should be created on the prefetch directory:

C:\>dir %windir%\Prefetch

Volume in drive C has no label.

Volume Serial Number is CC5B-113C

 

Directory of C:\Windows\Prefetch

 

02/16/2012  04:17 PM    <DIR>          .

02/16/2012  04:17 PM    <DIR>          ..

02/16/2012  04:17 PM           164,832 Op-W3WP.EXE-90E54C33-765F360E.pf

               1 File(s)        164,832 bytes

               2 Dir(s)  30,203,154,432 bytes free

Multi-Core Jitting feature.

The multi-core jitting feature is enabled by default, and work on all OS where ASP.NET 4.5 is available. You can disable it by setting the profileGuidedOptimizations enumerated value on the <system.web/compilation> section on the web.config, to None.

Multi-Core Jitting Implementation.

The feature uses the new class ProfileOptimization class of the System.Runtime namespace. The class is called the first time the app domain is created. First, we set the profile root to the codegen directory, which by default is something like:

"%windir%\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\myapp\weirdhash1\weirdhash2"

Remember that the temporary files folder value can be changed on tempDirectory attribute of the <system.web/compilation> section of the web.config.

After setting the profile root, we call StartProfile() with the filename "profileoptimization.prof". The CLR code underneath handles all the magic. If you examine the contents of the temporary ASP.NET file folder, you will see the file there:

C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\dotnetnuke\59a60e53\a2ac2624>dir *.prof

Volume in drive C has no label.

Volume Serial Number is CC5B-113C

 

Directory of C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\dotnetnuke\59a60e53\a2ac2624

 

02/16/2012  04:38 PM             9,828 profileoptimization.prof

               1 File(s)          9,828 bytes

               0 Dir(s)  30,203,035,648 bytes free    

Conclusion.

The ASP.NET Prefetch feature uses the operation recording APIs to improve startup time of web applications. The feature is enabled when a Windows Server 8 machine is configured for the operation API and enabledPrefetchOptimization flag is set on the web.config.

The multi-core jitting feature is available in more operating systems and is on by default. It uses a new CLR feature for profile base optimization.

Thanks for reading.

Originally posted at http://blogs.msdn.com/b/josere/

ASP.NET Performance: Managed runtime loader

$
0
0

Editor note: This blog is originally published by Jose Reyes - ASP.NET on 02-29-2012 in Web Performance Blog, which will be obsolete soon.  Future ASP.NET related performance blogs will be posted here.

Introduction

There is a file called aspnet.config in the .Net framework installation. This file is used to specify startup flags for both ASP.NET and CLR for those settings that are needed very early in the worker process lifetime, when the config system is not yet present.

In IIS 7.5 we added an attribute to the <applicationPools> configuration collection called CLRConfigFile, on the applicationHost.config file, which allows you to specify your own aspnet.config, for a particular application pool.

There is another attribute on the <applicationPools> called managedRuntimeLoader, which specify the library in charge of loading CLR. By default, this task is executed by ASP.NET native layer, in the webengine4.dll. If no loader is specified, or if an error occurs, the loading falls back to IIS itself.

IIS 7.5 issue.

There was a problem in IIS 7.5, in which the managedRuntimeLoader was never provided with the path to this CLRConfigFile, so it was forced to use the one in the framework directory. So if you wanted to use the CLRConfigFile, to setup different CLR flags for an application pool, you will need to set the attribute AND explicitly clear the managedRuntimeLoader attribute on the application pool definition on applicationHost.config:

  ...

<system.applicationHost>

  ...

        <applicationPools>

            <!-- Set the CLRConfigFile and clear managedRuntimeLoader -->

            <addname="MyAppPool"CLRConfigFile="c:\myconfigs\myapp1\aspnet.config"managedRuntimeLoader="" />

  ...

 

The second step shouldn’t be necessary and is confusing. The clearing of the attributes basically forces the fall back to IIS runtime loader, which uses the correct CLRConfigFile.

This has been fixed on IIS 8, where you only need to set the CLRConfigFile attribute.

To verify this is working, you can change one parameter on the aspnet.config such as disabling the server garbage collector. (Note: Disabling the server garbage collector is a good thing if you want to save memory, at the expense of throughput. Typical use of this is hosting scenarios, where web sites has low traffic and higher site density is desirable.)

<configuration>

    <runtime>

  ...

        <gcServerenabled="false"/>

 

Attaching a debugger to the worker process and using SOS command !eeversion will show the garbage collector mode being used:

C:\>cdb.exe -pn w3wp.exe

 

Microsoft (R) Windows Debugger Version 6.13.0009.1140 X86

Copyright (c) Microsoft Corporation. All rights reserved.

  …

0:044> .loadby sos clr

0:044> !eeversion

4.0.30319.239 retail

Workstation mode

SOS Version: 4.0.30319.239 retail build

 

Make sure your box has more than one logical core; otherwise workstation mode will always be used.

Implementing a loader

Implementing a loader is probably not needed, but if you want to do it, you will need a native DLL that exports a function named LoadManagedRuntime. In IIS 8 you can also export LoadManagedRuntimeEx. The function signature is shown below:

 

HRESULT __stdcall

LoadManagedRuntime(

        _In_ PCWSTR pwszRuntimeVersion,

        __deref_out IUnknown ** ppManagedRuntimeHost)

{

    return LoadRuntimeInternal(pwszRuntimeVersion, ppManagedRuntimeHost);

}

 

HRESULT __stdcall

LoadManagedRuntimeEx(

        _In_ PCWSTR pwszRuntimeVersion,

        _In_ PCWSTR pszClrConfigFile,

        __deref_out IUnknown ** ppManagedRuntimeHost)

{

    return LoadRuntimeInternal(pwszRuntimeVersion, ppManagedRuntimeHost, pszClrConfigFile);

}

 

HRESULT LoadRuntimeInternal(_In_ PCWSTR pwszRuntimeVersion, __deref_out IUnknown** ppHost /*= NULL*/, _In_ PCWSTR pwszAspNetHostConfig /*= NULL*/) {

    HMODULE hModule = NULL;

    HRESULT hr = S_OK;

    IUnknown *pHost = NULL;

    PFNCorBindToRuntimeHost pCorBindToRuntimeHost;

    TCHAR szPath[MAX_PATH + 1];

    TCHAR szAspConfig[MAX_PATH + 1];

 

    ExpandEnvironmentStrings(L"%windir%\\system32\\mscoree.dll", szPath, MAX_PATH);

    if(pwszAspNetHostConfig == NULL) {

        ExpandEnvironmentStrings(ASPNET_CONFIG, szAspConfig, MAX_PATH);

        pwszAspNetHostConfig = szAspConfig;

    }

 

    hModule = LoadLibrary(szPath);

    ON_NULL_EXIT(hModule);

 

    pCorBindToRuntimeHost = (PFNCorBindToRuntimeHost)GetProcAddress(hModule, "CorBindToRuntimeHost");

    ON_NULL_EXIT(pCorBindToRuntimeHost);

 

    hr = pCorBindToRuntimeHost(

                    L"v4.0.30319",

                    L"svr",

                    pwszAspNetHostConfig,

                    NULL, // reserved

                    STARTUP_CONCURRENT_GC|STARTUP_LOADER_OPTIMIZATION_MULTI_DOMAIN_HOST|STARTUP_LOADER_SAFEMODE|STARTUP_DISABLE_COMMITTHREADSTACK|STARTUP_HOARD_GC_VM,

                    CLSID_CLRRuntimeHost,

                    IID_IUnknown,

                    (VOID**)&pHost);

 

Cleanup:

    if (pHost != NULL && ppHost != NULL) {

        pHost->AddRef();

        *ppHost = pHost;

    }

    if(hModule != NULL) {

        FreeLibrary(hModule);

    }

    return hr;

}

 

 

See the attached project for the full sample code. The sample can be compiled into a native DLL and the managedRuntimeLoader attribute can be set to point to that DLL.

 

  ...

<system.applicationHost>

  ...

        <applicationPools>

            <!-- Set the CLRConfigFile and managedRuntimeLoader -->

            <addname="MyAppPool"CLRConfigFile="c:\myconfigs\myapp1\aspnet.config"managedRuntimeLoader="c:\mynativedlls\myruntimeloader.dll" />

  ...

 

Note that debugging such a code on IIS will require the use of “Image File Execution Options”, since the code is executed very early on the worker process lifecycle. An easier way to test might be to load the library yourself and call the functions, the way IIS would (see the test project).

Conclusion

IIS 7.5 required for you to clean the managedRuntimeLoader attribute, if you wanted to change CLR parameters on your own CLRConfigFile.

Implementation of a managed runtime loader requires a native DLL which exports a LoadManagedRuntime() and/or LoadManagedRuntimeEx().

Thanks for reading.

Originally posted at http://blogs.msdn.com/b/josere/

ASP.NET Performance: Debugging W3WP Startup

$
0
0

Editor note: This blog is originally published by Christy Henriksson on 03-19-2012 in Web Performance Blog, which will be obsolete soon.  Future ASP.NET related performance blogs will be posted here.

On a few occasions, I have needed to debug the startup of the IIS worker process (w3wp).  I finally decided to create a script so that I no longer need to search for the answer.  The script starts w3wp by requesting a non-existent ASPX page.  After windbg is closed, the script will kill the debug session and clean up the registry.

Script requirements:

Debug Script:

reg add "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\w3wp.exe" /v Debugger /t REG_SZ /d "cdb.exe -c \".server tcp:port=9999\"" /f
iisreset /restart
start /b tinyget5 -srv:localhost -uri:/notfound.aspx -status:404
sleep 3
windbg -remote tcp:port=9999,server=localhost
pskill cdb
pskill w3wp
reg delete "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\w3wp.exe" /f

UPDATE:

If you are setting managed breakpoints, you will want to break when the managed assembly loads using "sxe ld:Assembly".  For instance, "sxe ld:clr" or "sxe ld:System.Web.dll".

If you want to debug compilation, you should delete the "Temporary ASP.NET Files" under the framework installation folder for your website after the iisreset.

ASP.NET Performance: Performance Counters on Windows Client + IIS Express

$
0
0

Editor note: This blog is originally published by Christy Henriksson on 09-12-2012 in Web Performance Blog, which will be obsolete soon.  Future ASP.NET related performance blogs will be posted here.

I learned recently that ASP.NET performance counters are not available on Windows 7 or 8 (client) when running with IIS Express (or the Dev10 default of Cassini).  Fortunately, the fix is easy: run Visual Studio as Administrator.

If you’re using IIS Express without Visual Studio installed (for example, WebMatrix), then you’ll first need to install ASP.NET 4.5 features:

dism /online /enable-feature /featureName:NetFx4Extended-ASPNET45 /all

UPDATE: The above dism command is specific to Win8.  Basically, you need to make sure ASP.NET features are enabled on the machine in order for performance counters to get registered.  This happens automatically when you install VS.  For Win7 client, you can enable ASP.NET 3.5 features with a command like the following (note that /all isn’t available for automatically enabling parent features):

dism /online /enable-feature /featurename:IIS-WebServerRole /featurename:WAS-WindowsActivationService /featurename:WAS-ProcessModel /featurename:WAS-NetFxEnvironment /featurename:WAS-ConfigurationAPI /featurename:IIS-ApplicationDevelopment /featurename:IIS-ASPNET /featurename:IIS-DefaultDocument /featurename:IIS-NetFxExtensibility /featurename:IIS-ISAPIExtensions /featurename:IIS-ISAPIFilter /featurename:IIS-RequestFiltering /featurename:IIS-Metabase /featurename:IIS-WMICompatibility /featurename:IIS-LegacyScripts /featurename:IIS-IIS6ManagementCompatibility /featurename:IIS-WebServerManagementTools /featurename:IIS-HttpTracing

Announcing release of ASP.NET and Web Tools 2013.1 for Visual Studio 2012

$
0
0

We have released ASP.NET and Web Tools 2013.1 for Visual Studio 2012. This release brings a ton of great improvements, and include some fantastic enhancements to ASP.NET MVC 5, Web API 2, Scaffolding and Entity Framework to users of Visual Studio 2012 and Visual Studio 2012 Express for Web.

You can download and start using these features now.

Below are details on a few of the great improvements you can take advantage of with this release.  Please visit http://asp.net/aspnet/overview/aspnet-and-visual-studio-2012/aspnet-and-web-tools-20131-for-visual-studio-2012 for additional release notes, documentation, and tutorials.

Round tripping

With this release of ASP.NET and Web Tools, it is now possible for developers using Visual Studio 2012 and Visual Studio 2013 to collaborate on an ASP.NET MVC 5 application. This release brings in key features such as support for ASP.NET Razor 3 editing which allows developers to use syntax highlighting and Intellisense when editing a Razor View in their MVC application. Developers can also be productive by using the new ASP.NET Scaffolding framework in Visual Studio 2012 in any type of web application project such as ASP.NET Web Forms, MVC, and Web API.

ASP.NET MVC 5 and Web API 2 Templates

You can now use MVC 5 or Web API 2 project templates to create an applicationThese project templates will install the necessary NuGet packages for MVC 5 and Web API 2.

clip_image002

You can also add MVC 5 and Web API 2 controllers or views using item templates.

To learn more about what’s new in MVC 5 please visit http://www.asp.net/visual-studio/overview/2013/release-notes#TOC10

To learn more about what’s new in Web API 2 please visit http://www.asp.net/visual-studio/overview/2013/release-notes#TOC11

ASP.NET Scaffolding

ASP.NET Scaffolding is a code generation framework for ASP.NET Web applications. In previous versions of Visual Studio, scaffolding was limited to running within ASP.NET MVC projects. Since the advent of "One ASP.NET" there is no specific ASP.NET MVC project type, as all projects are just ASP.NET projects. 

With this update, you can use MVC's scaffolding from within any ASP.NET project, including scaffolding MVC controllors within Web Forms apps. To learn more about what is new in Scaffolding, please visit http://www.asp.net/visual-studio/overview/2013/aspnet-scaffolding-overview

 

clip_image004

ASP.NET Razor Tooling

With this release you will also get great editor support for editing Razor views in MVC. This includes features such as syntax highlighting, Intellisense etc.clip_image006

Entity Framework 6

When you Scaffold a MVC controller or Web API controller using Entity Framework, the controller will use Entity Framework 6 to generate code to perform CRUD actions on an entity. The controller also show cases some of the key features in Entity Framework 6 such as generating async actions. For more information on what’s new in Entity Framework please visit http://msdn.microsoft.com/en-US/data/jj574253

Bootstrap

When you Scaffold a MVC controller with Entity Framework and generate views for CRUD operations, the views use Bootstrap CSS framework to style the pages. Bootstrap is a responsive mobile first CSS framework that makes front end web development much easier. For more information on how to customize Bootstrap please visit http://www.asp.net/visual-studio/overview/2013/creating-web-projects-in-visual-studio#bootstrap.

NuGet 2.7

NuGet 2.7 includes a rich set of new features which are described in detail at NuGet 2.7 Release Notes.

This version of NuGet improves the experience around automatic package restore. When installing NuGet 2.7, users implicitly consent to automatically restoring missing packages. Users can explicitly opt out of package restoration through the NuGet settings in Visual Studio. This change simplifies how package restore works.

Summary

ASP.NET and Web Tools 2013.1 for Visual Studio 2012 enables developers to take advantage of the improvements in ASP.NET MVC 5, Web API 2, Scaffolding, and Entity Framework when using Visual Studio 2012. This release also makes it possible for developers to collaborate on MVC 5 or Web API 2 projects across Visual Studio 2012 and 2013.

Please download and start using this update now.

Building Browser Link extension in Visual Studio 2013

$
0
0

Browser Link feature in Visual Studio 2013 provides APIs for you to write your own Browser Link Extension. To take a look at some of the extensions, you can download Web Essentials for Visual Studio 2013 RTM.

In this blog, I will give you a step by step overview of the various APIs that we provide.

You will need the following to start with:

  1. Visual Studio 2013 RTM.
  2. Visual Studio 2013 SDK.
  3. Go to http://sidewaffle.com/ and download a template for extensions.

Once you have installed all of the above, you can get started:

Step 1: Go to  File –>New-> Visual C# –> Extensibility and select Browser Link Extension as shown in the image below.

image

Click OK, to create MyBrowserLinkProject. The browser link project will have a C# file and a JavaScript file. In the sample project, we have MyBrowserLinkProjectExtension.cs file and a MyBrowserLinkProjectExtension.js file.

MyBrowserLinkProjectExtension.js contains the script that will be injected in every browser that is invoked after Visual Studio is launched.

Step 2: Open file MyBrowserLinkProjectExtension.cs.

Here you will find a MyExtensionFactory class that implements interface IBrowserLinkExtensionFactory and MyExtension class that derives from base class BrowserLinkExtension.

MyExtensionFactory class has a CreateExtensionInstance() method and a GetScript().

CreateExtensionInstance method takes in a connection object. A connection can be thought of as a link to a page being rendered. For example, if Visual Studio has IE and Chrome browser rendering a particular page, then each of these can be thought of as a unique connection. You can create a new instance of an extension object or return the same instance of the extension object depending on what you want to do per connection.

 

Code Snippet
  1. publicBrowserLinkExtension CreateExtensionInstance(BrowserLinkConnection connection)
  2.         {
  3.             returnnewMyExtension();
  4.         }

GetScript  method just reads the script to use from MyBrowserLinkProject.js file.

Code Snippet
  1. publicstring GetScript()
  2.         {
  3.             using (Stream stream = GetType().Assembly.GetManifestResourceStream("MyBrowserLinkProject.Scripts.MyBrowserLinkProject.js"))
  4.             using (StreamReader reader = newStreamReader(stream))
  5.             {
  6.                 return reader.ReadToEnd();
  7.             }
  8.         }

 

Step 3: Now, let us look at the MyExtension class itself. This file contains an OnConnected method which you can implement and any number of Browser Link Callback methods.

Code Snippet
  1. publicclassMyExtension : BrowserLinkExtension
  2.     {
  3.         publicoverridevoid OnConnected(BrowserLinkConnection connection)
  4.         {
  5.             Browsers.Client(connection).Invoke("greeting", "Hello from Visual Studio!");
  6.         }
  7.  
  8.         [BrowserLinkCallback] // This method can be called from JavaScript
  9.         publicvoid SendText(string message)
  10.         {
  11.             MessageBox.Show(message);
  12.         }
  13.     }

 

OnConnected() will be called when a connection between Visual studio and browser has happened. This is  a good place to do any kind of initialization. In our example, we have chosen to Invoke the greeting function in Javascript.

Code Snippet
  1. publicoverridevoid OnConnected(BrowserLinkConnection connection)
  2.         {
  3.             Browsers.Client(connection).Invoke("greeting", "Hello from Visual Studio!");
  4.         }

 

This is how we can make a call from Visual Studio to the browser. In the above example we are trying to call the greetings function in the browser from within visual studio’s extension.

Step 4: Open MyBrowserLinkProjectExtension.js file and you will see the greeting function which you invoked in step 3.

Code Snippet
  1. (function (browserLink, $) {
  2.     /// <param name="browserLink" value="bl" />
  3.     /// <param name="$" value="jQuery" />
  4.  
  5.     function output(message) { // Helper for the 'greeting' function
  6.         if (console) {
  7.             console.log(message);
  8.         }
  9.     }
  10.  
  11.     return {
  12.  
  13.         greeting: function (message) { // Can be called from the server-side extension
  14.             output(message);
  15.         },
  16.  
  17.         onConnected: function () { // Optional. Is called when a connection is established
  18.             browserLink.invoke("SendText", "Hello from " + browserLink.initializationData.appName);
  19.         }
  20.     };
  21. });

Now let us see how we can make a call from Browser to Visual studio. For this, you will need Browser Link Callback methods defined in your extension.

In our example, you can see that we have a “SendText” method with a [BrowserLinkCallback] attribute. This means, this method can be called from javascript running in your browser.

Code Snippet
  1. [BrowserLinkCallback] // This method can be called from JavaScript
  2.         publicvoid SendText(string message)
  3.         {
  4.             MessageBox.Show(message);
  5.         }

 

Step 5: Do F5 and this will open up the experimental instance of VS. Here, create a new webforms website. Bring up the Browser Link dashboard. Click on the view in browser link here.

This will bring up a Message box which says “Hello from Internet Explorer”. This way you can see Browser’s JavaScript invoking a Visual studio method.

image

 

Step 6: If you invoke F12 tools in IE, you can see a Browserlink.js file that plugs in the extension script for you in all the browsers.

 

image

 

You can also see that Visual studio has successfully printed in your console. This was done by greetings function in your JavaScript.

Step 1 to 6 was a basic introduction of some of the APIs that you would require to get started.

Step 7: Let us look at Actions API.

These APIs provide a way for your Actions(BrowserLinkCallBack Methods) to be invoked via the Browser link Dashboard.

This will give you an entry in the context menu of your connection right next to the Refresh Extension as shown in the image below.

image

 

In our Example, we have two actions defined. One is “Action for SendText” and the other is “Action for Greetings”.

To do this you will need to add the following piece of code:

Code Snippet
  1. publicoverrideIEnumerable<BrowserLinkAction> Actions
  2.         {
  3.             get
  4.             {
  5.                 returnnewBrowserLinkAction[] {
  6.                     newBrowserLinkAction("Action for SendText", this.AddSendText),
  7.                     newBrowserLinkAction("Action for SendGreetings", this.AddGreetings),
  8.                    
  9.                 };
  10.             }
  11.         }

Note that, each of these Action methods AddSendText and AddGreetings inturn invoke a BrowserLinkCallBack method.

Code Snippet
  1. publicvoid AddSendText(BrowserLinkAction action)
  2.         {
  3.             SendText("Invoked from Actions context menu!");
  4.         }
  5.  
  6.         publicvoid AddGreetings(BrowserLinkAction action)
  7.         {
  8.             SendGreetings("Invoked via Actions: Hello from Visual Studio!");
  9.         }

Here are their corresponding BrowserLinkCallBack methods:

Code Snippet
  1. [BrowserLinkCallback] // This method can be called from JavaScript
  2.         publicvoid SendText(string message)
  3.         {
  4.             MessageBox.Show(message);
  5.         }
  6.  
  7.         [BrowserLinkCallback] // This method can be called from JavaScript
  8.         publicvoid SendGreetings(string message)
  9.         {
  10.             Browsers.Client(_browserlinkConnection).Invoke("greeting", message);
  11.         }

 

At this point, you can do an F5 on MyBrowserLinkProject. This will open up the experimental instance of VS. Create a Website here and Browse About.aspx with IE and Chrome.

Now click on the little arrow next to chrome and that will bring up the Actions menu for you.

image

Click on Action for SendGreetings and it will print out the following in Chrome’s console as shown in the image below. This lets you test out the BrowserLinkCallback methods quickly on a per connection basis. You can also invoke this on IE and see similar results.

 image

     

Step 8: Mapping Data API.

The API will provide two kinds of operations: mapping a source file position to a DOM element, and mapping a DOM element to a source file range.

All mapping operations will involve a DOM element reference. DOM elements only exist in the browser; they cannot be marshaled to the Visual Studio process. Because of this, the API will only be available in JavaScript. There will be no way to use the API directly from C#.

Each element that can be mapped will have a sourceMapping property attached to it.

Let us see a quick example. Open file MyBrowserLinkProjectExtension.js.

Inside the greeting method, add the following two lines of code. In the example, we are trying to get div1 and open the source file with the complete range for div tag selected.

 

Code Snippet
  1. greeting: function (message) { // Can be called from the server-side extension
  2.             output(message);
  3.             var testElement = document.getElementById("div1");
  4.             browserLink.sourceMapping.selectCompleteRange(testElement);
  5.         }

Now, do an F5 again. This will bring up experimental instance. Create a Razor website. In About.cshtml file add the following

div tag:  <div id="div1"> Select Me</div>.

View this page in IE Browser. Now from the Dashboard, invoke the “Action for SendGreetings”. This will select the text in source view as shown in the image below.

image

 

You can download WebEssentails2013 and look at  InspectModeBrowserLink.js to see how to make use of the Mapping Data API.

Hope this was useful.

Thanks,

Reshmi

Debugging OWIN app or framework

$
0
0

Diagnostics

The Microsoft.Owin.Diagnostics nuget package contains a welcome page and an error page. The UseWelcomePage extensions can be used to add a simple html page to your application to verify the site is up and running. The UseErrorPage extensions can be used to add an Exception filter to the request pipeline that will display exception and request details.This error page is similar to Yellow Screen Of Death (YSOD) in SystemWeb.

Configuring a Welcome page:

[assembly: OwinStartup(typeof(WebApplication.Startup))]
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseWelcomePage("/welcomePage");
}
}

Configuring an error page:

[assembly: OwinStartup(typeof(WebApplication.Startup))]

public class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseErrorPage(new ErrorPageOptions()
{
            //Shows the OWIN environment dictionary keys and values. This detail is enabled by default if you are running your app from VS unless disabled in code. 
ShowEnvironment = true,
            //Hides cookie details
ShowCookies = false, 
            //Shows the lines of code throwing this exception. This detail is enabled by default if you are running your app from VS unless disabled in code. 
 ShowSourceCode = true,
            });

app.Run(async context =>
{
throw new Exception("UseErrorPage() demo");
await context.Response.WriteAsync("Error page demo");
});
}
}
 
Debug Symbols:
Starting with v2.0.0 Katana's debug symbols are now being published to symbolsource.org. Refer to this page to setup symbols for Katana packages. Symbols for the nightly Dev and nightly Release packages are also published to symbolsource.org. Refer katana codeplex to know the nightly feed URLs.

For more information refer to the katana codeplex here.

Unit testing OWIN applications using TestServer

$
0
0

Unit testing OWIN applications using TestServer

Unit testing a OWIN application (pipeline) can be as simple as calling WebApp.Start<T>() on a Startup class. For example here is a simple OWIN pipeline:

You can have this piece of test code in your unit test library and execute the necessary tests. But one drawback with this approach is every time you call WebApp.Start<T>, the test starts a real HTTP listener server and executes the code. What if there is a way by which you can avoid starting a real HTTP server every time, but still unit test the OWIN application pipeline. If that’s what you are looking for, Microsoft.Owin.Testing package solves this problem for you.

Microsoft.Owin.Testing package:

This package contains a TestServer which can create an OWIN request processing pipeline and helpers to submit requests to the pipeline as if it is a real server. Requests made with these helpers never hit the network as they are processed directly in memory. Let’s try to implement the above same test using TestServer.

Install the nuget package ‘Microsoft.Owin.Testing’ using the Nuget package manager into your unit test project. Alternatively you can enter this command in the package manager console:

Install-package Microsoft.Owin.Testing

We are going to use TestServer.Create<T> to create the test server instead of WebApp.Start<T>. To make direct requests to this test server without hitting network, use the HttpClient exposed by this test server instance.

Requests can also be constructed and submitted with the CreateRequest helper method as below:

Let’s try to simplify the test further by passing in a lamda for the Configuration method instead of a startup class like below:

How it works?

 The HttpClient object that the TestServer helpers use has a special OwinHttpMessageHandler that intercepts all the requests made and converts them into OWIN requests. This OWIN request is being fed to the TestServer directly instead of sending it over the network. 

Adding your own client side message handlers:

If you would like to add your own HttpMessageHandler(s) on the client side, you can insert them on the client side pipeline. But as I mentioned in the previous section, to have this TestServer working you need to have the special OwinHttpMessageHandler at the end of the HttpClient pipeline. Here is a sample on how to use your own handlers on the client side:

Client code will have to look something like this:

OWIN environment object as a request:

Alternative to using CreateRequest() or HttpClient to send request, you can send an OWIN environment dictionary directly as a request by using the following overload of TestServer.

server.Invoke(yourOwinEnvironmentDictionary);

Modified ASP.NET 4.5 CPU Throttling

$
0
0

A while back, Jose blogged about the CPU throttling feature in ASP.NET 4.5. As described in the original post, this feature is intended to correct negative scaling in server throughput when handling async requests on a server with saturated CPU.

Now, for the next chapter to this story: CPU throttling under stress scenarios.

This feature was tested during development in the ASP.NET performance lab. Performance testing, unlike stress, tends to be very homogenous: measure server throughput under full load (CPU) when handling a specific scenario or request. When this feature entered the stress lab, it encountered more real-world applications: longer run times, various requests and bursty traffic. Under these conditions it became clear that CPU throttling had a problem with recovery.

PROBLEM: As Jose mentioned, ASP.NET throttles requests by adding them to a native queue until the managed layer is ready to process them. This is the same native queue used when MaxConcurrentRequestsPerCpu or MaxConcurrentThreadsPerCpu is exceeded. ASP.NET attempts to dequeue when other requests enter or complete the pipeline. This behavior is fine for requests queued due to high concurrency, since a large number of requests are executing and headed for completion. However, CPU throttling is not based on number of requests but on how expensive they are. As a result, there could be just a few CPU-intensive requests causing a backup in the native queue with no way to empty it aside from incoming requests.

SOLUTION: ASP.NET CPU throttling was modified just prior to RTM. ASP.NET now supports more aggressive dequeuing from the native queue both with incoming/completing requests and via a timer. Also, a second configuration, “percentCpuLimitMinActiveRequestPerCpu” was added to ensure a minimum number of requests are being served before throttling kicks in. The default throttling limit was also lowered from 99% to 90% in order to detect high pressure and avoid negative scaling earlier.

In conclusion, it is highly recommended that you don’t run your web servers at full capacity. Enabled by default, this feature is primarily intended as a safety net to prevent degradation in performance when serving async requests under load. If you find that requests are sitting in the queue (see: “ASP.NET\Requests in Native Queue”) even after the CPU has normalized, try disabling the feature by setting percentCpuLimit to 0. 

<configuration><system.web><applicationPoolpercentCpuLimit=”90percentCpuLimitMinActiveRequestPerCpu=”100></system.web></configuration>

Many thanks to Konst Khurin for his work on this feature and blog review.

Instant Azure Caching with MVC

$
0
0

In this blog post I’ll take my MVC Movie app and in 15 minutes connect it to the preview Windows Azure Cache service. The image below shows the details of a movie along with timing data (1.4 milliseconds), cache status (Hit in this case) and the PID of the IIS server.

details

You can download the completed app here. Later in the tutorial we’ll use the PID to show the session cache preserves data across web site failovers.

Features

  • Fast! Cache read access is typically in the 1 millisecond range, writes about 1.2 millisecond for the premium cache. The basic and standard caches are not quite that fast, but do provide a major speedup over typical database access (which is often in the hundreds to thousands of millisecond range.)
  • Ultra-fastLocal Cache - about 100 times faster than cache access.  Local Cache is great in applications like the movie app or weather apps that can use recent data. I’ll show how easy this is to configure.
  • Easy to set up, configure and use in your app. You can create a cache from 128MB to 150 GB. I’ll show how to do that later in this tutorial.
  • Works with every cloud product. Use the same cache from worker roles, web roles, web sites, VMs (even Linux VMs).
  • Huge. You can create caches from 128MB all the way to 150 GB.
  • Reliable, high availability. I’ll show how to hook up session cache, restart the web site and show session data is preserved. No more need to set up session affinity.
  • Low cost. A cache can provide a cost effective approach to speeding up your app. See the Capacity Planning Guide spreadsheet for Windows Azure Caching.
  • Multiple named caches, high availability, local cache, notifications, regions, tags, IncrementDecrement APIs, AppendPrepend APIs, Cache level BulkGet operations, expiration and eviction,  and more. See What's new in Windows Azure Caching for details.

Set up the app to use Azure caching

Create a cache on the Windows Azure portal

  1. Log into the Windows Azure portal, and click the New button on the bottom left of the screen.

    New

  2. Click Data Services, Cache, and then Quick Create.

    QuickCreate 
  3. Enter an Endpoint and a region near you (where your web site will run). In this sample we'll use the basic 128 MB cache.

    endPt

    You can use the Capacity Planning Guide spreadsheet for Windows Azure Caching to help you determine the appropriate cache size, performance and features for your application.

Configure the cache

Select the Configure tab for Cache in the Management Portal.  Each cache has a default named cache, and the Standard and Premium cache offerings support up to nine additional named caches, for a total of ten. Each named cache has its own set of options which allow you to configure your cache in a highly flexible manner.

In the image below, the default cache is configured for a one minute sliding policy.

ConfigCache

Each time a cache item is accessed, the expiration clock is reset. Setting it to one minute makes it easy to test the app.  In the download example, each page shows the cache Hit or Miss status, so setting it to one minute makes it easy to show expirations. Cache aside algorithms generally use a sliding cache. You should configure the expiration for the longest period possible that doesn’t overflow the cache and force excessive evictions. When the cache memory is full, new additions to the cache force evictions of the oldest items in the cache (LRU), and you pay a minor penalty waiting to evict the oldest cache items to make room for the new items. You can stress test your app and use the Monitor tab to see what percent of the cache capacity the app is using. (Monitoring is shown later in the tutorial.)

Configure the MvcMovie app for caching

  1. Use NuGet to install the Windows Azure Cache package. Select Online in the left tab and enter caching in the search box on the top right. Click the Install button for the Windows Azure Cache package.

    NuGet 
  2. In the Select Projects dialog click OK and then click Install.
  3. Open the root web.config file and find the <dataCacheClients> element at the bottom of the file.
  4. In the Windows Azure portal, copy the name of the Endpoint URL (fixitcache.cache.windows.net in the images above) and paste it into the identifier attribute of the <autoDiscover> element.
  5. Remove the comment characters from the <securityProperties> element and paste in the authentication key. You can get the key from the portal by clicking on Manage Keys when you've selected your cache. The code below shows the markup you must change:

    webCon

On Demand/ Cache Aside code

There are many cache approaches you can take depending on your application needs. For this sample I’ll use the on demand/cache aside approach. Each query for a movie or list of movies first searches the cache. If the data is found in the cache, it’s immediately returned without banging on the database. If the requested data is not in the cache, it uses the normal data access code, but then caches the data for the next time that data is requested. The following shows the getMovie method which is called by the Details, Edit and Delete action methods.

public class MoviesController : Controller{private MovieDBContext db = new MovieDBContext();private DataCache cache = new DataCache();Movie getMovie(int id)
   {Stopwatch sw = Stopwatch.StartNew();Movie m = (Movie)cache.Get(id.ToString());if (m == null)
      {Movie movie = db.Movies.Find(id); cache.Put(id.ToString(), movie);
         StopWatchMiss(sw);return movie;
      }
      StopWatchHit(sw);return m;
   }

When a movie is edited or deleted, it is evicted from the cache:

void ClearAllMoviesCache(int id = 0)
{if (id > 0)
   {
      cache.Remove(id.ToString());
   }
   cache.Remove("All Movies");
}

Note the code above also clear out the cache entry “All Movies”, which contains a list of all the movies and is used in the Index method.

 

Download and run the sample

Download and configure the sample using the instructions above. You must create a web site with a database. For instructions on deploying a web site with a database, see my tutorial Deploy a Secure ASP.NET MVC 5 app with Membership, OAuth, and SQL Database to a Windows Azure Web Site.

The app is configured to display timing and cache status on each page.

Note: Latency between your desktop and the cloud service cache will be high because your desktop must access the cache service in the cloud. When your web app is located in the same region as the cache service, latency will be very low, in the one millisecond range.

Configure Local Cache

In the root Web.config  file, find the <localCache> element and remove the comment characters. Local Cache, an ultra-fast second level cache stores cached items locally (in the memory of your web site or cloud service instance so there are no network hops or deserialization costs). Local Cache is hundreds of times faster than the cache service, reducing latency to the .01 millisecond range. Local Cache is not synchronized with the cache, so it shouldn't be used where you need exact data values. However you can register for notifications to update the local cache at regular intervals from the cache cluster. Deploy the updated application and you will notice cache hits are now in the .01 millisecond range.

Monitor the Cache

From the portal, click on a cache endpoint, then click Monitor. The image below shows the cache usage data over the last hour. Note the read/write requests per second are in units of a 1,000.

monitor

Click the Add Metrics button on the bottom of the portal page to add additional metrics.

image_thumb_1FB46D89

 

ASP.NET session state using a cache provider

While it’s considered a best practice is to avoid using session state, some applications can actually have a performance/complexity benefit from using some session data, and other apps require session state.  The default in memory provider for session state does not allow scale out (running multiple instances of the web site). The ASP.NET SQL Server session state provider will allow multiple web sites to use session state, but it incurs a high latency cost compared to an in memory provider. The ASP.NET session state cache provider is a low latency alternative that is very easy to configure and set up. If your app uses only a limited amount of session state, you can use most of the cache for caching data and a small amount for session state.

Configuring the ASP.NET session state cache provider

You must install the Windows Azure Cache package using NuGet (see the instructions earlier in this tutorial). In the Web.config file, remove the comments from the <sessionState> and <caching> elements inside the  <system.web> element. The following code shows the uncommented markup inside the <system.web> element:

<system.web><customErrors mode="Off"/><compilation debug="true" targetFramework="4.5" /><httpRuntime targetFramework="4.5" /><!-- Windows Azure Cache session state provider --><sessionState mode="Custom" customProvider="AFCacheSessionStateProvider"><providers><add name="AFCacheSessionStateProvider" type="Microsoft.Web.DistributedCache.DistributedCacheSessionStateStoreProvider, Microsoft.Web.DistributedCache" cacheName="default" dataCacheClientName="default" applicationName="AFCacheSessionState"/></providers></sessionState><!-- Windows Azure Cache output cache provider --><!--Uncomment this section to use Windows Azure Cache for output cache--><caching><outputCache defaultProvider="AFCacheOutputCacheProvider"><providers><add name="AFCacheOutputCacheProvider" type="Microsoft.Web.DistributedCache.DistributedCacheOutputCacheProvider, Microsoft.Web.DistributedCache" cacheName="default" dataCacheClientName="default" applicationName="AFCacheOutputCache" /></providers></outputCache></caching></system.web>

The sample download provides an easy mechanism to test session state is preserved on web site fail over. Run the download sample an click the Write Session button. You can optionally add route data to the session in the URL, such as Movies/WriteSession/MyTestSessionData.

ws

Click on the Read Session tab to read the session data. Now stop and restart the web site. (You can do this from the portal or from Visual Studio). Refresh the page or click the Read Session tab and you’ll see the PID has changed.

rs

See Session State Provider for more details. Erez Benari has a great blog on Disabling ARR’s Instance Affinity in Windows Azure Web Sites to allow you to use session state with multiple web sites, but with that approach, when a web site or host is updated, the load balancer sends subsequent requests to a new web site and all session data will be lost. If you app doesn’t use much session state and you’re using the already using the cache, you can get reliable and fast session state for practically free with the cache Session State Provider.

Caching Tips

  • For large objects, use protobuf-net, Migrant, MessagePack or another fast and flexible serialization framework.
  • Objects larger than 8MB should first be compressed or split up. To enable compression, add the isCompressionEnabled attribute to the <dataCacheClient> element:

<dataCacheClients>
    <
dataCacheClient name="default" isCompressionEnabled="true">
    

</
configuration>

  • The default the cache algorithm is well distributed,  you don’t need to manage it in your code, or worry about regions/named caches.
  • A region puts all the objects into a single instance which is useful for scenarios that need to keep related objects together (for example, you could have a region per user and keep multiple user objects user in a user region). Using regions allows you to bulk-query very efficiently. If you aren’t using bulk operations or getting tagged objects from the cache, you don’t need to create regions.
  • A single named cache is always distributed across all the nodes in the cluster, so you don’t need to create multiple named caches to distribute your data.

Let me know how you like this sample and what cache features I should add for the next version.

Follow me ( @RickAndMSFT )  on twitter where I have a no spam guarantee of quality tweets.

Resources:

Windows Azure Cache Extension Library WACEL implements high-level data structures that can be shared among your services and application. You can use WACEL data structures just as if you were using local data structures such as arrays, tables, circular buffers and OLAP cubes, and these data structures are backed by Windows Azure Cache, Windows Azure Table Storage, or both.

Microsoft Patterns and Practices - Windows Azure Guidance. See Caching guidance and Cache-Aside pattern.

Release Candidates for ASP.NET MVC 5.1, Web API 2.1 and Web Page 3.1.

$
0
0

Today we shipped release candidates for ASP.NET MVC 5.1, ASP.NET Web Pages 3.1 and Web API 2.1 to the NuGet gallery. In this release we are previewing some of the runtime features in ASP.NET and Web Tools 2013.2, which will include a broader set of updates to ASP.NET SignalR, ASP.NET Identity, Entity Framework, and the Microsoft OWIN Components as well as tooling updates to the Web Editors, Browser Link, Scaffolding, NuGet and Windows Azure WebSite publishing. We will be previewing all of these features along the way before all of the features are released.

Download this release

You can download the release candidates for ASP.NET MVC 5.1, Web API 2.1, Web Pages 3.1 as preview NuGet packages from the NuGet gallery. You can install or update to these pre-release packages through NuGet using the NuGet Package Manager Console, like this:

  • Install-Package Microsoft.AspNet.Mvc -Version 5.1.0-rc1 –Pre
  • Install-Package Microsoft.AspNet.WebApi -Version 5.1.0-rc1 –Pre
  • Install-Package Microsoft.AspNet.WebPages -Version 5.1.0-rc1 –Pre

Please remember to select the “Include Prerelease” option when searching for packages using the NuGet Package Manager or the Package Manager Console. For more information on how to install pre-release packages please read http://docs.nuget.org/docs/Reference/Versioning#Prerelease_Versions and http://docs.nuget.org/docs/release-notes/nuget-1.7#Show_prerelease_packages_in_the_Manage_NuGet_packages_dialog

Pre-requisites for this release

  • If you are using Visual Studio 2012, please download“ASP.NET and Web Tools 2013.1 for Visual Studio 2012”.
  • If you are using Visual Studio 2013, please download“Visual Studio 2013 Update 1 RC”. This update is needed for editing ASP.NET MVC 5.1 Razor Views.

What’s in the release?

You can find a complete listing of the features and fixes included in this release by referring to the release notes.

Check out some highlights of the new features included in this release below.

ASP.NET MVC 5.1

Attribute Routing

Attribute routing now supports constraints, enabling versioning and header based route selection. There's a Web API-based sample here: (https://aspnet.codeplex.com/SourceControl/latest#Samples/WebApi/RoutingConstraintsSample/ReadMe.txt); the concepts are the same as MVC.

Bootstrap support in HTML Helpers

We now allow passing in html attributes in Html.EditorFor as an anonymous object. This means you can pass in Bootstrap styles in HtmlHelpers and style the various input elements such as textboxes, dropdownlist etc. with the correct Bootstrap styles.

Support for Enums

We have added support in ASP.NET MVC 5.1 for using Enum Types in MVC views. We have added a new HTML Helper Html.EnumDropDownListFor() which will generate a dropdown when binding to Enum Types. For eg. if you have an Enum as follows.

Code Snippet
  1. publicenumMyEnum
  2. {
  3.     Sunday = 1,
  4.     Monday = 2
  5. }
  6.  
  7. publicclassTest
  8. {
  9.     publicint Id { get; set; }
  10.     publicstring MyProperty { get; set; }
  11.     publicMyEnum MyEnum { get; set; }
  12. }

When you use the EnumDropDownListFor Helper, it will generate the following view when you are creating an Enum. You can see a full sample at: https://aspnet.codeplex.com/SourceControl/latest#Samples/MVC/EnumSample/

image

ASP.NET Web API 2.1

Global Error Handling

In ASP.NET Web API, there is a centralized way to logged all unhandled exceptions. You can also use Logging frameworks such as ELMAH to log all exceptions from Web API to ELMAH.  You can look at a sample https://aspnet.codeplex.com/SourceControl/latest#Samples/WebApi/Elmah/ReadMe.txt

Attribute Routing

Attribute routing now supports constraints, enabling versioning and header based route selection. Many aspects of attribute routes are now customizable via the IDirectRouteProvider interface andRouteProviderAttribute class. The route prefix is now extensible via the IRoutePrefix interface and RoutePrefixAttribute class.

There's a Web API-based sample here (https://aspnet.codeplex.com/SourceControl/latest#Samples/WebApi/RoutingConstraintsSample/ReadMe.txt).

BSON media type formatter

We now support the BSON wire format both on the client and on the server assemblies. See a full sample at: https://aspnet.codeplex.com/SourceControl/latest#Samples/WebApi/BSONSample/

Support for Async filters

Web API now supports an easy way for authoring async filters. If your filter needs to access a database or do some async work, you can override the new virtual On*Async methods like the sample action filter below.

Code Snippet
  1. publicclassAsyncLoggingFilter : ActionFilterAttribute
  2.         {
  3.             publicoverrideasync Task OnActionExecutingAsync(HttpActionContext actionContext, CancellationToken cancellationToken)
  4.             {
  5.                 await Trace.WriteAsync("Executing action named {0} for request {1}.",
  6.                     actionContext.ActionDescriptor.ActionName,
  7.                     actionContext.Request.GetCorrelationId());
  8.             }
  9.         }

Query parsing support for the client formatting library

System.Net.Http.Formatting supported query parsing and query update for server side code, but the equivalent portable was missing this feature. In 5.1, a client application can now easily parse and update a query string.

Help Page Improvements

We have improved the Help Page feature in ASP.NET Web API so that the Help Page can provide more information such as :

  • Documentation of individual properties of parameters or return types of actions.
  • Documentation of data model annotations.
  • User interface design change to accommodate the above changes.
  • For eg. if you are returning a Course resource as shown below, the Help Page will give you additional information about the Course type.

    clip_image002

    clip_image004

Give feedback

If you have any issues with ASP.NET MVC, Web API and Web Pages, please open issues on the CodePlex site (https://aspnetwebstack.codeplex.com/workitem/list/basic). For any discussions on these features please discuss them in the ASP.NET forums. For ASP.NET MVC, please see http://forums.asp.net/1146.aspx/1?MVC and Web API http://forums.asp.net/1246.aspx/1?Web+API

Overall list of fixed issues in this release

We also made several bug fixes as a part of this release. You can find the complete list for ASP.NET MVC, Web API and Web Pages here.

ASP.NET December 2013 Security Updates

$
0
0

Today is Patch Tuesday, and the ASP.NET team would like to announce that we have two items included in this month’s release. The first is a bulletin affecting certain versions of SignalR; the second is an advisory affecting ASP.NET Web Forms (.aspx) applications. Each item is briefly outlined below. For more information, consult Security TechCenter for this month’s releases.

Cross-site scripting (XSS) vulnerability in ASP.NET SignalR

Main article: Bulletin MS13-103 (KB 2905244)

Some versions of ASP.NET SignalR contain a bug which could under certain circumstances allow an attacker to run arbitrary JavaScript in the context of a site visitor’s browser. This is an example of a cross-site scripting (XSS) attack.

Action items

If your web application uses SignalR, consult the table below for the recommended course of action.

SignalR version

Recommended steps

1.0.0 – 1.0.1

These versions of SignalR are not vulnerable to this attack, so no update is necessary. However, the 1.0.x branch is not under active support by Microsoft. It is recommended that applications upgrade to the latest 1.x version to remain in a supported state. At the time of this article’s publication, the latest supported 1.x version is 1.1.4.

1.1.0 – 1.1.3

These versions of SignalR are vulnerable to the attack, and applications which rely on them should upgrade to the latest 1.x version as soon as possible. At the time of this article’s publication, the latest supported 1.x version is 1.1.4.

2.0.0

This version of SignalR is vulnerable to the attack, and applications which rely on it should upgrade to the latest 2.x version as soon as possible. At the time of this article’s publication, the latest supported 2.x version is 2.0.1.

See KB 2905244 for more information on how to update the version of SignalR used by your application.

Insecure ASP.NET Web Forms (.aspx) configuration could allow remote code execution

Main article: KB 2905247

By default, ASP.NET Web Forms contains the configuration setting EnableViewStateMac=true, which helps verify that the __VIEWSTATE field and related fields haven’t been tampered with. MSDN warns against setting this switch to false on a production site due to the ability for an attacker to forge malicious payloads. If a web developer sets EnableViewStateMac=false for any page in his site, an attacker could leverage this to upload and invoke arbitrary executable code within the context of the web service account. This is an example of a remote code execution (RCE) attack.

Action items

The EnableViewStateMac switch has a default value of true unless the web developer has explicitly set this switch to false. To see if your application is vulnerable, search the source files that comprise your application for the term EnableViewStateMac (all one word), and verify that the switch is never set to false anywhere in your application. The search must minimally include .config, .aspx, .cs, and .vb files. However, it is safer to search all file extensions.

Important note:
The next version of ASP.NET will forbid setting EnableViewStateMac=false. Applications which set EnableViewStateMac=false may no longer function properly once this update is pushed out. Web developers must take this time to ensure that their applications do not set this switch to an insecure value.

As part of this advisory, we are also publishing a KB article on how to resolve "validation of view state MAC failed" exceptions that may have led developers to set EnableViewStateMac=false in the first place. That KB article can be found here.

Additional resources

Further information on this month’s security releases can be found at the following locations:

New tutorial for migrating applications with membership and User Profile information from Universal Providers to ASP.NET Identity

$
0
0

ASP.NET Identity is the new membership system for building ASP.NET applications. To learn more about ASP.NET Identity, please visit asp.net/identity 

The new tutorial explains how to migrate an application that uses Universal Providers for user and role management to the new ASP.NET Identity system. The tutorial also focuses on migrating user profile data created using Universal Providers. The approach mentioned to migrate profile data can be used in applications with SQL membership as well. In Universal Providers, the profile data is stored as serialized xml or binary data. Post migration, the profile data can be accessed as properties on the user class. Also serializing/de serializing profile information for each database transaction is prevented. 

Once the migration is completed, you can use the new features available in Identity: you can let users log in through their Google, Facebook, Twitter or Microsoft accounts, use OWIN authentication middleware, integrate user profile and application data, and so on. Feedback is welcome and do let us know if you hit issues during migration!

Building a basic Web Forms application using Visual Studio 2013

$
0
0

In a previous blog post, we have described the different options you have when creating a new web application with Visual Studio 2013 (VS 2013) and provided an overview of the various ASP.NET features and NuGet packages present in the templates.

In this post, I am going to take a specific template in VS 2013, namely the Web Forms template with no authentication, and describe how to build this project from scratch. At the end of the tutorial, you will end up with a template with content that is pretty much the same as creating a new VS 2013 project using Web Forms template with no authentication (File > New Project > ASP.NET Web Application (Visual C#) > Web Forms > No Authentication).

As we go through this post, you can see where and how different web technologies are leveraged by the template, which you can take and similarly apply in your existing web projects as you need.

Steps to create the Web Forms (No Auth) project from scratch

1. New Empty 4.5 CS

We start with the simplest web template: Open Visual Studio, File > New Project > ASP.NET Web Application (Visual C#) and provide a name for your project (eg: WebFormsNoAuth). In the ASP.NET project creation dialog, select “Empty” template without any additional options and hit OK.

2. Add basic master / content pages and style them with bootstrap

a. Install NuGet package : bootstrap

b. Add basic master page and content pages to your site

c. Add Site.css and style your pages using bootstrap and Site.css   

  • Notice that it is really easy to do styling with Bootstrap – you just needed the bootstrap files in your project (installed by the bootstrap NuGet package), and then reference the bootstrap.css and jQuery / bootstrap.js in Site.Master.
  • We then use many Bootstrap css classes to do the styling in pages like Site.Master (eg: navbar, navbar-collapse) and Default.aspx (eg: col-md-4, btn).
  • We also added a Site.css to add some custom styles. You can also add styles in Site.css to override styles already defined in Bootstrap. That way, if you update your Bootstrap version in the future, your overrides in Site.css remain.

d. Add favicon.ico

  • We added a favicon.ico file that many browsers will use to show in the address bar or browser tab next to your site’s URL.

At the end of this stage, you can try to F5 your project and see that you have a fully functional web application with basic pages. The pages are styled with Bootstrap and are responsive to different browser sizes. The project is fairly simple with a clean Web.config, and just 2 NuGet packages in packages.config : bootstrap and jQuery.

You can view the full code at this stage in the Git repo here.     

3. Add friendly urls

When you view a page like Contact.aspx in the browser, you can see that the extension “.aspx” still shows up at the end of the URL (eg: http://localhost:14480/Contact.aspx). We can change this to generate a friendly URL without extensions, and add routing to your web application (similar to MVC projects) by using ASP.NET Friendly Urls.

ASP.NET Friendly Urls also add View switching functionality so you can easily between a mobile view and desktop view.

To enable Friendly Urls in our application:

a. Install NuGet package : Microsoft.AspNet.FriendlyUrls

  • Open the NuGet package manager UI or console window and install the package “Microsoft.AspNet.FriendlyUrls”
  • Note that this automatically pulls down its dependent NuGet package : Microsoft.AspNet.FriendlyUrls.Core
  • If you do not have an existing RouteConfig class (like in our project), a new RouteConfig.csfile will get added for you. If you already have an existing RouteConfig class in your project, you should call EnableFriendlyUrls() in your RegisterRoutes method *before* any existing route registrations.
  • It automatically adds a Site.Mobile.Master and ViewSwitcher.ascx user control to help you easily add mobile views for your Web Forms project.       
  • InstallFriendlyUrls-Console

b. Add Global.asax and call RouteConfig.RegisterRoutes method

Now you can F5 your project again and see that the website uses ASP.NET routing and the URLs show up without the .aspx extension (eg: http://localhost:14480/Contact). You can also fixup the links in Site.Master to reference the friendly URL instead.

You can view the full code at this stage in the Git repo here.

4. Enable Web Optimization techniques such as Bundling and Minification

Bundling and minification are two web optimization techniques you can use in ASP.NET 4.5 to improve request load time. Bundling and Minification improves load time by reducing the number of requests to the server and reducing the size of requested assets (such as CSS and JavaScript). You can also learn more about adding Bundling and Minification to Web Forms.

To enable bundling and minification in our application:

a. Install NuGet package : Microsoft.AspNet.Web.Optimization.WebForms

  • Open the NuGet package manager UI or console window and install the package “Microsoft.AspNet.Web.Optimization.WebForms”
  • Note that this automatically pulls down several dependent NuGet packages : Microsoft.Web.Infrastructure, Antlr, Newtonsoft.Json, WebGrease, Microsoft.AspNet.Web.Optimization,
  • Web.config gets updated to add the new assemblies to your application

    InstallAspNetWebOpt-WebConfigChanges

b. Set up bundling of the CSS files

  • Add a Bundle.config file to your project and define the CSS bundle
  • Add the System.Web.Optimization namespace to web.config
  • Replace the CSS references in Site.Master with the webopt:BundleReference control

    CssBundling-1
           
    At this stage, if you F5 and view the page in your browser, and use the F12 tools to inspect the HTTP requests, you will see that the CSS files are not bundled yet.

    F12-OptNotEnabled

c. Turn on bundling and minification

  • To turn on bundling and minification, you can simply do this by setting the debug attribute to false in web.config
  • Alternatively, you can override the Web.config by setting with the EnableOptimizations property on the BundleTable class. So, if you want to turn on bundling and minification with debug=true, then add a BundleConfig.cs file to your App_Start folder with the following code.
         
  • You then need to update Global.asax to call BundleConfig.RegisterBundles
         
    CssBundling-2

    At this stage, if you F5 and view the page in your browser, and use the F12 tools to inspect the HTTP requests, you will see that the CSS files are now bundled and minified.

    F12-OptEnabled

You can view the full code at this stage in the Git repo here.

5. Use ScriptManager control with Web Optimization

The ScriptManger control in ASP.NET 4.5 makes it easier to register, manage and combine scripts using the ASP.NET WebOptimization feature.

Easy Integration with JQuery and Bootstrap

With ScriptManager control, you can enjoy various benefits such as :

  • Debug/Release support
  • CDN support
  • Override Script Mappings
  • Easily updating Jquery / bootstrap libraries

Here are the steps to add ScriptManager control to the application:

a. Install NuGet package : AspNet.ScriptManager.jQuery

  • Open the NuGet package manager UI or console window and install the package “AspNet.ScriptManager.jQuery”
  • Note that this updates jQuery to the matching version

b. Install NuGet package : AspNet.ScriptManager.bootstrap

  • Open the NuGet package manager UI or console window and install the package “AspNet.ScriptManager.bootstrap”

c. Update references in Site.Master to use the ScriptManager control

  • ScriptManager-SiteMaster

Remapping Framework scripts

One feature in ASP.NET 4.5 is the decoupling of the “Microsoft Ajax script files(MicrosoftAjaxCore etc)” and the WebForms scripts(GridView.js etc). You can serve these scripts from your application Scripts folder rather than load then up from System.Web. This makes the scripts easily redistributable and updateable.

Following are the steps to remap framework scripts. See 'Remapping Framework scripts' section here for more details on this feature.

a. Install NuGet package : AspNet.ScriptManager.MSAjax

  • Open the NuGet package manager UI or console window and install the package “AspNet.ScriptManager.MSAjax”
  • This installs the scripts locally in your application’s Scrips\WebForms\MSAjax folder

b. Install NuGet package : AspNet.ScriptManager.WebForms

  • Open the NuGet package manager UI or console window and install the package “AspNet.ScriptManager.WebForms”
  • This installs the scripts locally in your application’s Scrips\WebForms folder

c. Add the installed js files to a bundle in BundleConfig.cs and then reference the bundle from Site.Master.

RemapFxScripts-Diff

You can view the full code at this stage in the Git repo here.

6. Add Modernizr for HTML and CSS feature detection

Modernizr is a small JavaScript library for feature detection of HTML5 / CSS3.

a. Install NuGet package : Modernizr

  • Open the NuGet package manager UI or console window and install the package “Modernizr”
  • This adds a modernizr-*.js file in the application’s Scripts folder

b. Add the installed js files to a bundle in BundleConfig.cs and then reference the bundle from Site.Master.

  • AddModernizr-Diff

7. Add better support for older browsers like IE8 with Respond.js

You can use Respond.js to provide better support for HTML5 elements and CSS 3 media queries in older browsers like IE 8 and below.

a. Install NuGet package : Respond

  • Open the NuGet package manager UI or console window and install the package “Respond”
  • This adds respond.js and respond.min.js files in the application’s Scripts folder

b. Add the installed js files to a bundle in BundleConfig.cs and then reference the bundle from Site.Master.

  • AddRespond-Diff

8. Add _references.js for better intellisense

Finally, you can add a _references.js in your Scripts folder. This allows VS to provide JS intellisense when you are editing these files. With VS 2013, we added a new feature called autosync. With this enabled (as shown below), when you add a new JS file to your project, it will automatically add an entry in the _references.js file for you.

Summary

Ok, the post was a little long, but I hope this post was useful for you to learn about some of the different technologies that you can leverage using ASP.NET. You can view a list of all the commits for this project here.


Updating ASP.NET applications from ASP.NET Identity 1.0 to 2.0.0-alpha1

$
0
0

We released the 2.0.0-alpha1 version for ASP.NET Identity. Learn more here http://blogs.msdn.com/b/webdev/archive/2013/12/20/announcing-preview-of-microsoft-aspnet-identity-2-0-0-alpha1.aspx

One of the features in this version is Account Confirmation and Password Reset. As part of this new feature we have added two new properties to the IdentityUser class namely ‘Email’ and ‘IsConfirmed’. This results in a change of the schema created by the ASP.NET Identity system in 2.0. Updating the package in an existing application (which was using 1.0) will cause the application to fail since the Entity Framework model has been changed. You need to update your database schema to use the 2.0 features. This can be done using Entity Framework migrations. More information on migrations can be found here.

This article provides a quick overview on the migration process to 2.0.0-alpha1 from 1.0.0 version of ASP.NET Identity. We start with a web application with 1.0.0. version of Identity, have a local user registered for the application, update the Identity bits to 2.0.0-alpha1 and then migrate the database to make the application run as expected.

1. On Visual Studio 2013 RTM create a new 4.5 ASP.NET Web application(you can choose MVC or Web Forms)

clip_image001

 

2. Run the application and create a new local user. This step is analogous to users having used ASP.NET Identity 1.0.0 bits for user and role management and the database being created to store these information at the backend.

3. Now right click on project and select ‘Manage Nuget Packages’. Go to the ‘Update’ section and update the Identity packages

clip_image003

4. Now run the application and try to login old user. You would see the below error which shows that migration is needed on the database since the model is changed.

clip_image005

5. To enable migrations in Visual Studio, click on ‘View’, select ‘Package Manager Console’.

a. Enter ‘Enable Migrations’. This is create the initial configuration for the database

b. Next enter ‘Add Migrations Update1’. Here ‘Update1’ is an identifier you can have for this migration. The migrations code generated should as below

public override void Up()

{

RenameColumn(table: "dbo.AspNetUserClaims", name: "User_Id", newName: "UserId");

AddColumn("dbo.AspNetUsers", "Email", c => c.String());

AddColumn("dbo.AspNetUsers", "IsConfirmed", c => c.Boolean(nullable: false));

AlterColumn("dbo.AspNetUsers", "UserName", c => c.String(nullable: false));

DropColumn("dbo.AspNetUsers", "Discriminator");

}

public override void Down()

{

AddColumn("dbo.AspNetUsers", "Discriminator", c => c.String(nullable: false, maxLength: 128));

AlterColumn("dbo.AspNetUsers", "UserName", c => c.String());

DropColumn("dbo.AspNetUsers", "IsConfirmed");

DropColumn("dbo.AspNetUsers", "Email");

RenameColumn(table: "dbo.AspNetUserClaims", name: "UserId", newName: "User_Id");

}

To summarize the changes, there are 2 new columns added to the AspNetUsers table namely ‘Email’ and ‘IsUserConfirmed’. Also the ‘User_Id’ column in the ‘AspNetUserClaims’ table is renamed to 'UserId. The 'Discriminator' column is removed but this is more of an EF change.

NOTE: If you added custom properties on the ApplicationUser class called Email of type string and IsConfirmed of type bool and with the same names, you can delete the property in the ApplicationUser class and the properties will be mapped on to the one in IdentityUser base class. If the properties had different names and types, we would need to add a mapping for them in the DBContext class. Please refer to the following link for more mapping information.

c. Next we need to persist it to the database. Run the command ‘Update-Database -verbose’. The verbose flag lets you view the SQL queries generated. This should pass as expected

If you face issues with migrating to 2.0, please open issues on https://aspnetidentity.codeplex.com.

Announcing preview of Microsoft.AspNet.Identity 2.0.0-alpha1

$
0
0

Today, we are releasing a preview of ASP.NET Identity. The main focus in this release was to fix issues with the 1.0 release and build upon the 1.0 Framework to add more features such as Account Confirmation, Password Reset etc. Please read the known issues section below before trying out this preview. 

Download this release

You can download ASP.NET Identity as preview NuGet packages from the NuGet gallery. You can install or update to these pre-release packages through NuGet using the NuGet Package Manager Console, like this:

  • Install-Package Microsoft.AspNet.Identity.EntityFramework –Version 2.0.0-alpha1 –Pre
  • Install-Package Microsoft.AspNet.Identity.Core -Version 2.0.0-alpha1 –Pre
  • Install-Package Microsoft.AspNet.Identity.OWIN -Version 2.0.0-alpha1 –Pre

Please remember to select the “Include Prerelease” option when searching for packages using the NuGet Package Manager or the Package Manager Console. For more information on how to install pre-release packages please read http://docs.nuget.org/docs/Reference/Versioning#Prerelease_Versions and http://docs.nuget.org/docs/release-notes/nuget-1.7#Show_prerelease_packages_in_the_Manage_NuGet_packages_dialog

 

What’s in this release

Following is the list of features and major issues that were fixed.

Account Confirmation

The ASP.NET Identity system now supports Account Confirmation. This is a fairly common scenario in most websites today where when you register for a new account on the website, you are required to confirm your email before you could do anything in the website. Email Confirmation is useful because it prevents bogus accounts from being created. This is extremely useful if you are using email as a method of communicating with the users of your website such as Forum sites, banking, ecommerce, social web sites.

Note: To send emails you can configure SMTP Server or use some of the popular email services such as SendGrid (http://sendgrid.com/windowsazure.html) which integrate nicely with Windows Azure and require no configuration on the application developer

In the sample project below, you need to hook up the Email service for sending emails. You will not be able to reset your password until you confirm your account 

Password Reset

Password Reset is a feature where the user can reset their passwords if they have forgotten their password.  

Security Token Provider

Support a way to regenerate the Security Token for the user in cases when the User changes there password or any other security related information such as removing an associated login(such as Facebook, Google, Microsoft Account etc). This is needed to ensure that any tokens generated with the old password are invalidated. In the sample project, if you change the users password then a new token is generated for the user and any previous tokens are invalidated. This feature provides an extra layer of security to your application since when you change your password, you will be logged out from everywhere (all other browsers) where you have logged into this application.

You can configure this in Startup.Auth.cs as follows. You can specify how often should the OWIN cookie middleware check if the Security Token for the current user is valid. This is in the sample project listed below.

Code Snippet
  1. // Enable the application to use a cookie to store information for the signed in user
  2. // and to use a cookie to temporarily store information about a user logging in with a third party login provider
  3. // Configure the sign in cookie
  4. app.UseCookieAuthentication(newCookieAuthenticationOptions {
  5.     AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
  6.     LoginPath = newPathString("/Account/Login"),
  7.     Provider = newCookieAuthenticationProvider {
  8.         OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
  9.             validateInterval: TimeSpan.FromSeconds(5),
  10.             regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
  11.     }
  12. });

 

Make the type of Primary Key be extensible for Users and Roles

In 1.0 the type of PK for Users and Roles was strings. This means when the ASP.NET Identity system was persisted in Sql Server using Entity Framework, we were using nvarchar. There were lots of discussions around this default implementation on Stack Overflow and based on the incoming feedback, we have provided an extensibility hook where you can specify what should be the PK of your Users and Roles table. This extensibility hook is particularly useful if you are migrating your application and the application was storing UserIds are GUIDs or ints.

Since you are changing the type of PK for Users and Roles, you need to plug in the corresponding classes for Claims, Logins which take in the correct PK. Following is a snippet of code which shows how you can change the PK to be int

Code Snippet
  1. publicclassApplicationUser : IdentityUser<int, CustomUserLogin, CustomUserRole, CustomUserClaim>
  2. {
  3. }
  4. publicclassCustomRole : IdentityRole<int, CustomUserRole>
  5. {
  6.     public CustomRole() { }
  7.     public CustomRole(string name) { Name = name; }
  8. }
  9. publicclassCustomUserRole : IdentityUserRole<int> { }
  10. publicclassCustomUserClaim : IdentityUserClaim<int> { }
  11. publicclassCustomUserLogin : IdentityUserLogin<int> { }
  12.  
  13. publicclassApplicationDbContext : IdentityDbContext<ApplicationUser, CustomRole, int, CustomUserLogin, CustomUserRole, CustomUserClaim>
  14. {
  15. }

 

Support IQueryable on Users and Roles

We have added support for IQueryable on UsersStore and RolesStore so you can easily get the list of Users and Roles.

For eg. the following code uses the IQueryable  and shows how you can get the list of Users from UserManager. You can do the same for getting list of Roles from RoleManager

Code Snippet
  1. //
  2. // GET: /Users/
  3. publicasyncTask<ActionResult> Index()
  4. {
  5.     return View(await UserManager.Users.ToListAsync());
  6. }

 

Support Delete operation through the UserManager

In 1.0, if you had to delete a User, you could not do it through the UserManager. We have fixed this issue in this release so you can do the following to delete a user

Code Snippet
  1. var user = await UserManager.FindByIdAsync(id);
  2.                 if (user == null)
  3.                 {
  4.                     return HttpNotFound();
  5.                 }
  6.                 var result = await UserManager.DeleteAsync(user);

 

UserManagerFactory Middleware

You can use Factory implementation to get an instance of UserManager from the OWIN context. This pattern is similar to what we use for getting AuthenticationManager from OWIN context for SignIn and SignOut. This is a recommended way of getting an instance of UserManager per request for the application.

Following snippet of code shows how you can configure this middleware in StartupAuth.cs. This is in the sample project listed below.

Code Snippet
  1. // Configure the UserManager
  2.             app.UseUserManagerFactory(newUserManagerOptions<ApplicationUserManager>()
  3.             {
  4.                 DataProtectionProvider = app.GetDataProtectionProvider(),
  5.                 Provider = newUserManagerProvider<ApplicationUserManager>()
  6.                 {
  7.                     OnCreate = ApplicationUserManager.Create
  8.                 }
  9.             });

Following snippet of code shows how you can get an instance of UserManager

Code Snippet
  1. HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();

 

DbContextFactory Middleware

ASP.NET Identity uses EntityFramework for persisting the Identity system in Sql Server. To do this the Identity System has a reference to the ApplicationDbContext. The DbContextFactory Middleware returns you an instance of the ApplicationDbContext per request which you can use in your application.

Following code shows how you can configure it in StartupAuth.cs. The code for this middleware is in the sample project.

Code Snippet
  1. app.UseDbContextFactory(ApplicationDbContext.Create);

Samples

  • We have a sample project which shows these new features at https://aspnet.codeplex.com. Please look for the Identity folder in the source. https://aspnet.codeplex.com/SourceControl/latest#Samples/Identity
    • This project shows how a ASP.NET Web Application project template would look like. Please look at the readme in the project for instructions on how to run.
  • For documentation on ASP.NET Identity 1.0 please visit http://www.asp.net/identity. We are working on adding more documentation on this site.

 

Known Issues/ Breaking change

As part of these new features such as Account Confirmation and Password Reset, we have added two new properties to the IdentityUser class namely ‘Email’ and ‘IsConfirmed’. This results in a change of the schema created by the ASP.NET Identity system in 2.0. Updating the packages to 2.0 in an existing application (which was using 1.0) will cause the application to fail since the underlying Entity Framework model has been changed. You need to update your database schema to use the 2.0 features. This can be done using Entity Framework migrations. For more details on how to update your application from 1.0 to 2.0, please visit this detailed blog posthttp://blogs.msdn.com/b/webdev/archive/2013/12/20/updating-asp-net-applications-from-asp-net-identity-1-0-to-2-0-0-alpha1.aspx

Note:

This is an area of migration which we are trying to see if we can provide a better story before we release the final version. Since the new features requires database schema updates, there is a user action involved to update the database manually. It is due to this reason that we have updated the package version to 2.0.0 as per SemVer guidelines, since on installing this version will break existing applications and you have to update the database schema.

ASP.NET Identity 2.0.0-alpha1 depends upon EntityFramework 6.1.0-alpha1 which was also released today (http://blogs.msdn.com/b/adonet/archive/2013/12/20/ef-6-1-alpha-1-available.aspx) since in EntityFramework 6.1.0-alpha1, there were bug fixes which helped in improving the migration scenario from Identity 1.0 – 2.0

 

Give feedback and get support

  • If you find any bugs please open them at our Codeplex Site where we track all our bugs https://aspnetidentity.codeplex.com/
  • If you want to discuss these features, please discuss them on Stack Overflow and use the following tag “asp.net-identity”

 

What’s next

We still have many bugs to fix and a few features to add before we release the final RTM version so do expect a few more previews in the coming months. You can check our roadmap at https://aspnetidentity.codeplex.com/wikipage?title=Roadmap&version=1

 

Thank You for trying out the preview and your feedback for ASP.NET

How to customize the generated files from the New Scaffolded Item dialog

$
0
0

In Visual Studio 2013 we introduced the Add New Scaffolded Item dialog. This dialog replaced the Add View/Add Controllers ASP.NET MVC dialog which was had in 2012. This new dialog works for all ASP.NET projects (MVC, Web Forms and Web API). This is one example of how we are delivering on the “One ASP.NET” vision. We’ve also released the same support for Visual Studio 2012, checkout our previous post at http://blogs.msdn.com/b/webdev/archive/2013/11/18/announcing-release-of-asp-net-and-web-tools-2013-1-for-visual-studio-2012.aspx for more info on how to get started in VS2012 with the new features.

One of the really great features that we had with the Add View/Add Controller ASP.NET MVC dialog was the ability to override the generated output of the dialog box. The method to do this was pretty simple. If you wanted to tweak the result of the dialog box you’d have to copy the corresponding T4 file (more info on T4) into the right spot in your project, modify it to suit your needs and after that when you invoke the dialog box the updated t4 file(s) will be used instead of the default ones. We follow this same pattern. We’ve simplified the end-to-end flow though by using SideWaffle.

In this post I’ll first describe how you can customize the generated contents of the New Scaffoldded Item dialog box as well as explain how that works. To simplify the end-to-end flow we will be using using SideWaffle. I’ve got some steps at the bottom regarding the usage in case you would like to avoid installing SideWaffle. Try the steps below to get started.

How to customize the generated output

To customize the generated content for a particular project follow these steps.

  1. Download and install SideWaffle if you haven’t already
  2. Right click on your web project and chose Add New Item. Select the template shown in the image below and click OK.
    1. SNAGHTMLf263605
  3. Customize the .t4 files found under the CodeTemplates folder in your project

After you invoke the ASP.NET Scaffolding T4 files item template it will drop all the .t4 files you need into a top level folder in your project named CodeTemplates. Based on your project language (C#/VB) the correct files are added to the project. Each folder under this folder represents an individual scaffolder that we ship. In the image below you can see these folder names.

image

You can connect the folder to the scaffolder by the name of the folder. The names are pretty straight forward, for example the MvcControllerEmpty folder corresponds to the MVC 5 Controller – Empty scaffolder. Under each folder you’ll find the files that the specific scaffolder will use during the scaffolding process. Since most existing scaffolders generate 1 file you’ll typically find only 1 .t4 file in the directory. For scaffolders which generate more than 1 file you’ll find additional files.

Let’s tweak the Empty MVC controller scaffold. Let’s take a look at what’s under the MvcControllerEmpty folder. That folder has a single .t4 file, Controller.cs.t4 (or Controller.vb.t4 if VB). Below is the current content of this file.

<#@ template language="C#" HostSpecific="True" #>
<#@ output extension="cs" #>
<#@ parameter type="System.String" name="ControllerName" #>
<#@ parameter type="System.String" name="ControllerRootName" #>
<#@ parameter type="System.String" name="Namespace" #>
<#@ parameter type="System.String" name="AreaName" #>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace <#= Namespace #>
{
    public class <#= ControllerName #> : Controller
    {
        //
        // GET: <#= (!String.IsNullOrEmpty(AreaName)) ? ("/" + AreaName) : String.Empty #>/<#= ControllerRootName #>/
        public ActionResult Index()
        {
            return View();
        }
    }
}

Let’s say that you prefer to place your using statements inside of the namespace we’ll modify this file to have the following content instead.

<#@ template language="C#" HostSpecific="True" #>
<#@ output extension="cs" #>
<#@ parameter type="System.String" name="ControllerName" #>
<#@ parameter type="System.String" name="ControllerRootName" #>
<#@ parameter type="System.String" name="Namespace" #>
<#@ parameter type="System.String" name="AreaName" #>
namespace <#= Namespace #>
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;

    public class <#= ControllerName #> : Controller
    {
        //
        // GET: <#= (!String.IsNullOrEmpty(AreaName)) ? ("/" + AreaName) : String.Empty #>/<#= ControllerRootName #>/
        public ActionResult Index()
        {
            return View();
        }
    }
}

Now when I create a new Empty MVC controller the generated output is as follows.

namespace WebApplication2.Controllers
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;

    public class Default3Controller : Controller
    {
        //
        // GET: /Default3/
        public ActionResult Index()
        {
            return View();
        }
    }
}

That’s all there is to it. You can check in the files and then when your team members get latest they will have the same behavior.

How to get started without SideWaffle

If you would like to do this without installing SideWaffle, it’s still very easy. You can just copy the files from your local machine into your project. You’ll find all the folders that you need to copy at C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\Extensions\Microsoft\Web\Mvc\Scaffolding\Templates. You can copy the contents of that folder into a top level folder named CodeTemplates into your project as shown above. FYI if you do this both C# and VB files will be added to your project. You can simply get rid of the files that do not correspond to the language that your project is using.

This sample is pretty basic but I’m sure that you can imagine much more sophisticated tweaks for your particular needs. Please let us know what you think about these features in the comments below. I personally really love the model where we generate some content by default but you can tweak that by checking in some artifacts into your project. I’d like to see where we can apply this same thinking in other areas across the product. Keep an eye out in the future for similar efforts.

Thanks,
Sayed Ibrahim Hashimi | http://msbuildbook.com/ | @SayedIHashimi

Implementing custom password policy using ASP.NET Identity

$
0
0

We recently released the 2.0.0-alpha1 version of ASP.NET Identity. Learn more here: http://blogs.msdn.com/b/webdev/archive/2013/12/20/announcing-preview-of-microsoft-aspnet-identity-2-0-0-alpha1.aspx

To provide a more secure user experience for the application, you might want to customize the password complexity policy. This might include minimum password length, mandatory special characters in the password, disallowing recently used passwords, etc. More information on password policy can be found here. By default ASP.NET Identity enforces a minimum password length of 6 characters. This article provides a simple walkthrough that shows how to add a few more password policies to an application.

We will create an application using Visual Studio 2013, update the Identity assemblies to 2.0.0-alpha1, and then add code to enforce the following password policies:

i. Change the default password length requirement from 6 characters to 10 characters.

ii. The password should have at least one number and one special character.

iii. The user cannot reuse any of the last 5 previous passwords.

Lastly we’ll run the application to verify if these policies have been successfully enforced.

Create application

  • In Visual Studio 2013 RTM create a new 4.5 ASP.NET Web application. Choose MVC.

image

  • Right-click the project and select ‘Manage Nuget Packages’. Go to the ‘Update’ section and update the Identity packages to 2.0.0-alpha1

image

  • Let’s quickly look at the user creation flow in the application. This will help us outline the password validation steps in the Identity system. Under the Controllers folder, the AccountController has actions for user account management.
    • The Account controller uses an instance of UserManager class which is defined in the Identity framework. This takes a UserStore class which has persistence-specific API for user management. In our case it uses Entity Framework.
    • The Register post method creates a new user. The call to CreateAsync in turn calls the ‘ValidateAsync’ method on the PasswordValidator property to validate the supplied password.
 1: var user = new ApplicationUser() { UserName = model.UserName };
 2:  
 3: var result = await UserManager.CreateAsync(user, model.Password);
 4:  
 5:if (result.Succeeded)
 6: {
 7: await SignInAsync(user, isPersistent: false);
 8:  
 9:return RedirectToAction("Index", "Home");
 10: }
 11:  
 
      
    • On success the user is signed in.

Similarly, password validation is called when the user tries to change the password. This can be observed in the ‘Manage’ post action.

Policy 1: Change the default password length requirement from 6 characters to 10 characters.

By default the PasswordValidator property in UserManager is set to the MinimumLengthValidator class which validates that the password length is at least 6. This value can be changed when instantiating a UserManager object.

  • The minimum password length value can be changed in the AccountController in the constructor where the UserManager is instantiated or at a global level by defining a separate class derived from UserManager. The second approach is possible by extending the UserManager class in the application and setting the property. Under the IdentityExtensions folder, create a new class ApplicationUserManager which extends from UserManager<ApplicationUser>.

    

 1:publicclass ApplicationUserManager : UserManager<ApplicationUser>
 2: {
 3:public ApplicationUserManager(): base(new UserStore<ApplicationUser>(new ApplicationDbContext()))
 4:         {
 5:               PasswordValidator = new MinimumLengthValidator (10);
 6:         }
 7: }
 8:

The UserManager class takes an IUserStore class which is a persistence-specific implementation of user management APIs. Since the UserStore class is EntityFramework-specific, we need to pass in the DbContext object. This call is essentially the same as defined in the constructor of the AccountController class.

The additional advantage of defining the custom ApplicationUserManager class is that we can override methods defined in the UserManager class, which we will be doing for the subsequent password policies.

  • We then need to hook in the ApplicationUserManager class defined in the above step in the AccountController. Change the constructor and the UserManager Property in the AccountControlleras below.
      
 1:public AccountController() : this(new ApplicationUserManager())
 2:         {
 3:         }
 4:  
 5:public AccountController(ApplicationUserManager userManager)
 6:         {
 7:             UserManager = userManager;
 8:         }
 9:public ApplicationUserManager UserManager { get; private set; }
 

This way we are making the AccountController use the custom UserManager. This enables you to do additional customization while keeping the other code in the controller intact.

  • Run the application and try to register a local user. If the password is less than 10 characters in length, you’ll get the following error message.

image

Policy 2: Passwords should have at least one special character and one numeral

As mentioned in the previous section, the PasswordValidator property in the UserManager class validates the length of the password to 6 characters. Though we can change the ‘RequiredLength’, to add additional checks we would need to extend the behavior through a new class. We can add new password validators by creating a class that implements the IIdentityValidator interface and adding the validations as needed. In our case we want to check for special characters and numbers in the supplied password along with checking if it is of minimum length in the ‘ValidateAsync’ method.

  • Create a new folder under the root project called IdentityExtensions. Add a new class CustomPasswordValidator implementing IIdentityValidator<string> since password is of type string.
 1:publicclass CustomPasswordValidator : IIdentityValidator<string>
 2:  
 3: {
 4:  
 5:publicint RequiredLength { get; set; }
 6:  
 7:public CustomPasswordValidator(int length)
 8:  
 9: {
 10:  
 11: RequiredLength = length;
 12:  
 13: }
 14:  
 15:public Task<IdentityResult> ValidateAsync(string item)
 16:  
 17: {
 18:  
 19:if (String.IsNullOrEmpty(item) || item.Length < RequiredLength)
 20:  
 21: {
 22:  
 23:return Task.FromResult(IdentityResult.Failed(String.Format("Password should be of length {0}",RequiredLength)));
 24:  
 25: }
 26:  
 27:string pattern = @"^(?=.*[0-9])(?=.*[!@#$%^&*])[0-9a-zA-Z!@#$%^&*0-9]{10,}$";
 28:  
 29:if (!Regex.IsMatch(item, pattern))
 30:  
 31: {
 32:  
 33:return Task.FromResult(IdentityResult.Failed("Password should have one numeral and one special character"));
 34:  
 35: }
 36:  
 37:return Task.FromResult(IdentityResult.Success);
 38:  
 39: }

In the ValidateAsync method, we check if the password is of the specified length. Then we use a regular expression to verify if the password has a special character and a numeric character. Note: The regular expression is not tested fully and should be used as a sample only.

  • Next we need to set this validator in the PasswordValidator property of the UserManager. Navigate to the ApplicationUserManager created earlier and change the PasswordValidator property from MinimumLengthValidator to CustomPasswordValidator.
 1:publicclass ApplicationUserManager : UserManager<ApplicationUser[PR6] >
 2:  
 3: {
 4:  
 5:public ApplicationUserManager()
 6:  
 7: : base(new UserStore<ApplicationUser(new ApplicationDbContext()))
 8:  
 9: {
 10:  
 11: PasswordValidator = new CustomPasswordValidator(10);
 12:  
 13: }
 14:  
 15: }
  • No change is needed in the AccountController class. Now try to create a user with password that does not meet the requirements. An error message is displayed as shown below.

image

Policy 3: The user cannot reuse the last five previous passwords

When existing users change or reset their password, we can check if they are trying to reuse an old password. This is not done by default since the Identity system does not store the password history per user. We can do this in the application by creating a separate table to store password history per user and then retrieve the password hashes whenever the user tries to reset or change password.

  • Open the IdentityModels.cs file in the editor. Create a new class called ‘PreviousPassword’ as shown below.
 1:publicclass PreviousPassword
 2:  
 3: {
 4:  
 5:public PreviousPassword()
 6:  
 7: {
 8:  
 9: CreateDate = DateTimeOffset.Now;
 10:  
 11: }
 12:  
 13: [Key, Column(Order = 0)]
 14:  
 15:publicstring PasswordHash { get; set; }
 16:  
 17:public DateTimeOffset CreateDate { get; set; }
 18:  
 19: [Key, Column(Order = 1)]
 20:  
 21:publicstring UserId { get; set; }
 22:  
 23:publicvirtual ApplicationUser User { get; set; }
 24:  
 25: }

In this class, the ‘Password’ field holds the hashed password for the user referenced by the field ‘UserId’. The ‘CreateDate’ holds the timestamp when the password was added. This can be used to filter the password history to get the last 5 passwords or the latest password.

EntityFramework code first creates a corresponding table called ’PreviousPasswords’ with the ‘UserId’ and the ‘Password’ field forming the composite primary key. You can read more about code first conventions here.

  • Add a property on the user class ‘ApplicationUser’ to hold a list of previous passwords
 1:publicclass ApplicationUser : IdentityUser
 2:     {
 3:public ApplicationUser()
 4:             : base()
 5:         {
 6:             PreviousUserPasswords = new List<PreviousPassword>();
 7:         }
 8:publicvirtual IList<PreviousPassword> PreviousUserPasswords { get; set; }
 9:  
 10:     }
  • As explained in Policy 1, the UserStore class holds the persistence-specific methods for user operations. We need to store the password hash in the history table when the user is created for the first time. Since the UserStore does not define such a method separately, we need to define an override for the existing method to store the password history. This can be done by extending the existing UserStore class and override the existing methods to store the passwords. This is then hooked in the ApplicationUserManager. Add a new class under the IdentityExtensions folder.
 1:publicclass ApplicationUserStore : UserStore<ApplicationUser>
 2:  
 3: {
 4:  
 5:public ApplicationUserStore(DbContext context)
 6:  
 7: : base(context)
 8:  
 9: {
 10:  
 11: }
 12:  
 13:publicoverride async Task CreateAsync(ApplicationUser user)
 14:  
 15: {
 16:  
 17: await base.CreateAsync(user);
 18:  
 19: await AddToPreviousPasswordsAsync(user, user.PasswordHash);
 20:  
 21: }
 22:  
 23:public Task AddToPreviousPasswordsAsync(ApplicationUser user, string password)
 24:  
 25: {
 26:  
 27: user.PreviousUserPasswords.Add(new PreviousPassword() { UserId = user.Id, PasswordHash = password });
 28:  
 29:return UpdateAsync(user);
 30:  
 31: }
 32:  
 33: }

The ‘AddToPreviousPasswordsAsync’ method stores the password in the ‘PreviousPasswords’ table separately

  • We need to call the above method whenever user tries to change or reset a password. The API’s to do this are defined in the UserManager class. We need to override them and include the above password history method call. We can do this by overriding the ChangePassword and ResetPassword methods in the ApplicationUserManager class defined in the Policy 2.
 1:publicclass ApplicationUserManager : UserManager<ApplicationUser>
 2:  
 3: {
 4:  
 5:privateconstint PASSWORD_HISTORY_LIMIT = 5;
 6:  
 7:public ApplicationUserManager()
 8:  
 9: : base(new ApplicationUserStore(new ApplicationDbContext()))
 10:  
 11:  {
 12:  
 13: PasswordValidator = new CustomPasswordValidator(10);
 14:  
 15:  }
 16:  
 17:publicoverride async Task<IdentityResult> ChangePasswordAsync(string userId, string currentPassword, string newPassword)
 18:  
 19: {
 20:  
 21:if (await IsPreviousPassword(userId, newPassword))
 22:  
 23: {
 24:  
 25:return await Task.FromResult(IdentityResult.Failed("Cannot reuse old password"));
 26:  
 27: }
 28:  
 29: var result = await base.ChangePasswordAsync(userId, currentPassword, newPassword);
 30:  
 31:if (result.Succeeded)
 32:  
 33: {
 34:  
 35: var store = Store as ApplicationUserStore;
 36:  
 37: await store.AddToPreviousPasswordsAsync(await FindByIdAsync(userId), PasswordHasher.HashPassword(newPassword));
 38:  
 39: }
 40:  
 41:return result;
 42:  
 43: }
 44:  
 45:publicoverride async Task<IdentityResult> ResetPasswordAsync(string userId, string token, string newPassword)
 46:  
 47: {
 48:  
 49:if (await IsPreviousPassword(userId, newPassword))
 50:  
 51: {
 52:  
 53:return await Task.FromResult(IdentityResult.Failed("Cannot reuse old password"));
 54:  
 55: }
 56:  
 57: var result = await base.ResetPasswordAsync(userId, token, newPassword);
 58:  
 59:if (result.Succeeded)
 60:  
 61: {
 62:  
 63: var store = Store as ApplicationUserStore;
 64:  
 65: await store.AddToPreviousPasswordsAsync(await FindByIdAsync(userId), PasswordHasher.HashPassword(newPassword));
 66:  
 67: }
 68:  
 69:return result;
 70:  
 71: }
 72:  
 73:private async Task<bool> IsPreviousPassword(string userId, string newPassword)
 74:  
 75: {
 76:  
 77: var user = await FindByIdAsync(userId);
 78:  
 79:if (user.PreviousUserPasswords.OrderByDescending(x => x.CreateDate).
 80:  
 81: Select(x => x.PasswordHash).Take(PASSWORD_HISTORY_LIMIT).Where(x => PasswordHasher.VerifyHashedPassword(x, newPassword) != PasswordVerificationResult.Failed
 82:  
 83: ).Any())
 84:  
 85: {
 86:  
 87:returntrue;
 88:  
 89: }
 90:  
 91:returnfalse;
 92:  
 93: }
 94:  
 95: }

The ‘PASSWORD_HISTORY_LIMIT’ field is used to get the last ‘X’ number of passwords from the table. Notice we hooked in the ApplicationUserStore in the constructor to get the new method to store the password. Whenever the user changes the password, we validate it against the last 5 passwords stored in the table and return true/false based on the validation.

  • Create a local user and go to Manage page. Try to change the password using same password when the user is created. You see a message as shown below.

image

Code Sample

The sample project Identity-PasswordPolicy is checked into http://aspnet.codeplex.com/SourceControl/latest under Samples/Identity.

Summary

This post shows how you can extend the ASP.NET Identity Validation system to enforce different types of password policies for the users of your application. The example uses the MVC template, but the same changes can be applied to a web forms application.

I hope you have found this walkthrough useful. If you have any questions around ASP.NET Identity or find issues, please feel free to open bugs on the Identity Codeplex site, https://aspnetidentity.codeplex.com/ , leave comments on this blog, or ask questions on asp.net/forums or StackOverflow(tag: aspnet-identity). I can also be reached on twitter (@suhasbjoshi).


Announcing E-book version of Scott Guthrie’s “Building Real-World Cloud Apps with Windows Azure”

$
0
0

We have published online and downloadable e-book versions of Scott Guthrie’s presentation titled Building Real-World Cloud Apps with Windows Azure (original video version is available here: part 1, part 2).

Along with the e-book we published the code for the Fix It application that Scott developed to demonstrate many of the recommended cloud development patterns. Before publishing the code, we worked with Microsoft Patterns and Practices to do a thorough code review and testing. In an Appendix to the e-book, we document what we learned from that process, listing issues we fixed and issues we deferred to a later release.

If you’re curious about developing for the cloud, considering a move to the cloud, or are new to cloud development, you’ll find in this e-book a concise overview of the most important concepts and practices you need to know. The concepts are illustrated with concrete examples, and each chapter links to other resources for more in-depth information.    

Table of contents

  • Introduction.
    • Intro to the Fix It sample application
    • Intro to Windows Azure Web Sites
    • Creating and deploying a simple web app
  • Automate everything.
    • Use scripts to maximize efficiency and minimize errors in repetitive processes.
    • Demo: Windows Azure management scripts.
  • Source control.
    • Set up branching structure in source control to facilitate DevOps workflow.
    • Demo: add scripts to source control.
    • Demo: keep sensitive data out of source control.
    • Demo: use Git in Visual Studio.
  • Continuous integration and delivery.
    • Automate build and deployment with each source control check-in.
  • Web development best practices.
    • Keep web tier stateless.
    • Demo: scaling and auto-scaling in Windows Azure Web Sites.
    • Avoid session state.
    • Use a CDN.
    • Use asynchronous programming model.
    • Demo: async in ASP.NET MVC and Entity Framework.
  • Single sign-on.
    • Introduction to Windows Azure Active Directory.
    • Demo: create an ASP.NET app that uses Windows Azure Active Directory.
  • Data storage options.
    • Types of data stores.
    • How to choose the right data store.
    • Demo: Windows Azure SQL Database.
  • Data partitioning strategies.
    • Partition data vertically, horizontally, or both to facilitate scaling a relational database.
  • Unstructured blob storage.
    • Store files in the cloud by using the blob service.
    • Demo: using blob storage in the Fix It app.
  • Design to survive failures.
    • Types of failures.
    • Failure Scope.
    • Understanding SLAs.
  • Monitoring and telemetry.
    • Why you should both buy a telemetry app and write your own code to instrument your app.
    • Demo: New Relic for Windows Azure
    • Demo: logging code in the Fix It app.
    • Demo: built-in logging support in Windows Azure.
  • Transient fault handling.
    • Use smart retry/back-off logic to mitigate the effect of transient failures.
    • Demo: retry/back-off in Entity Framework 6.
  • Distributed caching.
    • Improve scalability and reduce database transaction costs by using distributed caching.
  • Queue-centric work pattern.
    • Enable high availability and improve scalability by loosely coupling web and worker tiers.
    • Demo: Windows Azure storage queues in the Fix It app.
  • More cloud app patterns and guidance.
  • Appendix: The Fix It Sample Application
    • Known Issues
    • Best Practices
    • How to download, build, run, and deploy.

Acknowledgments

The e-book was written by Tom Dykstra, Rick Anderson, and Mike Wasson. Most of the original content came from Scott Guthrie, and he in turn drew on material from Mark Simms and the Microsoft Customer Advisory Team (CAT).

Many other colleagues at Microsoft reviewed and commented on drafts and code:

  • Tim Ammann - Reviewed the automation chapter.
  • Christopher Bennage - Reviewed and tested the Fix It code.
  • Ryan Berry - Reviewed the CD/CI chapter.
  • Vittorio Bertocci - Reviewed the SSO chapter.
  • Chris Clayton - Helped resolve technical problems in the PowerShell scripts.
  • Conor Cunningham - Reviewed the data storage options chapter.
  • Carlos Farre - Reviewed and tested the Fix It code for security issues.
  • Larry Franks - Reviewed the telemetry and monitoring chapter.
  • Jonathan Gao - Reviewed Hadoop and MapReduce sections of the data storage options chapter.
  • Sidney Higa - Reviewed all chapters.
  • Gordon Hogenson - Reviewed the source control chapter.
  • Tamra Myers - Reviewed data storage options, blob, and queues chapters.
  • Pranav Rastogi - Reviewed the SSO chapter.
  • June Blender Rogers - Added error handling and help to the PowerShell automation scripts.
  • Mani Subramanian - Reviewed all chapters and led the code review and testing process for the Fix It code.
  • Shaun Tinline-Jones - Reviewed the data partitioning chapter.
  • Selcin Tukarslan - Reviewed chapters that cover SQL Database and SQL Server.
  • Edward Wu - Provided sample code for the SSO chapter.
  • Guang Yang - Wrote the PowerShell automation scripts.

Members of the Microsoft Developer Guidance Advisory Council (DGAC) also reviewed and commented on drafts:

  • Jean-Luc Boucho
  • Catalin Gheorghiu
  • Wouter de Kort
  • Carlos dos Santos
  • Neil Mackenzie
  • Dennis Persson
  • Sunil Sabat
  • Aleksey Sinyagin
  • Bill Wagner
  • Michael Wood

Other members of the DGAC reviewed and commented on the preliminary outline:

  • Damir Arh
  • Edward Bakker
  • Srdjan Bozovic
  • Ming Man Chan
  • Gianni Rosa Gallina
  • Paulo Morgado
  • Jason Oliveira
  • Alberto Poblacion
  • Ryan Riley
  • Perez Jones Tsisah
  • Roger Whitehead
  • Pawel Wilkosz
Viewing all 7144 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>