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

View Persisted Logs in Azure Storage in Visual Studio 2012

$
0
0

In ScottGu’s Blog “Announcing the release of Windows Azure SDK 2.0 for .NET”, among all other new features, you learn how to stream your Windows Azure Web Site’s application logs into Visual Studio. It might be also useful if you persist those same logs in Azure Table Storage and view them in Visual Studio for certain time intervals. This blog will describe the steps how to achieve that.

You need to install Windows Azure SDK 2.0 for .NET from Windows Azure .NET Developer Center in order to use this feature.

Add Tracing To Your Application

Add some tracing in a WebForm application with Systyem.Diagnostics.Trace. To test, I usually add some traces inside the Page_Load method as shown below.

   1:  publicpartialclass _Default : Page
   2:      {
   3:  protectedvoid Page_Load(object sender, EventArgs e)
   4:          {
   5:              System.Diagnostics.Trace.TraceError("Application Error.");
   6:              System.Diagnostics.Trace.TraceWarning("Application Warning.");
   7:              System.Diagnostics.Trace.TraceInformation("Application Information.");
   8:              System.Diagnostics.Trace.WriteLine("Application WriteLine.");
   9:          }
  10:      }

Publish the project to Azure from VS 2012.

Store Application Logs in an Azure Table Storage

- At the Azure Portal, create a storage to store our application logs.

image

 

- You need to associate your web site with this storage by clicking on the “manage connection” under the Configure tab of your Azure site.

image

 

- Select the storage you created above in the pop-up dialog.

image

 

- This setting will show up under the Connection strings section of the site after the steps above.

image

 

Alternatively, you can set this connection string “CLOUD_STORAGE_ACCOUNT” manually within VS if you know the storage account key

image

- You can obtain the storage account’s key from the “Modify Account” dialog of the storage listed under “Windows Azure Storage” node in Server Explorer in Visual Studio.

image

Now you’re ready to see how things will work together.

First, we need to generate some application logs so we can view them later. Using the Azure Web Site with System.Diagnostics traces that we added at the beginning of this blog, each time we view//refresh the Default page in a browser, log will be generated and persisted in the Azure Table storage associated with the site.

View the Most Recent Application Logs in Azure Table

- Switch to the Logs tab of the site’s Settings window.

image

- The first time you open this Logs tab, you will see the spinning wheel indicating that it’s trying to retrieve the application logs in the Azure storage of the site. When the retrieval is complete, you will see the logs displayed in the table .

image

- You can change the time interval when the logs being stored in the Azure storage by change the dropdown selection

image

Also, if you want to view all the logs in the storage, click on the link on the upper right “View all application logs”, shown in the above picture. This will take you to the WAWSAppLogTable tab which lists all the loggings.

image

 

Note that by default, it will log only Application Errors traces of your site. To change the logging level, you need to go to the Configure tab of your site’s Portal UI

image 

b


Knockout IntelliSense Highlighting Bug Fix

$
0
0

We introduced Knockout IntelliSense in Visual Studio 2012 for web projects with KnockoutJS included, and fixed a few bugs in VS Update 1 and 2. However, one bug was not fixed in VS Update 2 and is still frequently reported: the highlighting region can shift around as the page is edited:

KOBug

This bug was fixed and release in Web Tools Extension 1.3. However, the shipping vehicle for WTE 1.3 was more limited than we anticipated at the time, and this component is not a part of VS Update 3 for Visual Studio 2012.

To obtain this fix, please install Windows Azure SDK for .NET 2.0 by following these steps:

1. Close Visual Studio 2012.

2. Run Web Platform Installer.

3. In the search box in the upper right corner, enter “azure vs 2.0” and press Enter.

4. Click “Add” by the “windows Azure SDK for .NET 2.0” entry. Make sure the name is an exact match, there are sub-components with similar names which will not install the fix:

AzureSDK20

5. Click the Install button at the lower right corner and follow the installation instructions.

We apologize for the inconvenience, but we hope this fix substantially improves your Knockout IntelliSense experience. Please let us know if you experience any additional problems.

ASP.NET updates to support Windows Azure Active Directory

$
0
0

Today we released an update to the Visual Studio 2013 Preview which enables you to create ASP.NET applications which use Windows Azure Active Directory for authentication.

In this post I will describe; how you can get the additional support, where to find more info and a list of known issues.

How to get the latest support

In order to try out the latest support you will need to first download and install Visual Studio 2013 Preview. After installing this to get the latest features for Windows Azure AD (WAAD) you will need to install ASP.NET and Web Tools Preview Refresh (Supports English version of VS2013 Preview only).

More info on these features

We have created some formal docs which describe the New Web Project dialog at http://asp.net/vnext/overview/latest/creating-web-projects-in-visual-studio. You can read more about the WAAD features under the Organizational account authentication options section. In that walk through we cover the following scenarios.

You can also take a look at Vittorio’s blog post Easy Web App Integration with Windows Azure Active Directory, ASP.NET & Visual Studio for some additional information regarding the Multi-tenant/organization support.

 

With this release we are interested in receiving feedback on the Cloud Single and Multi Organization scenarios. If you are a WAAD customer who is interested in using WAAD for Single Sign On with your web applications we’d love to hear from you. You can either leave your comments below or email me directly at sayedha@microsoft.com. Now to the known issues.

 

Known Issues

Below you’ll find a list of known issues with the WAAD support which is contained in the ASP.NET and Web Tools Preview Refresh (Supports English version of VS2013 Preview only).

Registering a new organization with a multi-tenant application may not work in some cases

For a multi-tenant application when registering a new tenant, you may receive the error below.

An error occurred while processing your request.

HTTP Error Code:
400

Message:
ACS90019: Unable to determine the tenant identifier from the request.

After receiving this error if you wait a few minutes and try again the process should complete successfully.

Error when navigating to a sub-app with out the trailing ‘/’

When publishing an ASP.NET project using WAAD you will receive the error below if you navigate to the app without the trailing slash on the URL. For example if you have a website at http://contoso.com and publish an application underneath, for example myapp4, you must navigate to the app with a URL that includes the trailing slash (http://contoso.com/myapp4/). Using the URL without the trailing slash (http://contoso.com/myapp4) results in the error below.

[FederationException: ID3206: A SignInResponse message may only redirect within the current web application: '/myapp4' is not allowed.] System.IdentityModel.Services.WSFederationAuthenticationModule.SignInWithResponseMessage(HttpRequestBase request) +74833 System.IdentityModel.Services.WSFederationAuthenticationModule.OnAuthenticateRequest(Object sender, EventArgs args) +364 System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +136 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +69

The workaround here is to always navigate to the application with a URL that includes the trailing slash.

Multi-tenant support does not work when publishing to a sub-app

For ASP.NET projects configured to use WAAD in the multi-tenant scenario you must publish the application to a website. Publishing to a sub-app is not currently supported.

On-Premises option not yet supported

In this release the On-Premises option can be found in the Configure Authentication dialog, but this is not yet supported. For this release you should avoid the On-Premises option. The underlying issue is code which is placed inside of the template. There are manual workarounds here. If you are interested in trying this out send me an email at sayedha@microsoft.com and I can walk you through the changes required.

Error during project create for Web Forms if MVC/Web API checkboxes are checked when using Org Auth

In this preview if you select to create a Web Forms project with Org Auth and you have checked the MVC or Web API you will receive an error like the following.

SNAGHTML1061fe89

In this build you should not select the MVC or Web API checkboxes when creating a Web Forms project with Org Auth.

 

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

Announcing release of ASP.NET and Web Tools for Visual Studio 2013 Preview and the refresh update

$
0
0

I’m excited to show the new features of the ASP.NET and Web Tools for Visual Studio 2013 Preview. I’m also announcing the release of ASP.NET and Web Tools Refresh for Visual Studio 2013 Preview. This refresh update is a free download for Visual Studio 2013 Preview, and contains a few bug fixes, updated templates and Scaffolding for both ASP.NET and Visual Studio.

Click here to download and install the Visual Studio 2013 Preview today. If you have the English version of VS2013 preview, you can also install the ASP.NET and Web Tools Refresh (Do not install this on non-English VS2013 Preview). Please check http://www.asp.net/vnext  for release notes, documentation and tutorials.

Visual Studio Web Tooling Enhancements

Browser Link – SignalR channel between browser and Visual Studio

A new feature Browser Link uses a SignalR channel between browsers and Visual Studio 2013 preview. It currently allows manually refreshing all connected browsers by clicking the toolbar refresh button. You can connect multiple browsers to your development site, including mobile emulators, and click refresh to refresh all the browsers all at the same time.

clip_image001

 

New HTML editor in VS2013 Preview

In VS2013 Preview, a new HTML editor is released for Razor files and web project HTML files. Webform files and Windows Store JavaScript application HTML files are still using the legacy editor for various reasons. The new HTML editor provides a single unified HTML5 based schema. It has some improvement such as automatic brace completion, jQuery UI and AngularJS attribute IntelliSense, attribute IntelliSense Grouping. The tools\options\Text Editors settings are different for legacy and new HTML editors, they are named “HTML (Razor)” (For Web projects HTML files and razor files) and “HTML” (Web Forms and pages in Windows 8 Modern JavaScript app) respectively.

 

ASP.NET Enhancements

One ASP.NET

We made a simple UI for creating projects that offer support for multiple ASP.NET frameworks (Web Forms, MVC, and Web API). New features are available for Web Forms that used to be offered only for MVC, such as automatic test project creation and an Intranet site template.

clip_image002

Different Authentication configurations can be chosen, which works the same in all ASP.NET frameworks and in web hosting software other than IIS.

clip_image003

One ASP.NET projects now uses Bootstrap to provide responsive design and theming capabilities.

OWIN integrated pipeline and Katana

ASP.NET authentication is now based on OWIN middleware that can be used on any OWIN-based host. For example, you can see all the OWIN packages we included when creating a SPA template project:

clip_image004

Katana added an HttpListener-based server, a self-host API and OwinHost executable for running OWIN applications without having to create a custom host. It also added a rich set of middleware components for authentication as shown before, including social authentication, local authentication, Enterprise and protocol general authentication, Microsoft Account, Windows Azure Directory Services, OpenID and OAuth 2.0. For more information see An Overview of Project Katana.

 

ASP.NET Identity

ASP.NET now supports claims-based authentication, where user’s identity is represented as a set of claims from a trusted issuer. As you can see in previous screen shot of “Configure Authentication” dialog, user can be authenticated through username and password, social services, or using organizational accounts.

You can now authorize requests from client applications to your Web APIs using OAuth2 2.0 bearer tokens. A good example with social network is the new SPA project.

clip_image005

For more information see Create an ASP.NET MVC 5 App with Facebook and Google OAuth2 and OpenID Sign-on.

ASP.NET MVC 5

MVC projects are now standard Web Applications and do not use their own project GUID. A MVC5 project is created if MVC checkbox is checked in One ASP.NET new project dialog. For more information see Getting Started with ASP.NET MVC 5.

ASP.NET Web API 2

For ASP.NET Web API 2 features, please visit here.

Scaffolding

VS 2013 Preview has completely rewritten MVC and WebForms Scaffolding. Please visit here for more information.

ASP.NET SignalR

SignalR 2.00-Beta1 is included with VS2013 Preview. Please update the package to SignalR 2.00-Beta2. It includes support for MonoTouch and MonoDroid, portable .NET client, a self-hosting package Microsoft.AspNet.SignalR.SelfHost, and is backwards compatible for servers. For more SignalR Release Notes information, please see: https://github.com/SignalR/SignalR/blob/master/ReleaseNotes.md

Entity Framework

Entity Framework 6.0.0-beta1 is included with VS2013 Preview. Please see http://entityframework.codeplex.com/wikipage?title=specs for the full spec.

Summary

Today’s Visual Studio 2013 preview and ASP.NET and Web Tooling Preview Refresh have a lot of useful features for developers using ASP.NET. Read the release notes to learn even more, and install it today!

HTML Editing Features in Visual Studio 2013 Preview

$
0
0

The Preview Release of Visual Studio 2013 contains a surprising addition: a brand new HTML editor! In fact, VS 2013 contains two HTML editors. The story’s a little complicated, so this article will do its best to simplify the matter.

Visual Studio 2012 included a brand new CSS editor, implemented entirely in managed code and highly extensible through MEF. This allowed the development of the Web Essentials extension, which greatly extended the feature set of CSS but which is rev’ed independently in a rapid cadence. Unfortunately, the HTML editor’s architecture remained dated and could not be extended without re-shipping existing product components.

In Visual Studio 2013 we introduce the first step in remedying this situation. The HTML editor used by Razor files (.cshtml and .vbhtml) as well as normal HTML files has been replaced with entirely new code. Web Forms (.aspx and .ascx) involve significantly more complexity and did not fit into a well-polished release for Visual Studio 2013, so they will be updated in an upcoming product release. In addition, for the Preview Release, HTML files in Windows Web Applications (modern apps written in HTML and JavaScript) use the legacy HTML editor.

The main emphasis for the Preview Release of the modern HTML editor has been feature and performance parity, but there are some notable improvements as well. New features already evident in the new editor include:

A single, unified and improved HTML schema

Instead of choosing from a list of schemas, HTML IntelliSense has been unified into a single schema that makes sense; focused on real-world, HTML5-centric usage rather than specs which were never fully implemented. Additions include attributes for jQuery UI and AngularJS.

Automatic brace completion and type-through

Similar to C# with Power Tools, when you type opening quotes, parenthesis or brackets, the matching closing character is inserted ahead of the cursor. If you type that character you “type through” the highlighted matching character. This makes typing faster and more convenient and your fingers stay in home position much more of the time. The experience is consistent across code, markup, styles and script.

clip_image001

IntelliSense item grouping

Visual Studio 2012 introduced aria attributes, which unfortunately filled half the IntelliSense completion list. In Visual Studio 2013 groups of attributes are collapsed into “…” groups, which are expanded when selected or typed:

clip_image002

Improved Smart Indent and formatting

Smart Indent (automatically indenting items as you type) has been made smarter, and formatting has been made simpler, so your document turns out the way you want it to look. Format Document is now a safe operation, and Smart Indent and Format Document work together with high fidelity. You’ll have to use the editor to appreciate this, but it provides a much better “feel.” Formatting has improved enough that we’ve turned on “format on paste” by default in the HTML editor for the first time.

Advanced settings

Under Tools\Options\Text Editors\HTML (Razor) there’s a new Advanced Settings pane which is clean, tabular, and extensible. Settings have been simplified to those that customers actually use, and additional settings can easily be added through extensions similar to Web Essentials.

Note, however, that there are now two sets of HTML settings. “HTML (Razor)” applies to the modern editor, and “HTML” applies to Web Forms and pages in Windows 8 Modern JavaScript app:

clip_image003

If the nomenclature is confusing, the simplest way to select the correct settings is to right click in HTML file you’re working on and select “Formatting and Validation…”. This will always take you to the correct settings group:

clip_image004

Better Razor experience

When you open your first Razor page, colorization is nearly instant instead of taking many seconds as it did in Visual Studio 2012. We’ve made a few improvements in formatting and Smart Indent already, and many more are in the works for RTM.

Existing features that did not make it into the preview build are:

CSS Class IntelliSense

When you add a class attribute to an HTML element, previous versions of Visual Studio would provide IntelliSense completion for all classes available. As long as you were not using the Code Only profile, or Windows Express, or Bundling and Minification, or MVC. We are rewriting this feature to be faster, more accurate, and always available. However, this is not available in the Preview release. Stay tuned.

Knockout IntelliSense

Knockout IntelliSense is in current development builds of Visual Studio 2013, but just missed being ported to the Preview branch. Effort went into fixing bugs and improving performance for the Preview Release instead.

Feedback

We are vitally interested in your feedback on the new HTML editor. Please comment here, post bugs to Connect, and make requests and suggestions via User Voice. It will be helpful if you identify editor bugs as modern or legacy editor issues. The modern editor is easy to identify by typing “<p aria”. If there’s a compact entry followed by “…” it’s the modern editor, if there’s a long list of aria- entries it’s the legacy editor. Let us know what you think; we want to make Visual Studio your favorite HTML editor.

Adding External Logins to your ASP.NET application in Visual Studio 2013

$
0
0

The project templates showcase a way of logging in with external login providers, along with the normal way of logging in by creating a local account

This post highlights how you can turn on support for logging through these services in the ASP.NET project templates that shipped with Visual Studio 2013 Preview. To learn more about how authentication via external providers works, please read the following article. http://www.asp.net/web-api/overview/security/external-authentication-services#USING

Enable OAuth login using Facebook, Twitter

Steps to get keys for Facebook

  • Go to the Facebook developers site (log in if you're not already logged in).
  • Choose the Create New App button, and then follow the prompts to name and create the new application.
  • In the section Select how your app will integrate with Facebook, choose the Website section.
  • Fill in the Site URL field with the URL of your site (for example, http://www.example.com). The Domain field is optional; you can use this to provide authentication for an entire domain (such as example.com).
    Note   If you are running a site on your local computer with a URL like http://localhost:12345 (where the number is a local port number), you can add this value to the Site URL field for testing your site. However, any time the port number of your local site changes, you will need to update the Site URL field of your application.
  • Choose the Save Changes button.
  • Choose the Apps tab again, and then view the start page for your application.
  • Copy the App ID and App Secret values for your application and paste them into a temporary text file. You will pass these values to the Facebook provider in your website code.
  • Exit the Facebook developer site.

Steps to get keys for Twitter

  • Browse to the Twitter developers site.
  • Choose the Create an App link and then log into the site.
  • On the Create an Application form, fill in the Name and Description fields.
  • In the WebSite field, enter the URL of your site (for example, http://www.example.com).
    Note   If you're testing your site locally (using a URL like http://localhost:12345), Twitter might not accept the URL. However, you might be able to use the local loopback IP address (for example http://127.0.0.1:12345). This simplifies the process of testing your application locally. However, every time the port number of your local site changes, you'll need to update the WebSite field of your application.
  • In the Callback URL field, enter a URL for the page in your website that you want users to return to after logging into Twitter. For example, to send users to the home page of the Starter Site (which will recognize their logged-in status), enter the same URL that you entered in the WebSite field.
  • Accept the terms and choose the Create your Twitter application button.
  • On the My Applications landing page, choose the application you created.
  • On the Details tab, scroll to the bottom and choose the Create My Access Token button.
  • On the Details tab, copy the Consumer Key and Consumer Secret values for your application and paste them into a temporary text file. You'll pass these values to the Twitter provider in your website code.
  • Exit the Twitter site.

Steps to enable OAuth/OpenID support in

    • Create a new ASP.NET Application
    • Goto App_Start\Startup.Auth.cs and uncomment the following lines of code
//app.UseTwitterAuthentication( // consumerKey: "", // consumerSecret: ""); 
//app.UseFacebookAuthentication( // appId: "", // appSecret: "");
//app.UseGoogleAuthentication();
Have fun integrating this into your application!!!

Introducing ASP.NET Identity – A membership system for ASP.NET applications

$
0
0

ASP.NET Identity is the new membership system for building ASP.NET web applications. ASP.NET Identity allows you to add login features to your application and makes it easy to customize data about the logged in user.

Features

Following are some of the feature of the ASP.NET Identity system

  • One ASP.NET Identity system
    • ASP.NET Identity can be used with all of the ASP.NET frameworks such as ASP.NET MVC, Web Forms, Web Pages, Web API and SignalR
  • Ease of plugging in profile data about the user
    • When you create new users in your application, it is now easy to add extra information about the user. For eg.. if you wanted to add a Birthdate option for users when they Register an account in your application.
    • ASP.NET Identity uses Entity Framework Code First and it is possible to extend the POCO classes.
  • Persistence control
    • By default the ASP.NET Identity system will store all the user information in a database. ASP.NET Identity uses Entity Framework Code First to implement all of its persistence mechanism.
    • If your application requirements are that this information might be stored in a different storage mechanism such as SharePoint, Azure Table Service, No Sql databases etc. it is now possible to plug in different storage providers.
  • Unit testability
    • ASP.NET Identity makes the web application more unit testable. You can write Unit Tests for the parts of your application that use ASP.NET Identity
  • Simple Role provider
    • There is a Simple Role providers which lets you restrict access to parts of your application by Roles. You can easily create Roles such as “Admin” and add Users to Roles.
  • Claims Based
    • ASP.NET Identity supports claims-based authentication, where the user’s identity is represented as a set of claims. There is a Claims
  • External Logins 
    • You can easily add external logins such as Microsoft Account, Facebook, Twitter and Google to your application store the user specific data in your application using this system.
    • You can also add login functionality using Windows Azure Active Directory and store the user specific data in your application using this system.

How do I get it?

ASP.NET Identity is used by ASP.NET Web Forms, MVC and SPA templates in Visual Studio 2013. it is also available as Nuget packages on the Nuget gallery

  • Nuget packages
    • Microsoft.Aspnet.Identity.Core
      • This package contains the core interfaces of ASP.NET Identity.
      • core
    • Microsoft.Aspnet.Identity.EntityFramework
      • This package contains the implementation of ASP.NET Identity system which works with Entity Framework. This means that if you use this package then you can store information in a Sql Server database.
      • ef 
  • VS 2013 preview
    • The ASP.NET Web Forms, MVC and SPA templates have 1.0.0-alpha1 version of ASP.NET Identity
  • ASP.NET and Web Tools 2013 Preview Refresh (Supports English version of VS2013 Preview only)
    • The ASP.NET Web Forms, MVC and SPA templates have 1.0.0-beta1 version of ASP.NET Identity
    • You can download the Preview refresh by clicking the above link
    • Following are the notable changes from 1.0.0-alpha1 – 1.0.0-beta1
      • In these templates you no longer need IdentityConfig.cs
      • Lots of public APIs were changed for renames and refactoring of code.
      • Transactions support was added to the framework.

 

Sample to add profile data

The following video video(mark 55min) http://channel9.msdn.com/Events/TechEd/NorthAmerica/2013/DEV-B314#fbid=fEhPNbmXE9- gives you a sneak peak into the features.

You can download a sample from https://github.com/rustd/AspnetIdentitySample. This is based on the ASP.NET MVC template that shipped with ASP.NET and Web Tools 2013 Preview Refresh (Supports English version of VS2013 Preview only) Once you have this Preview Refresh installed you can do the same for ASP.NET Web Forms and SPA applications.

Please do stay tuned to this blog for upcoming posts where I will dive into the various other features in this system.

Browser Link feature in Visual Studio Preview 2013

$
0
0

Browser Link is just a channel between your Visual Studio IDE and any open browser. This will allow dynamic data exchange between your web application and Visual Studio.

This feature is enabled by default in Visual Studio 2013 Preview. When Browser Link is enabled we register an HTTPModule with ASP.NET, which will then inject a <script> reference to every page request from the server. It is this JavaScript that does the magic of connecting the browser to Visual Studio. For Preview, we have a feature called the “Refresh Linked Browsers” that makes use of this channel between browsers and IDE.

Because the browser-side code is all JavaScript, it should work on all browsers, without requiring any other browser plug-in. It also works on iPad/ iPhone emulators. The connection between the browser and Visual Studio uses SignalR, an ASP.NET technology for bi-directional communication over HTTP. When Browser link is enabled, Visual Studio acts as a SignalR server, to which multiple clients (the browsers) can connect.

 image

Let me try to walk you through the feature with a few questions:

1. What does the Browser Link feature look like?

As mentioned earlier, “Refresh Linked Browser” is the only feature that we have for Preview. This shows up with a little Refresh icon image  in your toolbar next to debug drop down .

This feature becomes active as soon as you navigate to a page in your current project. You could do F5, Ctrl+F5, “View in Browser” or open any browser and paste your requested url to get this started.

In the image below you can see that:

1.  “Refresh Linked Browsers” is active as you may have browsers opened at this point.

2.  Brower Link feature is ON by default.

3.  “Refresh Linked Browsers” has a keyboard shortcut (Ctrl+Alt+Enter).

  image

2. How will I know which browsers are connected to VS?

Once you navigate to your page using various browsers, they will be listed in a tooltip as you hover over the Refresh icon image

The tooltip will look like the image below. Note that the tooltip shows how many browsers are connected. It also lists the connections with their respective urls.

image

If there are no browsers open for the project currently open in Visual studio, the tool tip will look like the image below. At this point you can do a View in Browser of a page to start the connection.

image

 3. How does “Refresh Linked Browsers” work?

Let us assume that you want to quickly see how “Default.aspx” renders in various browsers.

Start off with launching “Browse with” and select multiple browsers(IE, Firefox, Chrome etc). At this point, VS will show you that there are 3 browsers connected.

Make an edit to Default.aspx  file . Change text in <h1> ASP.net </h1> to ASP.NET 4.5. Now click on the refresh button or do Ctrl+Alt+Enter to save and refresh the page. This will update all the browsers at once. Note that, this will only refresh the browser. It will not navigate to the page for you.

image

4. How do I know if Browser Link is turned ON?

Go to “View Source” of your rendered page and you will see a script tag at the very bottom. See image below. The presence of this script indicated that Browser Link feature is enabled.

image

4. How do I turn off Browser Link?

You can uncheck “Enable Browser Link” and it will be turned off “ Browser Link” for all future requests made.

image

You can also use the following appsettings in your web.config file.

1. Set appSetting “vs:EnableBrowserLink” to “false ““. This will  disable Browser Link.

image

2. Set debug= false in web.config file. This will  also disable Browser Link. Note that debug= true is required for Browser Link feature to work.

image

5. What is coming up for RTM?

For RTM we will have Browser Link available as an extensible API for users to write extensions that can talk to various browsers and VS. Stay tuned and we will be posting details of this soon.

 Known Browser Link issues for Preview:

1. The Browser Link script tag is injected after the body tag. This will be moved inside the body tag for the next release.

2. “Refresh Linked Browsers” will not work for HTML pages. This can be fixed by enabling  Run All Managed Modules in  your web.config settings.

image

3. Browser Link does not work for sites that aren’t hosted on localhost.

4. We do not work on default Website Templates. This is because  debug flag is set to false in web.config. You will have to set the debug flag to true for Browser Link to start working.

 

Thanks,

Reshmi Mangalore


Make VS2012 MVC4 VSIX template to work for Visual Studio 2013 preview

$
0
0

Visual Studio 2012.2 supports customized MVC4 template, you can get a walkthrough here: http://blogs.msdn.com/b/yjhong/archive/2012/12/13/custom-mvc-4-template-walkthrough.aspx . But the created template VSIX file cannot be uploaded to VS Gallery at the time. Starting 6/26/2013, you can upload the MVC4 template VSIX files to VS Gallery now.

The VS2012.2 created VSIX may not install or work for Visual Studio 2013 preview, however. We need to fix a few thing in the following steps.

1. Change source.extension.vsixmanifest file InstallationTarget version from “11.0” to “[11.0,12.0]” in order to support both VS2012 and VS2013 preview, for example:

<Installation AllUsers="true">

<InstallationTarget Version="[11.0,12.0]" Id="Microsoft.VisualStudio.Pro" />

<InstallationTarget Version="[11.0,12.0]" Id="Microsoft.VisualStudio.VWDExpress" />

</Installation>

In Visual Studio 2012 spec, it mentioned Version=”11.0” means VS2012 and all future VS releases. But in Visual Studio 2013 preview, this is changed to mean that version of VS only. Changing it to “[11.0,]” to support VS2012 and all VS release in the future. Changing it to [11.0,12.0] to support both VS2012 and VS2013. Changing it to “12.0” to support VS2013 only.

2. In your vstemplate file, if you have such field specified to reduce the VSIX size and allow VSIX to use packages installed locally with VS2012.2 installations:

<packages repository="registry" keyName="AspNetMvc4VS11" isPreunzipped="true">

<package id="xxxxx" version="x.x.x" skipAssemblyReferences="true" />
...

</packages>

You will need to change the keyName value to “AspNetMvc4VS12” to support machines that has Visual Studio 2012 preview but does not have Visual Studio 2012 installed. This is because registry value name changed from “AspNetMvc4VS11” to “AspNetMvc4VS12” in HKLM\Software\NuGet\Repository. If you do this way, you will have to create two versions of VSIX, one for VS2012 and one for VS2013 preview.

If you still want to use one VSIX to support both VS2012.2 and VS2013 preview, you will need to include all the packages in the VSIX file and do not depend on the different package versions that installed along with each version of Visual Studio.

Now, you should be able to create the template successfully in VS2013 preview by going through “Web -> Visual Studio 2012 -> ASP.NET MVC 4 Web Application”.

Please test your VSIX file with Visual Studio 2013 preview and make changes if needed.

Thank you for your support.

Fix SPA VB project creating issue for ASP.NET and Web Tools Preview Refresh for Visual Studio 2013 Preview

$
0
0

Issue

Unfortunately after installing ASP.NET and Web Tools Preview Refresh for Visual Studio 2013 Preview, creating SPA VB template will fail.

SPAIssue

This post describes how to fix this issue.

Option 1: Fix script

I authored these two scripts (one for x86 and x64) to fix the issue.

Download here

Note:

  1. Please ensure your execution policy is correct. (Run command: Set-ExecutionPolicy RemoteSigned)
  2. Please run the script under Administration Privilege

Option 2: Manually fix

If for some reason you can’t run the scripts, you can fix the issue by altering template files.

  • Find your WebTemplates folder. It is usually at C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\WebTemplates
  • Go to WebTemplates\MVC\VisualBasic
  • If you’re using English version of VS, go to folder 1033. Otherwise you will see a number-named folder older than 1033, go to it.
  • Move following files:
    FromTo
    Spav5.0\Content\VB\*.cssSpav5.0\Content\
    Spav5.0\Scripts\app\VB\*.jsSpav5.0\Scripts\app\
    Spav5.0\Scripts\VB\*.jsSpav5.0\Scripts\
    Spav5.0\Views\VB\web.configSpav5.0\Views\
    Spav5.0\VB\web.configSpav5.0\
  • Then edit Spav5.0\spa.vbhtml.vstemplate. Remove all occurrences of “VB\”

 

Manage CORS policy dynamically

$
0
0

Brief

We introduced CORS support in ASP.NET Web API a few months ago. Out of the box it supports configuring CORS policy by attributes. It is a very intuitive and powerful way but lacks flexibility at runtime. Imaging your service allows a 3rd party to consume your service. You need the capability of updating the allowing origins list without compiling and deploying your service each time the list changes.

In following this article, I show you two examples of dynamically managing your CORS policy.

  1. Manage your CORS allowed origins in a SQL database.
  2. Manage your CORS allowed origins in the web.config file.

Prerequisites

  1. Visual Studio Express 2013 Preview for Web or Visual Studio 2013 Preview.
  2. QUnit.
  3. Bootstrap (optional)

Set up the test environment

CORS Service

Create a WebAPI project. It comes with a default ValuesController. Mark the controller with EnableCors attribute:

   1:      [EnableCors("*", "*", "*")]
   2:  publicclass ValuesController : ApiController
   3:      {
   4:  // GET api/values
   5:  public IEnumerable<string> Get()
   6:          {
   7:  returnnewstring[] { "value1", "value2" };
   8:          }
   9:   
  10:  // GET api/values/5
  11:  publicstring Get(int id)
  12:          {
  13:  return"value";
  14:          }
  15:   
  16:  // POST api/values
  17:  publicvoid Post([FromBody]stringvalue)
  18:          {
  19:          }
  20:   
  21:  // PUT api/values/5
  22:  publicvoid Put(int id, [FromBody]stringvalue)
  23:          {
  24:          }
  25:   
  26:          [DisableCors]
  27:  // DELETE api/values/5
  28:  publicvoid Delete(int id)
  29:          {
  30:          }
  31:      }

Add following line to the App_Start\WebApiConfig.cs file to enable CORS.

   1:  config.EnableCors();

Now your CORS service is set up.

Test client

The client code can’t stay in the same service as CORS service since it requires two services hosted at different origins so the CORS mechanism will kick in.

CORS is also affected by the choice of browsers[i]. So the tests need to be run in browser. Therefore I write the test in QUnit[ii].

Create an empty ASP.NET project. Adding following files:

\Index.html

   1:  <!DOCTYPEhtml>
   2:  <htmlxmlns="http://www.w3.org/1999/xhtml">
   3:  <head>
   4:  <title>CORS Test</title>
   5:  <linkhref="Content/bootstrap.css"rel="stylesheet"/>
   6:  </head>
   7:  <body>
   8:  <divclass="container">
   9:  <h1>CORS Test Client</h1>
  10:  <p>Input the url to the CORS service in following form.</p>
  11:  <formaction="Test.html"method="get"class="form-inline">
  12:  <inputtype="text"name="url"class="input-xxlarge"/>
  13:  <inputtype="submit"name="submit"class="btn"/>
  14:  </form>
  15:  </div>
  16:  </body>
  17:  </html>

\Test.html

   1:  <!DOCTYPEhtml>
   2:  <htmlxmlns="http://www.w3.org/1999/xhtml">
   3:  <head>
   4:  <title>CORS Test</title>
   5:  <linkhref="Content/qunit.css"rel="stylesheet"/>
   6:  </head>
   7:  <body>
   8:  <divid="qunit"></div>
   9:  <divid="qunit-fixture"></div>
  10:  <scriptsrc="Scripts/jquery-2.0.2.js"></script>
  11:  <script src="Scripts/qunit.js"></script>
  12:  <script src="Scripts/test.js"></script>
  13:  </body>
  14:  </html>

\Scripts\test.js

   1:  function getParameterByName(name) {
   2:      name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
   3:  var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
   4:          results = regex.exec(location.search);
   5:  return results == null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
   6:  }
   7:   
   8:  test("Cross domain get request", function () {
   9:  var testUrl = getParameterByName("url");
  10:   
  11:  var xhr = new XMLHttpRequest();
  12:      xhr.open("GET", testUrl + "/api/Values", false);
  13:      xhr.send();
  14:   
  15:  var retval = JSON.parse(xhr.responseText);
  16:   
  17:      equal(2, retval.length);
  18:      equal("value1", retval[0]);
  19:      equal("value2", retval[1]);
  20:  });

Notes:

  1. The project requires QUnit.js and QUnit.css. It also includes Bootstrap. Bootstrap is optional.
  2. Index.html is the front page. It accepts a URL to which this test client will sent CORS request to.
  3. Test.html contains QUnit test fixture.
  4. Test.js contains the test case and a utility function to get parameter from query string.

What now?

Now you have both CORS service and test client. Host them separately in IIS Express or Azure:

clip_image001

clip_image002

Visit the test client and input the CORS service URL:

clip_image004

The page will navigate to the test page once you submit the URL:

clip_image006

Notice the test passes since the CORS service accepts request from all origins.

Manage your CORS allowed origin in database

The goal is to save the allowed origin list in database and make CORS components to visit the database at runtime. We will introduce a data model, CRUD views to manage the database and a new CORS attribute to mark your endpoints.

The advantage of using database is that it’s powerful. You can change the policy at runtime without restart the service. The downside is that database is sometime overkill especially when your service is too simple to add a database.

Create management page

Model

I used Entity Framework for the database. First, let’s create the simplest model:

   1:  publicclass AllowOrigin
   2:      {
   3:  publicint Id { get; set; }
   4:   
   5:  publicstring Name { get; set; }
   6:   
   7:  publicstring Origin { get; set; }
   8:      }
  • Id is the key for database index;
  • Name is used to categorize the origin. Multiple origins can have the same name so as to apply them to a specified endpoint;
  • Origin is the allowed URL origin.

Create Controller and Views by scaffolding

Now, let’s use the powerful ASP.NET scaffolding to create controller and views for managing allowed origin list.

clip_image008

Let’s add a MVC 5 Controller with read/write actions and views, using Entity Framework.

clip_image009

Once views and controller are created let’s update the _Layout.cshtml file by adding a link to the navigation bar:

   1:  <div class="nav-collapse collapse">
   2:  <ul class="nav">
   3:  <li>@Html.ActionLink("Home", "Index", "Home", new { area = "" }, null)</li>
   4:  <li>@Html.ActionLink("API", "Index", "Help", new { area = "" }, null)</li>
   5:  <li>@Html.ActionLink("CORS Admin", "Index", "CorsAdminOrigin")</li>
   6:  </ul>
   7:  </div>

Now the CORS origin management page is ready to go:
clip_image011

Extend CORS to read allow origin from database

We will take advantage of one CORS extension point to accomplish our goal:

ICorsPolicyProvider

Instances that implement this interface will create a CORS policy based on a given http request. A CORS policy is a rule deciding how the CORS engine will process the CORS request

   1:  namespace System.Web.Http.Cors
   2:  {
   3:  /// <summary>
   4:  /// Provides an abstraction for getting the <see cref="CorsPolicy"/>.
   5:  /// </summary>
   6:  publicinterface ICorsPolicyProvider
   7:      {
   8:  /// <summary>
   9:  /// Gets the <see cref="CorsPolicy"/>.
  10:  /// </summary>
  11:  /// <param name="request">The request.</param>
  12:  /// <param name="cancellationToken">The cancellation token.</param>
  13:  /// <returns>The <see cref="CorsPolicy"/>.</returns>
  14:          Task<CorsPolicy> GetCorsPolicyAsync(HttpRequestMessage request, CancellationToken cancellationToken);
  15:      }
  16:  }

Out of box EnableCorsAttribute implements ICorsPolicyProvider. It turns all of your settings in the CORS attribute to CORS policy.

AllowCors

We won’t use the EnableCors attribute. Instead we create a new attribute:

   1:  publicclass AllowCorsAttribute : Attribute, ICorsPolicyProvider
   2:  {
   3:  privatestring _configName;
   4:   
   5:  public AllowCorsAttribute(string name = null)
   6:      {
   7:          _configName = name ?? "Default";
   8:      }
   9:   
  10:  publicstring ConfigName
  11:      {
  12:          get { return _configName; }
  13:      }
  14:   
  15:  public Task<CorsPolicy> GetCorsPolicyAsync(
  16:          HttpRequestMessage request,
  17:          CancellationToken cancellationToken)
  18:      {
  19:  using (var db = new CorsContext())
  20:          {
  21:              var origins = db.AllowOrigins.Where(o => o.Name == ConfigName).ToArray();
  22:   
  23:              var retval = new CorsPolicy();
  24:              retval.AllowAnyHeader = true;
  25:              retval.AllowAnyMethod = true;
  26:              retval.AllowAnyOrigin = false;
  27:   
  28:  foreach (var each in origins)
  29:              {
  30:                  retval.Origins.Add(each.Origin);
  31:              }
  32:   
  33:  return Task.FromResult(retval);
  34:          }
  35:      }
  36:  }

AllowCors attribute derives from System.Attribute and implement ICorsPolicyProvider, therefore it will be picked up by AttributeBasedPolicyProviderFactory. However it accepts only one parameter for its name. The rest of the settings of the policy are read from the database.

In this sample, it only loads allowed origin from database. It is for the sake of simplicity. In a real scenario all settings can be saved in database.

How does it work

Attributes your ValuesController

Replace the EnableCors attribute with AllowCors attribute for ValuesController:

   1:  [AllowCors("Values")]
   2:  publicclass ValuesController : ApiController
   3:  {

Notice I gave a name “Values” for this scope.

A negative test

Now open both test client and the CORS service (remember to redeploy your services) Run your test client you will notice that the tests failed:

clip_image013

The error reads:

SEC7120: Origin http://corstestclient.azurewebsites.net not found in Access-Control-Allow-Origin header.
Test.html

This is expected since test client is not on the allowed list.

Add allowed origin

So go to the CORS service and add test client to allowed list. Remember the name of the CORS policy to apply is “Values”.

clip_image014

Rerun your test client. Now it passes!

Manage your CORS allowed origin in web.config

The goal of this sample is to show you how to manage CORS setting in web.config.

There are multiple benefits to use web.config. First, it doesn’t need recompile and fully redeployed. Second, it’s so simple that you just need a notepad to update the configuration. Last, if you’re using Azure web site, the portal allow you update the settings on the flight.

There a few downside of web.config. It requires service to be started to change the policy. And it doesn’t fit the situation you need configure endpoints differently.

Adding settings in web.config

   1:  <appSettings>
   2:  <addkey="webpages:Version"value="3.0.0.0"/>
   3:  <addkey="webpages:Enabled"value="false"/>
   4:  <addkey="PreserveLoginUrl"value="true"/>
   5:  <addkey="ClientValidationEnabled"value="true"/>
   6:  <addkey="UnobtrusiveJavaScriptEnabled"value="true"/>
   7:  <addkey="cors:allowOrigins"value="http://localhost:40861"/>

Extend CORS to read allow origin from web.config

This is quite straightforward if you have gone through the database sample first:

   1:  publicclass AllowCorsAttribute : Attribute, ICorsPolicyProvider
   2:  {
   3:  privateconststring keyCorsAllowOrigin = "cors:allowOrigins";
   4:   
   5:  private CorsPolicy _policy;
   6:   
   7:  public Task<CorsPolicy> GetCorsPolicyAsync(
   8:          HttpRequestMessage request, 
   9:          CancellationToken cancellationToken)
  10:      {
  11:  if (_policy == null)
  12:          {
  13:              var retval = new CorsPolicy();
  14:              retval.AllowAnyHeader = true;
  15:              retval.AllowAnyMethod = true;
  16:              retval.AllowAnyOrigin = false;
  17:   
  18:              var value = ConfigurationManager.AppSettings[keyCorsAllowOrigin];
  19:   
  20:  if (!string.IsNullOrEmpty(value))
  21:              {
  22:  foreach (var one in from v invalue.Split(';')
  23:  where !string.IsNullOrEmpty(v)
  24:                                      select v)
  25:                  {
  26:                      retval.Origins.Add(one);
  27:                  }
  28:              }
  29:   
  30:              _policy = retval;
  31:          }
  32:   
  33:  return Task.FromResult(_policy);
  34:      }
  35:  }

Note: You don’t need to reload policy for every request. Web.config doesn’t change during the life time of a service.

How it works

Put your client origin in the web.config and start the service. Run your test client. It just works.

clip_image015

Configure in Azure Web Site Portal

Here’s a powerful integration sample if you’re using Azure Web Sites to host your service. In the Azure Web Site portal you can configure your application settings:

clip_image017

Now you can change the allow list in browser.


[i]http://caniuse.com/cors

[ii]http://qunitjs.com/


Understanding OWIN Forms authentication in MVC 5

$
0
0

Overview

The new security feature design for MVC 5 is based on OWIN authentication middleware. The benefit for it is that security feature can be shared by other components that can be hosted on OWIN. Since the Katana team did a great effort to support the OWIN integrated pipeline in ASP.NET, it can also secure apps hosted on IIS, including ASP.NET MVC, Web API, Web Form.

Forms authentication uses an application ticket that represents user's identity and keeps it inside user agent's cookie. When user first accesses a resource requiring authorization, it will redirect user to login page. After the user provides credentials, your application code will validate the user name and password and build user claims including user's name, roles, etc. After passing claims to the Forms authentication middleware, it will convert it to an application ticket and serialize, encrypt and encode it into a ticket token. Then, send it out as a cookie. When the next time user sends request with the cookie, the middleware will validate it and convert the ticket token back to claims principal and save it in HttpContext.User, which will shared across ASP.NET pipeline.

ASP.NET also has a forms authentication support through the FormsAuthenticationModule, which, however, can only support applications hosted on ASP.NET and doesn't have claim support . Here is a rough feature comparison list:

Features

Asp.Net Forms Authentication

OWIN Forms Authentication

Cookie Authentication

Yes

Yes

Cookieless Authentication

Yes

No

Expiration

Yes

Yes

Sliding Expiration

Yes

Yes

Token Protection

Yes

Yes

Claims Support

No

Yes

Web Farm Support

Yes

Yes

Unauthorized Redirection

Yes

Yes

In this blog, you will learn:

· Creating an MVC project with OWIN Forms authentication enabled.

· Understanding OWIN Forms authentication options.

· Understanding Application Sign In Cookie flow.

· Understanding External Sign In Cookie flow.

· Working with new Identity API

Creating MVC project with OWIN Forms authentication enabled

To get started, you need to create new MVC .

· Make sure you have installed:

· In Visual Studio 2013, select New Project from File menu

· In New Project dialog, select Installed Template / Visual C# / Web / ASP.NET Web Application

· In New ASP.NET Project dialog, select MVC project template

clip_image002

Optional: On the right panel of the dialog, you can select Configure Authentication, to choose No Authentication, Individual User Accounts, Organization Authentication and Windows Authentication. In this tutorial, we use Individual User Accounts, which is the default setting.

clip_image004

· Click Create Project button

In the new project, open the App_Start/Startup.Auth.cs file. It has the following code:

Code Snippet
  1. publicpartialclassStartup
  2. {
  3.     // For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301864
  4.     publicvoid ConfigureAuth(IAppBuilder app)
  5.     {
  6.         // Enable the application to use a cookie to store information for the signed in user
  7.         // and to use a cookie to temporarily store information about a user logging in with a third party login provider
  8.         app.UseSignInCookies();
  9.  
  10.         // Uncomment the following lines to enable logging in with third party login providers
  11.         //app.UseMicrosoftAccountAuthentication(
  12.         //    clientId: "",
  13.         //    clientSecret: "");
  14.  
  15.         //app.UseTwitterAuthentication(
  16.         //   consumerKey: "",
  17.         //   consumerSecret: "");
  18.  
  19.         //app.UseFacebookAuthentication(
  20.         //   appId: "",
  21.         //   appSecret: "");
  22.  
  23.         //app.UseGoogleAuthentication();
  24.     }
  25. }

 

Note that UseSignInCookies must be called before any external login providers.

 

Understanding OWIN Forms authentication options

The UseSignInCookies extension method actually registers two cookie authentications. (You can see the source for the methods below at at: http://katanaproject.codeplex.com/SourceControl/latest#src/Microsoft.Owin.Security.Forms/FormsAuthenticationExtensions.cs )

Code Snippet
  1. publicstaticvoid UseSignInCookies(thisIAppBuilder app)
  2. {
  3.     app.UseApplicationSignInCookie();
  4.     app.UseExternalSignInCookie();
  5. }

Both the UseApplicationSignInCookie and the UseExternalSignInCookie extension methods call UseFormsAuthentication, but with different settings.

Code Snippet
  1. publicstaticIAppBuilder UseApplicationSignInCookie(thisIAppBuilder app)
  2. {
  3.     return UseFormsAuthentication(app, new FormsAuthenticationOptions
  4.     {
  5.         AuthenticationType = FormsAuthenticationDefaults.ApplicationAuthenticationType,
  6.         AuthenticationMode = AuthenticationMode.Active,
  7.         CookieName = FormsAuthenticationDefaults.CookiePrefix + FormsAuthenticationDefaults.ApplicationAuthenticationType,
  8.         LoginPath = FormsAuthenticationDefaults.LoginPath,
  9.         LogoutPath = FormsAuthenticationDefaults.LogoutPath,
  10.     });
  11. }
  12.  
  13. publicstaticIAppBuilder UseExternalSignInCookie(thisIAppBuilder app)
  14. {
  15.     app.SetDefaultSignInAsAuthenticationType(FormsAuthenticationDefaults.ExternalAuthenticationType);
  16.  
  17.     return UseFormsAuthentication(app, new FormsAuthenticationOptions
  18.     {
  19.         AuthenticationType = FormsAuthenticationDefaults.ExternalAuthenticationType,
  20.         AuthenticationMode = AuthenticationMode.Passive,
  21.         CookieName = FormsAuthenticationDefaults.CookiePrefix + FormsAuthenticationDefaults.ExternalAuthenticationType,
  22.         ExpireTimeSpan = TimeSpan.FromMinutes(5),
  23.     });
  24. }

The Application sign in cookie is used to authenticate users for the current application, while external sign in cookie is used to authenticate users from external providers, like Facebook, Google, Twitter and Microsoft account. If you want to change the default authentication options, you can use UseFormsAuthentication extension method to change them.

Here are list of options that you can change in UseFormsAuthentication:

Code Snippet
  1. app.UseFormsAuthentication(new FormsAuthenticationOptions()
  2. {
  3.     AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Active,
  4.     AuthenticationType = "MyApplication",
  5.     CookieDomain = ".myapp.com",
  6.     CookieHttpOnly = true,
  7.     CookieName = ".AspNet.MyApplication",
  8.     CookiePath = "/Account",
  9.     CookieSecure = CookieSecureOption.Always,
  10.     ExpireTimeSpan = TimeSpan.FromDays(1),
  11.     LoginPath = "/Account/Login",
  12.     ReturnUrlParameter = "return_url",
  13.     SlidingExpiration = true,
  14.     Provider = new FormsAuthenticationProvider()
  15.     {
  16.         OnResponseSignin = async ctx =>
  17.         {
  18.             Console.WriteLine("OnResponseSignin");
  19.             PrintClaimsIdentity(ctx.Identity);
  20.         },
  21.         OnValidateIdentity = async ctx =>
  22.         {
  23.             Console.WriteLine("OnValidateIdentity");
  24.             PrintClaimsIdentity(ctx.Identity);
  25.         }
  26.     }
  27. });

Options

Description

ApplicaitonSignInCookie Default Values

ExternalSignInCookie Default Values

AuthenticationMode

If Active the authentication middleware alters the requested user coming in and returns 401 Unauthorized responses going out.

If Passive the authentication middleware will only provide identity and alter responses when explicitly indicated by the AuthenticationType.

Active

Passive

AuthenticationType

The AuthenticationType in the options corresponds to the IIdentity.AuthenticationType property. A different value may be assigned in order to use the same authentication middleware type more than once in a pipeline.

“Application”

“External”

CookieDomain

Defines the domain that cookie is under

<null>

<null>

CookieHttpOnly

Defines if the cookie is http only. It's true by default.

True

True

CookieName

Defines the name of the cookie

“.AspNet.Application”

“.AspNet.External”

CookiePath

Defines the path that cookie is under. By default, it's /.

“/”

“/”

CookieSecure

Defines if the cookie will only be sent back to HTTPS URL. By default, it is SameAsRequest, which means If the URI that provides the cookie is HTTPS, then the cookie will only be returned to the server on subsequent HTTPS requests. Otherwise if the URI that provides the cookie is HTTP, then the cookie will be returned to the server on all HTTP and HTTPS requests.

SameAsRequest

SameAsRequest

ExpireTimeSpan

Defines the expiration of the cookie.

14 days

5 minutes

LoginPath

Defines the Login path when unauthorized request will be redirected to.

“/Account/Login”

<null>

ReturnUrlParameter

Defines the return URL parameter name, which tells your application the URL of previous unauthorized request to redirect to after login. Your application code is responsible for retrieving it and redirecting the user agent to the return URL

“ReturnUrl”

<null>

SlidingExpiration

Defines if the authentication supports sliding expiration, which will automatically extends the expiration time if user session is still active. By default, it's true.

True

False

Provider

The forms authentication provider that can intercept events during sign in and validate identity.

· OnResponseSignin: happens just before set-cookie is sent out

· OnValidateIdentity: happens just after incoming cookie is parsed into ClaimsIdentity

<null>

<null>

Understanding Application Sign in Cookie flow

Active mode is similar to what the old ASP.NET forms authentication module did, while passive is a way to let framework code control the authentication explicitly.

ApplicatinSignInCookie is an active forms authentication middleware, so when a valid cookie is returned, it will:

· Automatically redirect an unauthorized response to the login page.

· Set the logged in user principal to HttpContext.User, so the rest of ASP.NET pipeline will know what user is authenticated.

 

The following is a basic flow of application forms authentication.

User Agent

Forms Authentication Middleware(Application)

Web App

1. Get /Account/Manage

---------------------------->

  
  

2. Response Status: 401

AccountController is protected by Authroize attribute, so unauthorized request will return a 401 error.

[Authorize]

public class AccountController : Controller

{

}

<----------------------------

 

3. Alter response status to 302 and redirect to /Application/Login?ReturnUrl=/Account/Manage

The application sign in cookie is in active authentication mode and it will automatically redirect to login page when there is a 401 response.

<----------------------------

 

4. GET /Application/Login?ReturnUrl=/Account/Manage

---------------------------->

  
  

5. Response Status: 200 and with login page in body

<----------------------------

6. POST /Application/Login?ReturnUrl=/Account/Manage

User input user name and password and post back to server

---------------------------->

  
  

7. Status: 301

Location: /Account/Manage

Server code does:

a. Validating user credentials

b. Calling IdentityAuthenticationManager.SignIn to sign in with application sign in cookie

c. Redirecting to returnUrl

<----------------------------

 

8. Status: 302

Location: /Account/Manage

Set-Cookie: .AspNet.Application=<Ticket Token>

The middleware will convert user claims with extra data into ticket token and set it in cookie.

<----------------------------

 

9. GET /Account/Manage

Cookie: .AspNet.Application=<Ticket Token>

---------------------------->

  
 

10. Validate <Ticket Token> and convert it to claims identity and set it to HttpContext.User

---------------------------->

 
  

11. Status: 200 with manage account page in body

Authorize attribute sees that the identity is authenticated from HttpContext.User. So allow the request to reach the action.

<----------------------------

Understanding External Sign in Cookie flow

ExternalSignInCookie is a passive forms authentication, which is unobtrusive to your application if you don't explicitly ask it to do something. Your application code can explicitly ask it to provide the user identity or alter the response to set cookie or remove cookie. To demo external sign in cookie, you need to configure an external provider like Facebook. This flow chart starts from the point Facebook authentication middleware receives the user info from Facebook graph API. For the detailed flow for external provider sign in process, please check out Robert’s tutorial: External Authentication Services

User Agent

Forms Authentication Middleware(Application)

Forms Authentication Middleware(External)

Facebook Authentication Middleware

Web App

<After facebook returns authorization code back to your app>

1. GET /signin-facebook?code=<authorization code>&state=<state>

---------------------------->

    
   

2. Status: 302

Location: /Account/ExternalLoginCallback?loginProvider=Facebook

Middleware code does:

a. Get access token by authorization code from facebook

b. Get user graph data from facebook

c. Convert user graph data into claims identity

d. Sign in claims identity as external type

<----------------------------

 
  

3. Status: 302

Location: /Account/ExternalLoginCallback?loginProvider=Facebook

Set-Cookie: .AspNet.External=<ticket token>

External forms middleware does:

a. Convert claims identity to ApplicationTicket

b. Serialize ApplicationTicket to byte array

c. Encrypt and encode byte array to ticket token

d. Set cookie to response

<----------------------------

  

4. Get /Account/ExternalLoginCallback?loginProvider=Facebook

Cookie: .AspNet.External=<ticket token>

 

---------------------------->

    
    

5.IdentityAuthenticationManager.GetExternalIdentity()

The extension method will call into OWIN middleware to explicitly authenticate with external type

<----------------------------

  

6. Authenticate cookie and return user claims identity

External forms middleware does:

a. Decode and decrypt ticket token into byte array

b. Deserialize byte array to ApplicationTicket

c. Get claims identity from ApplicationTicket

d. Return identity back to caller

---------------------------->

  
    

7. Status: 200

Body: external login page

 

After getting the external identity, check if the user is already registered.

- If no, return external login confirmation page.

- If yes, directly log user in (Not included in this flow)

<----------------------------

8. POST /Account/ExternalLoginConfirmation

Cookie: .AspNet.External=<ticket token>

Body: UserName=test&LoginProvider=Facebook

---------------------------->

    
    

9. IdentityAuthenticationManager.GetExternalIdentity()

The extension method will call into OWIN middleware to explicitly authenticate with external type

<----------------------------

  

10. Authenticate cookie and return user claims identity

---------------------------->

  
    

11. Status: 302

Location: /

Web app code does:

a. Create local user via membership provider

b. Associate local user with external identity’s ID claim (facebook id)

c. Sign the external identity in as Application type

d. Redirect to returnUrl or home page

<----------------------------

 

12. Status: 302

Location: /

Set-Cookie: .AspNet.Application=<Ticket Token>

 

Turn claims identity to ticket token and set cookie in response

<----------------------------

   

Working with new Identity API

IdentityAuthenticationManager wraps everything that you need to work with Application and External sign in cookies.

Code Snippet
  1. publicclassIdentityAuthenticationManager
  2. {
  3.     public IdentityAuthenticationManager();
  4.     public IdentityAuthenticationManager(IdentityStoreManager storeManager);
  5.  
  6.     publicstring ClaimsIssuer { get; set; }
  7.     publicstring RoleClaimType { get; set; }
  8.     public IdentityStoreManager StoreManager { get; set; }
  9.     publicstring UserIdClaimType { get; set; }
  10.     publicstring UserNameClaimType { get; set; }
  11.  
  12.     publicvirtualvoid Challenge(HttpContextBase context, string authenticationType, string redirectUrl);
  13.     publicvirtual Task<bool> CheckPasswordAndSignIn(HttpContextBase context, string userName, string password, bool isPersistent);
  14.     publicvirtual Task<bool> CreateAndSignInExternalUser(HttpContextBase context, string loginProvider, IUser user);
  15.     publicvirtual IEnumerable<Microsoft.Owin.Security.AuthenticationDescription> GetExternalAuthenticationTypes(HttpContextBase context);
  16.     publicvirtual Task<ClaimsIdentity> GetExternalIdentity(HttpContextBase context);
  17.     publicvirtual Task<IList<Claim>> GetUserIdentityClaims(string userId, IEnumerable<Claim> claims);
  18.     publicvirtual Task<bool> LinkExternalIdentity(ClaimsIdentity id, string userId, string loginProvider);
  19.     publicvirtual Task SignIn(HttpContextBase context, string userId, bool isPersistent);
  20.     publicvirtual Task SignIn(HttpContextBase context, string userId, IEnumerable<Claim> claims, bool isPersistent);
  21.     publicvirtual Task<bool> SignInExternalIdentity(HttpContextBase context, ClaimsIdentity id, string loginProvider);
  22.     publicvirtualvoid SignOut(HttpContextBase context);
  23.     publicvirtualbool VerifyExternalIdentity(ClaimsIdentity id, string loginProvider);
  24. }

Method

Description

CheckPasswordAndSignIn

Verify user name and password against storage like SQL server and sign in with Application cookie

CreateAndSignInExternalUser

Create user based on external identity from External cookie in storage like SQL server, and sign in user as Application cookie

GetExternalIdentity

Get external identity from External cookie

GetUserIdentityClaims

Replace user id and name claims and add roles and user custom claims from storage.

LinkExternalIdentity

Link external identity with local user in storage

SignIn

Sign out External cookie and sign in Application cookie

SignInExternalIdentity

Get user associating with external identity in storage and sign this user in as Application cookie

SignOut

Sign out from Application cookie

VerifyExternalIdentity

Verify if the external identity has the same issuer as loginProvider

Challenge

Explicitly ask authentication middleware to send challenge to the response. For example, Application forms middleware will challenge to redirect to login page with 302 status code.

GetExternalAuthenticationTypes

Get supported external authentication types which you register in the OWIN middleware pipeline, like Facebook, Google, etc.

The following shows the login code for the ASP.NET MVC template:

Code Snippet
  1. [HttpPost]
  2. [AllowAnonymous]
  3. [ValidateAntiForgeryToken]
  4. publicasyncTask<ActionResult> Login(LoginViewModel model, string returnUrl)
  5. {
  6.     if (ModelState.IsValid)
  7.     {
  8.         // Validate the user password
  9.         if (await AuthenticationManager.CheckPasswordAndSignIn(HttpContext, model.UserName, model.Password, model.RememberMe))
  10.         {
  11.             return RedirectToLocal(returnUrl);
  12.         }
  13.     }
  14.  
  15.     // If we got this far, something failed, redisplay form
  16.     ModelState.AddModelError("", "The user name or password provided is incorrect.");
  17.     return View(model);
  18. }

Introducing $select and $expand support in Web API OData

$
0
0

Last week Microsoft released the preview of Visual Studio 2013, and along with it came the ASP.NET and Web Tools for Visual Studio 2013 Preview. In this new release, we are expanding the OData support in Web API to include support for $select and $expand, two of the most popular OData query operators. In this blog post we’ll cover the following topics:

  • What are $select and $expand.
  • How to use $select and $expand in an application.
  • Configuration options and formatter support for $select and $expand.

What are $select and $expand

The $select operator allows a client to pick a subset of the properties of an entity to be retrieved when querying a feed or a single entity. The $expand operator allows a client to retrieve related entities for a given navigation property in line with the entities being retrieved.

By using $select and $expand, we can make sure that we get the data we need in an optimal way.

For example, we could use $select to return only the Id and Name properties of an entity, and we could use $expand to retrieve a customer and its related Orders on a single query.

How to use $select and $expand in an application

Let’s see an example, we will start by retrieving only the Name property of a feed of customers. In order to do that, we need to do 3 things:

  • Create a model like the one in the following diagram:

image

  • Write a CustomersController that returns a feed of Customers or a specific Customer for a given key:
[ODataNullValue]publicclass CustomersController : ODataController
{
    ShoppingContext context;public CustomersController()
    {
        context = new ShoppingContext();
    }

    [Queryable(MaxExpansionDepth = 5)]
    public IQueryable<Customer> Get()
    {return context.Customers.AsQueryable();
    }

    [Queryable(MaxExpansionDepth = 5)]
    public SingleResult<Customer> Get(int key)
    {return SingleResult.Create(context.Customers.Where(c => c.Id == key));
    }
}
  • Setup the server and map the OData route as in the following code:
class Program
{staticvoid Main(string[] args)
    {string serviceUrl = "http://localhost:12345";using (WebApp.Start(serviceUrl, Configure))
        {
            Console.WriteLine("Server listening on {0}", serviceUrl);
            Console.ReadKey();
        }
    }privatestaticvoid Configure(IAppBuilder builder)
    {
        HttpConfiguration configuration = new HttpConfiguration();
        IEdmModel model = ShoppingEdmModel.GetModel();
        HttpServer server = new HttpServer(configuration);
        configuration.Routes.MapODataRoute("odata", "odata", model, new DefaultODataBatchHandler(server));

        builder.UseHttpMessageHandler(server);
    }
}

Once we have our server up and running, we only need to send the following request using fiddler in order to get just the Name property of the Customers feed.

GET http://localhost:12345/odata/Customers?$select=Name HTTP/1.1
Host: localhost:12345
accept: application/json

Here is the response that we get:

HTTP/1.1 200 OK
Content-Length: 415
Content-Type: application/json; charset=utf-8
Server: Microsoft-HTTPAPI/2.0
DataServiceVersion: 3.0
Date: Tue, 28 May 2013 23:58:17 GMT

{
  "odata.metadata":"http://localhost:12345/odata/$metadata#Customers","value":[
    {
      "Name":"Name 1"
    },{
      "Name":"Name 2"
    },{
      "Name":"Name 3"
    },{
      "Name":"Name 4"
    },{
      "Name":"Name 5"
    },{
      "Name":"Name 6"
    },{
      "Name":"Name 7"
    },{
      "Name":"Name 8"
    },{
      "Name":"Name 9"
    },{
      "Name":"Name 0"
    }
  ]
}

As we see on the response, we are still sending back a feed of customers, but we are only retuning their name, which allows us to improve the efficiency of our applications by reducing the amount of data returned from the database.

We can see this if we see the query that Entity Framework sends to the database when we query just for the Ids of the customers:

SELECT
[Extent1].[Id] AS [Id],
N'bf436648-6bf3-4bd2-9639-2810e0a91f53' AS [C1],
N'Id' AS [C2]
FROM [dbo].[Customers] AS [Extent1]

Aditionally, we can also apply $select when we are retrieving just a single entity. We could send the following request using fiddler:

GET http://localhost:12345/odata/Customers(5)?$select=Name HTTP/1.1
Host: localhost:12345
accept: application/json

As the following table shows, we get back a Customer, but we only get back its name property:

HTTP/1.1 200 OK
Content-Length: 100
Content-Type: application/json; charset=utf-8
Server: Microsoft-HTTPAPI/2.0
DataServiceVersion: 3.0
Date: Wed, 29 May 2013 00:01:21 GMT

{
  "odata.metadata":"http://localhost:12345/odata/$metadata#Customers/@Element","Name":"Name 5"
}

Here is a more complex example in which we use $select and $expand together:

GET http://localhost:18340/odata/Customers?$select=Id,Name,Orders/BillingAddress&$expand=Orders HTTP/1.1
accept: application/json
Host: localhost:18340

In the example above, we are selecting the Id, Name, and the Billing Address property of the related Orders of a Customer.

Here is the first entity of the associated response:

{
  "odata.metadata":"http://localhost:18340/odata/$metadata#Customers","value":[
    {
      "Orders":[
        {
          "BillingAddress":{
            "FirstLine":"FirstLine 1",
            "SecondLine":"SecondLine 1",
            "ZipCode":214,
            "City":"City 1",
            "Country":"Country 1"
          }
        },{
          "BillingAddress":{
          "FirstLine":"FirstLine 2",
          "SecondLine":"SecondLine 2",
         "ZipCode":20,
         "City":"City 2",
         "State":"State 2",
         "Country":"Country 2"
          }
        },{
          "BillingAddress":{
            "FirstLine":"FirstLine 3",
            "SecondLine":"SecondLine 3",
            "ZipCode":88,
            "City":"City 3",
            "State":"State 3",
            "Country":"Country 3"
          }
        }
      ], "Id":1,
         "Name":"Name 1"
    },
    ...
}

In order to apply a $select or $expand to a single entity, we can write our action method in two ways. If we just return an entity, like a customer and we apply the [Queryable] attribute on top of the action, $select and $expand will work, but the underlying query won’t be optimized. Here is an example on how to do it.

[Queryable]public Customer Get(int key)
{return context.Customers.Single(x => x.Id == key);
}

This is not a problem if we are using Linq to objects as our backend, but it might cause a performance issue if we are using Entity Framework as the backend, as if we perform an $expand operation and lazy loading is enabled, we will be triggering an extra query for each navigation property we are expanding.

In order to optimize queries to the backend when using $select and $expand, we can write a different version of this action that returns a special class, SingleResult, that allows the queryable attribute to access the query object, apply the $select and $expand operators, and that takes care of ensuring that only one entity is returned.

[Queryable]public SingleResult<Customer> Get(int key)
{return SingleResult.Create(context.Customers.Where(x => x.Id == key));
}

Configuration options and formatter support for $select and $expand

When dealing with a real application, we need a way to configure operators like $expand so that a client (by mistake or maliciously, can’t send an expensive query to the service). In the case of $expand, we can configure the depth of the expansions that we allow our clients to perform in their queries so that they don’t cause a denial of service on the database. In order to do this, we can set the MaxExpansionDepth property on the ODataQueryOptions object or in the Queryable attribute.

In this release of web API the OData formatter and the Json formatter support $select and $expand. An example of $select and $expand queries can be found at the ODataQueryableSample in the aspnet samples codeplex project, and this functionality is available with visual studio 2013 preview, on the official Nuget package feed or in the nightly build Nuget feed. For more information, please look at http://aspnetwebstack.codeplex.com

How does VS determine which version of Razor engine to use when editing razor webpage files

$
0
0

In VS2013 Preview, we released new Razor V3 runtime and design time Engine to support MVC5 and Razor V3 website’s runtime and design time behavior. Unlike Razor V2 runtime and design time, VS2013 did not GAC these binaries. Instead, the binaries are installed in the project bin folder when corresponding NuGet package is installed, and in “%ProgramFiles (x86)%\Microsoft Visual Studio 12.0\Common7\IDE\CommonExtensions\Microsoft\Web\Razor\v3.0” to support design time.

As in VS2012 to determine which razor v1/v2 design time dlls to load, VS 2013 preview first use web.config file key <add key="webpages:Version" value="x.0.0.0" /> to determine the design time dll version to load for editing webpages. For example, by default, MVC5 project contains <add key="webpages:Version" value="3.0.0.0" /> , VS will load Razor V3 dlls to edit the project’s webpage files (i.e. cshtml or vbhtml files) .

If the key is missing from web.config file such as default Razor V2/V3 website, VS will use bin directory’s razor dll version to determine the design time razor engine dll to load.

Since Razor v1 is no longer ships with VS2013 preview, if a single webpage file (i.e. cshtml or vbhtml files) is opened without bin directory nor web.config setting, VS 2013 preview will simply load the webpage as a plain text file.

You can verify these behavior by debugging into the Visual Studio process and check the module window, filter with razor keyword.

 

“Enable Edit and Continue” debugging option is now on by default for new web applications in VS2013 preview

$
0
0

In VS2010 and VS2012, the edit and continue option is disabled by default when creating a new web application project. In VS2013 preview, we turned it on by default. You can find this option on the Web tab in the web project’s properties window.  

clip_image002

With “Enable Edit and Continue” on, the VS debugger starts your web application in IIS Express. When you stop debugging, IIS Express is closed too. With this behavior, you will see the IIS Express system tray shows up during debugging and gone after debugging. This behavior is the same as in VS2012 when the Enable Edit and Continue option is turned on.

If you don’t need ENC (Edit and Continue) functionality during development and would like IIS Express to stay after a debugging session, you can simply turn the Enable Edit and Continue option off.

If you think it is important to have both ENC functionality and to leave IIS Express running after debugging, please use uservoice to let us know. Thanks for the support!

For more information about some new debugger feature in Visual Studio 2013 Preview,  please visit http://blogs.msdn.com/b/visualstudioalm/archive/2013/06/26/debugging-support-for-64-bit-edit-and-continue-in-visual-studio-2013.aspx .


Tracing in ASP.NET MVC Razor Views

$
0
0

System.Diagnostics.Trace can be a useful tool for logging and debugging, and sometimes it would be handy to be able to call one of the tracing methods from a Razor view.

For example, when an MVC application runs in production, by default MVC catches most application exceptions for you and routes them to Views/Shared/Error.cshtml. That view doesn’t show error details for security reasons, so you end up with the not-very-helpful message “An error occurred while processing your request.”

image

Running locally you get detailed error info, or you can catch exceptions by running in debug mode, but what to do about errors that happen in production? 

If you can re-create the error in production, you can temporarily tell the site to go ahead and display detailed error information by adding a customErrors element to your Web.config file in the system.web element:

Code Snippet
  1. <system.web>
  2.   <customErrorsmode="Off"defaultRedirect="Error" />

Now instead of “An error occurred” you get an actual error message and a stack trace.

image

But another quick-and-dirty alternative that doesn’t require temporarily exposing error details to the public, is to add tracing statements to the view, for example:

Code Snippet
  1. @using System.Diagnostics
  2.  
  3. @model System.Web.Mvc.HandleErrorInfo
  4.  
  5. @{
  6.     ViewBag.Title = "Error";
  7.     var message = string.Format("Error in Controller {0}, Action method {1}. Exception: {2}",
  8.         Model.ControllerName, Model.ActionName, Model.Exception.Message);
  9.     if (Model.Exception.InnerException != null)
  10.     {
  11.         message += "; Inner exception: " + Model.Exception.InnerException.Message;
  12.     }
  13.     Trace.TraceError(message);    
  14. }
  15.  
  16. <hgroupclass="title">
  17.     <h1class="error">Error.</h1>
  18.     <h2class="error">An error occurred while processing your request.</h2>
  19. </hgroup>

Unfortunately, when you do this you don’t get any trace output, and if you step through the code in the debugger you’ll see it step right over the TraceError method call without executing it.

Trace statements require the TRACE compiler constant, but it’s on by default and you can verify that in the Build tab of the project properties window:

image

The problem is that this setting in the .csproj file only applies to .cs files.  ASP.NET uses a different compile process for .cshtml files (or .aspx files in Web Forms), and the settings for that compile process are in the Web.config file. If you don’t explicitly specify the TRACE constant there, tracing method calls in .cshtml views are ignored.

You have at least two options for dealing with this situation if you want to add tracing in a view: define a TRACE constant for the .cshtml compiler, or use a static helper method.

Below is an example of what you have to add to the application Web.config file for a Visual Studio project that targets .NET 4.5, in order to define a TRACE constant for the .cshtml compiler:

Code Snippet
  1. <system.codedom>
  2.   <compilers>
  3.     <compiler
  4.       language="c#;cs;csharp"
  5.       extension=".cs"
  6.       type="Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
  7.       compilerOptions="/define:TRACE"
  8.       warningLevel="1" />
  9.   </compilers>
  10. </system.codedom>

With this in place the TraceError method call gets executed.

If you’re using a different Visual Studio or ASP.NET version, you can get the Version number you need by looking at your root Web.config file, copying out the codedom element from there, and adding the compilerOptions setting. The root Web.config file for .NET 4 or 4.5 is located in C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\web.config:

Code Snippet
  1. <system.codedom>
  2.     <compilers>
  3.         <compilerlanguage="c#;cs;csharp"extension=".cs"warningLevel="4"type="Microsoft.CSharp.CSharpCodeProvider, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
  4.             <providerOptionname="CompilerVersion"value="v4.0"/>
  5.             <providerOptionname="WarnAsError"value="false"/>
  6.         </compiler>
  7.         <compilerlanguage="vb;vbs;visualbasic;vbscript"extension=".vb"warningLevel="4"type="Microsoft.VisualBasic.VBCodeProvider, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
  8.             <providerOptionname="CompilerVersion"value="v4.0"/>
  9.             <providerOptionname="OptionInfer"value="true"/>
  10.             <providerOptionname="WarnAsError"value="false"/>
  11.         </compiler>
  12.     </compilers>
  13. </system.codedom>
  

If you’d rather use a static trace helper, create a class like the following example:

Code Snippet
  1. using System.Diagnostics;
  2.  
  3. namespace MyExample
  4. {
  5.     publicstaticclassTraceHelper
  6.     {
  7.         publicstaticvoid MyTrace(TraceLevel level, string message)
  8.         {
  9.             switch (level)
  10.             {
  11.                 caseTraceLevel.Error:
  12.                     Trace.TraceError(message);
  13.                     break;
  14.                 caseTraceLevel.Warning:
  15.                     Trace.TraceWarning(message);
  16.                     break;
  17.                 caseTraceLevel.Info:
  18.                     Trace.TraceInformation(message);
  19.                     break;
  20.                 caseTraceLevel.Verbose:
  21.                     Trace.WriteLine(message);
  22.                     break;
  23.             }
  24.         }
  25.     }
  26. }

Now you can use virtually the same code in your view without having to add a codeDom element to your Web.config:

Code Snippet
  1. @using MyExample
  2. @using System.Diagnostics
  3.  
  4. @model System.Web.Mvc.HandleErrorInfo
  5.  
  6. @{
  7.     ViewBag.Title = "Error";
  8.     var message = string.Format("Error in Controller {0}, Action method {1}. Exception: {2}",
  9.         Model.ControllerName, Model.ActionName, Model.Exception.Message);
  10.     if (Model.Exception.InnerException != null)
  11.     {
  12.         message += "; Inner exception: " + Model.Exception.InnerException.Message;
  13.     }
  14.     TraceHelper.MyTrace(TraceLevel.Error, message);
  15. }
  16.  
  17. <hgroupclass="title">
  18.     <h1class="error">Error.</h1>
  19.     <h2class="error">An error occurred while processing your request.</h2>
  20. </hgroup>

There are many ways to get the trace output, and I’ve added some links for info about that at the end of this post.

Adding tracing to views might be an effective way to debug a problem in production, and I’ve used Error.cshtml to show an example of how to do that. If your goal is a more permanent method of logging unhandled errors, a better method is to use an exception filter. To do that you create a class that implements IExceptionFilter, such as the following example:

Code Snippet
  1. using System.Web.Mvc;
  2.  
  3. namespace MyExample
  4. {
  5.     publicclassErrorLoggerFilter : IExceptionFilter
  6.    {
  7.         publicvoid OnException (ExceptionContext context)
  8.         {
  9.             var message = string.Format("Error processing URL: {0}. Exception: {1}",
  10.                 context.HttpContext.Request.Url,  context.Exception.Message);
  11.             if (context.Exception.InnerException != null)
  12.             {
  13.                 message += "; Inner exception: " + context.Exception.InnerException.Message;
  14.             }
  15.             context.HttpContext.Trace.Write(message);
  16.             System.Diagnostics.Trace.TraceError(message);    
  17.         }
  18.     }
  19. }

And then register the filter in App_Start/FilterConfig.cs:

Code Snippet
  1. using System.Web;
  2. using System.Web.Mvc;
  3.  
  4. namespace MyExample
  5. {
  6.     publicclassFilterConfig
  7.     {
  8.         publicstaticvoid RegisterGlobalFilters(GlobalFilterCollection filters)
  9.         {
  10.             filters.Add(newHandleErrorAttribute());
  11.             filters.Add(newErrorLoggerFilter());
  12.         }
  13.     }
  14. }

For another look at tracing best practices for web applications, see 47:00-55:36 in this video: Scott Guthrie: Building Real World Cloud Apps with Windows Azure - Part 2.

If you deploy your application to a Windows Azure Web Site, the latest SDK makes it exceptionally easy to get trace output immediately in the Visual Studio Output window while the site is running.  In two weeks the tutorial I’ve written about this will be published on WindowsAzure.com; until then, see the intro in the ScottGu blog post introducing Windows Azure SDK 2.0.

Some other links:

Thanks to Rick Anderson and Yishai Galatzer for help with the code for this blog post.

Writing Web API Client Code for Multiple Platforms Using Portable Libraries

$
0
0

The Microsoft ASP.NET Web API Client Libraries make it easy to write .NET clients that interact with RESTful HTTP services. Unfortunately, until recently the Web API client libraries did not support all platforms. Because of this limitation, developers had to maintain different code, depending on the target platform.

The new release of Microsoft ASP.NET Web API Client Libraries now comes with support for building portable libraries that target .NET 4.5, Windows Store and Windows Phone 8 applications. This support is built on the recently released portable HttpClient and the portable library support in Json.NET. Developers can now build a single portable library that can be used to consume Web APIs from Windows Phone and Windows Store apps as well as from middle-tier logic running on .NET 4.5

This blog post shows you how to create a reusable portable class library that consumes a sample HTTP service, and then how to use the library from a client application that targets multiple platforms.

Create the projects for different platforms

1. We will create three projects; a portable class library, which will actually use the Web API Client Libraries, a console application and a Windows Store app, which are the clients that will consume the portable library.
Create a new project named ContosoClient in C# with the Portable Class Library template. This is the common library that the other projects will use. The template is located under the Windows tab of the New Project dialog box:

clip_image002

2. In the Add Portable Class Library dialog, select the .NET Framework 4.5, Windows Phone 8, and .NET for Windows Store apps target platforms. Depending on the target platforms that you select, different .NET profile will be used for this project.

clip_image004

Note: This release of Microsoft ASP.NET Web API Client Libraries does not support Xbox 360, Silverlight, or Windows Phone 7.5 and lower. I won’t show how to create a Windows Phone 8[MW1] project in this article, but the ContosoClient portable library also supports Windows Phone 8.

3. Create a Windows console app named ContosoConsole.

4. Create a Windows Store app named ContosoStore with the Blank App (XAML) template as follows:

clip_image006

Configure the projects for the Web API Client Libraries

1. In Visual Studio, right-click the ContosoClient solution, and then select Manage NuGet Packages for solution. In the Manage NuGet Packages dialog, select Online->All in the left pane, select Include Prelease, and then search for “Microsoft.AspNet.WebApi.Client” as follows:

clip_image008

2. Click the Install button to install the Web API Client Libraries in all three of the projects that we created.

Note: Instead of having a single assembly set working for all the supported platforms, the Web API Client Libraries have two different sets of assemblies, depending on the target platforms. Because of this, you should install the package in all of the clients, although they do not directly use the libraries.

3. In Visual Studio, add a reference to ContosoClient to both of ContosoConsole and ContosoStore as follows:

clip_image010

Update the projects to consume Contoso Recipe Service

1. In Visual Studio, go to ContosoClient, and then add the following code. It calls the Contoso Recipe sample service, and deserializes the JSON result into a list of RecipeDataItemDto objects. The recipe service returns much more data regarding each recipe, but in this sample we only serialize the title and ID, in order to simplify the code.

Code Snippet
  1. using System;
  2. using System.Collections.Generic;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Net.Http;
  6. using System.Net.Http.Formatting;
  7. using System.Net.Http.Headers;
  8. using System.Threading.Tasks;
  9. using Newtonsoft.Json;
  10.  
  11. namespace ContocoClient
  12. {
  13.     publicclassRecipeDataAgent
  14.     {
  15.  
  16.         publicasyncTask<IEnumerable<RecipeDataItemDto>> GetRecipeDataItemsAsync()
  17.         {
  18.  
  19.             var client = new HttpClient();
  20.  
  21.             client.BaseAddress = newUri("http://contosorecipes8.blob.core.windows.net/");
  22.  
  23.             var jsonTypeFormatter = new JsonMediaTypeFormatter();
  24.  
  25.             jsonTypeFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/octet-stream"));
  26.  
  27.             var response = await client.GetAsync(("AzureRecipesRP"));
  28.  
  29.             returnawait response.Content.ReadAsAsync<List<RecipeDataItemDto>>(new[] { jsonTypeFormatter }); ;
  30.  
  31.         }
  32.  
  33.     }
  34.     publicclassRecipeDataItemDto
  35.     {
  36.         [JsonProperty("key")]
  37.         publicstring UniqueId
  38.         { get; set; }
  39.  
  40.         publicstring Title
  41.         { get; set; }
  42.     }
  43. }
 

2. In Visual Studio, go to ContosoClient and add the following code to Program.cs.

using ContocoClient;

Code Snippet
  1. namespace ContosoConsole
  2. {
  3.     classProgram
  4.     {
  5.         staticvoid Main(string[] args)
  6.         {
  7.             CallRecipeServiceAsync().Wait();
  8.         }
  9.  
  10.         publicstaticasync Task CallRecipeServiceAsync()
  11.         {
  12.             var recipes = awaitnew RecipeDataAgent().GetRecipeDataItemsAsync();
  13.             foreach (var receipe in recipes)
  14.             {
  15.                 Console.WriteLine(receipe.Title);
  16.             }
  17.         }
  18.     }
  19. }

3. Run the console application by pressing Ctrl+F5. The application will show the title of the all the recipes that the service returns:

clip_image012

4. In Visual Studio, go to ContosoStore and add the following code into the <Page> element in MainPage.xaml.

Code Snippet
  1. <GridBackground="{StaticResource ApplicationPageBackgroundThemeBrush}">
  2.   <ListViewx:Name="itemListView"/>
  3. </Grid>

5. In MainPage.xaml.cs, add the following method to the MainPage class.

Code Snippet
  1. public async void UpdateListView()
  2. {
  3.     var recipes = await new RecipeDataAgent().GetRecipeDataItemsAsync();
  4.     foreach (var receipe in recipes)
  5.     {
  6.         itemListView.Items.Add(receipe.Title);
  7.     }
  8. }

6. Call the UpdateListView method from the NavigatedTo method.

Code Snippet
  1. protectedoverridevoid OnNavigatedTo(NavigationEventArgs e)
  2. {
  3.     UpdateListView();
  4. }

7. Run the Windows Store app by pressing Ctrl+F5. The app will show the titles in the list view.[DR2]

clip_image014

Summary

The Web API Client Libraries make it easy to write Web API clients, but until now you had to maintain different source code for each platform using platform-specific APIs. With this release you can now write portable Web API client code that targets .NET 4.5, Windows Store apps and Windows Phone 8 apps. Enjoy!


Publish HTML/JS website to Linux/Apache using Visual Studio

$
0
0

We received a question about how to use Visual Studio to deploy HTML/JS website to Linux / Apache.  To do it, you need to create an empty ASP.NET website project in Visual Studio (File->New Web Site…) and then include all the HTML/JS files.

1. Right click on the website Project, select “Publish Web Site”.

2. Drop down the Publish Profile drop down and select New Profile. Name it “FTP” or whatever you want to call it.

clip_image001

clip_image002

3. On the Connection Tab set Publish method to FTP, fill in FTP server, root folder for the website on the server, user name and password.

clip_image003

4. Click “Validate” to see if we can connect.

5. Press the “Publish” button

 

The detailed MSDN topic for VS2012 is here.  This functionality exists in VS2010 and WEBMATRIX as well. 

Katana License Lifts Windows-only Restriction

$
0
0

(cross-posted from http://codebetter.com/howarddierking/2013/07/23/katana-license-lifts-windows-only-restriction/)

Over the past few months, a great deal of attention has been paid to the following clause used in most of the licenses associated with the NuGet packages that we and other teams at Microsoft ship.

 

“ a. Distribution Restrictions. You may not

distribute Distributable Code to run on a platform other than the Windows platform;

In the case of the ASP.NET-related projects, including project Katana, this license (and the associated restriction) does not apply to the source code, but rather to the compiled binaries that are distributed via NuGet (the Katana source code is released under the Apache 2.0 license). This means that even today, it is perfectly reasonable to build the source code yourself and run it on Mono on whatever platform you choose.
 
But why should you have to jump through those hoops just to satisfy a clause in the license?
 
As Microsoft teams continue to take more and more components out of the traditional box products and deliver them as NuGet packages, the frustration over this restriction has grown proportionally. And in the particular case of project Katana, where one of the key selling points is portability, and where we want other OSS frameworks to build on top of us, it quickly became clear that the restriction fundamentally did not align with one of the core goals of the project.
 
So we changed the license.
 
With the release of Katana 2.0, which will accompany Visual Studio 2013, the Windows-only restriction will be removed from the Katana binary license. It’s important to note here that at this point, the exception applies only to the Katana packages.
 
While it may appear to be a small step, we’re very excited as we believe it to be a significant one in the right direction!

EF/MVC Series updated to EF5/MVC4

$
0
0

Tom Dykstra and I have updated Tom’s popular EF/MVC series to the latest release, that is MVC 4 and EF 5. The biggest change was the addition of code first migrations.  What’s great about the updated 10 part series is you can download the end of each chapter. Suppose you want to get a jump start on Concurrency (Covered in Chapter 7), you can now download the completed chapter 6 and start working on the concurrency tutorial.

In addition to bug fixes and new features in MVC and EF, we’ve streamlined the tutorial so you can get through it faster and with less friction. We’ll be monitoring feedback closely, so let us know what works and what needs to be improved.

Significant changes:

  • code first migrations
  • Now uses LocalDB, which simplifies development and deployment.
  • Windows Azure Deployment added.

 

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

Viewing all 7144 articles
Browse latest View live


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