Skip to content

Latest commit

 

History

History
831 lines (712 loc) · 45.5 KB

dntut_mobile_rest_api_with_sql.md

File metadata and controls

831 lines (712 loc) · 45.5 KB
# REST service using ASP.NET Web API and SQL Database

This tutorial shows how to deploy an ASP.NET web application that uses the ASP.NET Web API to a Windows Azure Web Site by using the Publish Web wizard in Visual Studio 2012 or Visual Studio 2012 for Web Express.

You can open a Windows Azure account for free, and if you don't already have Visual Studio 2012, the SDK automatically installs Visual Studio 2012 for Web Express. So you can start developing for Windows Azure entirely for free.

This tutorial assumes that you have no prior experience using Windows Azure. On completing this tutorial, you'll have a data-driven web application up and running in the cloud and using a cloud database.

You'll learn:

  • How to enable your machine for Windows Azure development by installing the Windows Azure SDK.
  • How to create a Visual Studio ASP.NET MVC 4 project and publish it to a Windows Azure Web Site.
  • How to use the ASP.NET Web API to enable Restful API calls.
  • How to use a SQL database to store data in Windows Azure.
  • How to publish application updates to Windows Azure.

You'll build a simple contact list web application that is built on ASP.NET MVC 4 and uses the ADO.NET Entity Framework for database access. The following illustration shows the completed application:

screenshot of web site

In this tutorial:

Set up the development environment

To start, set up your development environment by installing the Windows Azure SDK for the .NET Framework.

  1. To install the Windows Azure SDK for .NET, click the link below. If you don't have Visual Studio 2012 installed yet, it will be installed by the link. This tutorial requires Visual Studio 2012.
    Get Tools and SDK for Visual Studio 2012
  2. When you are prompted to run or save vwdorvs11azurepack.exe, click Run.

Web Platform Installer - Windows Azure SDK for .NET

When the installation is complete, you have everything necessary to start developing.

Set up the Windows Azure environment

Next, set up the Windows Azure environment by creating a Windows Azure Web Site and a SQL database.

Create a web site and a SQL database in Windows Azure

The next step is to create the Windows Azure web site and the SQL database that your application will use.

Your Windows Azure Web Site will run in a shared hosting environment, which means it runs on virtual machines (VMs) that are shared with other Windows Azure clients. A shared hosting environment is a low-cost way to get started in the cloud. Later, if your web traffic increases, the application can scale to meet the need by running on dedicated VMs. If you need a more complex architecture, you can migrate to a Windows Azure Cloud Service. Cloud services run on dedicated VMs that you can configure according to your needs.

SQL Database is a cloud-based relational database service that is built on SQL Server technologies. The tools and applications that work with SQL Server also work with SQL Database.

  1. In the Windows Azure Management Portal, click Web Sites in the left tab, and then click New.
  2. Click CUSTOM CREATE.
    Create with Database link in Management Portal
    The New Web Site - Custom Create wizard opens.
  3. In the New Web Site step of the wizard, enter a string in the URL box to use as the unique URL for your application. The complete URL will consist of what you enter here plus the suffix that you see below the text box. The illustration shows "contactmgr22", but that URL is probably taken so you’ll have to choose a different one.
  4. In the Region drop-down list, choose the region that is closest to you.
  5. In the Database drop-down list, choose Create a new SQL database. Accept the default connection string. Create a New Web Site step of New Web Site - Create with Database wizard
  6. Click the arrow that points to the right at the bottom of the box. The wizard advances to the Database Settings step.
  7. In the Name box, enter ContactDB.
  8. In the Server box, select New SQL Database server. Alternatively, if you previously created a SQL Server database, you can select that SQL Server from the dropdown control.
  9. Click the arrow that points to the right at the bottom of the box.
  10. Enter an administrator LOGIN NAME and PASSWORD. If you selected New SQL Database server you aren't entering an existing name and password here, you're entering a new name and password that you're defining now to use later when you access the database. If you selected a SQL Server you’ve created previously, you’ll be prompted for the password to the previous SQL Server account name you created. For this tutorial, we won't check the **Advanced ** box. The **Advanced ** box allows you to set the DB size (the default is 1 GB but you can increase this to 150 GB) and the collation.
  11. Click the check mark at the bottom of the box to indicate you're finished. Database Settings step of New Web Site - Create with Database wizard

    The following image shows using an existing SQL Server and Login. Database Settings step of New Web Site - Create with Database wizard
    The Management Portal returns to the Web Sites page, and the Status column shows that the site is being created. After a while (typically less than a minute), the Status column shows that the site was successfully created. In the navigation bar at the left, the number of sites you have in your account appears next to the Web Sites icon, and the number of databases appears next to the SQL Databases icon.

Create an ASP.NET MVC 4 application

You have created a Windows Azure Web Site, but there is no content in it yet. Your next step is to create the Visual Studio web application project that you'll publish to Windows Azure.

Create the project

  1. Start Visual Studio 2012.
  2. From the File menu click New Project.
  3. In the New Project dialog box, expand Visual C# and select Web under Installed Templates and then select ASP.NET MVC 4 Web Application. Keep the default .NET Framework 4.5. Name the application ContactManager and click OK.
    New Project dialog box
  4. In the New ASP.NET MVC 4 Project dialog box, select the Internet Application template. Keep the default Razor View Engine and then click OK.
    New ASP.NET MVC 4 Project dialog box

Set the page header and footer

  1. In Solution Explorer, expand the Views\Shared folder and open the _Layout.cshtml file.
    _Layout.cshtml in Solution Explorer
  2. Replace the contents of the _Layout.cshtml file with the following code:

&lt;!DOCTYPE html&gt;<br/>
&lt;html lang=&quot;en&quot;&gt;<br/>
&lt;head&gt;<br/>
    &lt;meta charset=&quot;utf-8&quot; /&gt;<br/>
    &lt;title&gt;@ViewBag.Title - Contact Manager&lt;/title&gt;<br/>
    &lt;link href=&quot;~/favicon.ico&quot; rel=&quot;shortcut icon&quot; type=&quot;image/x-icon&quot; /&gt;<br/>
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width&quot; /&gt;<br/>
    @Styles.Render(&quot;~/Content/css&quot;)<br/>
    @Scripts.Render(&quot;~/bundles/modernizr&quot;)<br/>
&lt;/head&gt;<br/>
&lt;body&gt;<br/>
    &lt;header&gt;<br/>
        &lt;div class=&quot;content-wrapper&quot;&gt;<br/>
            &lt;div class=&quot;float-left&quot;&gt;<br/>
                &lt;p class=&quot;site-title&quot;&gt;@Html.ActionLink(&quot;Contact Manager&quot;, &quot;Index&quot;, &quot;Home&quot;)&lt;/p&gt;<br/>              
            &lt;/div&gt;<br/>
        &lt;/div&gt;<br/>
    &lt;/header&gt;<br/>
    &lt;div id=&quot;body&quot;&gt;<br/>
        @RenderSection(&quot;featured&quot;, required: false)<br/>
        &lt;section class=&quot;content-wrapper main-content clear-fix&quot;&gt;<br/>
            @RenderBody()<br/>
        &lt;/section&gt;<br/>
    &lt;/div&gt;<br/>
    &lt;footer&gt;<br/>
        &lt;div class=&quot;content-wrapper&quot;&gt;<br/>
            &lt;div class=&quot;float-left&quot;&gt;<br/>
                &lt;p&gt;&amp;copy; @DateTime.Now.Year - Contact Manager&lt;/p&gt;<br/>
            &lt;/div&gt;<br/>
        &lt;/div&gt;<br/>
    &lt;/footer&gt;<br/><br/>
	@Scripts.Render("~/bundles/jquery")<br/>
	@RenderSection("scripts", required: false)
&lt;/body&gt;<br/>
&lt;/html&gt;

Run the application locally

  1. Press CTRL+F5 to run the application. The application home page appears in the default browser.
    To Do List home page

This is all you need to do for now to create the application that you'll deploy to Windows Azure. Later you'll add database functionality.

Deploy the application to Windows Azure

  1. In your browser, open the Windows Azure Management Portal.

  2. In the Web Sites tab, click the name of the site you created earlier.
    Contact manager application in Management Portal Web Sites tab

  3. On the right side of the window, click Download publish profile.
    Quickstart tab and Download Publishing Profile button
    This step downloads a file that contains all of the settings that you need in order to deploy an application to your Web Site. You'll import this file into Visual Studio so you don't have to enter this information manually.

  4. Save the .publishsettings file in a folder that you can access from Visual Studio.
    saving the .publishsettings file Security Note: The .publishsettings file contains your credentials (unencoded) that are used to administer your Windows Azure subscriptions and services. The security best practice for this file is to store it temporarily outside your source directories (for example in the Libraries\Documents folder), and then delete it once the import has completed. A malicious user gaining access to the publishsettings file can edit, create, and delete your Windows Azure services.

  5. In Visual Studio, right-click the project in Solution Explorer and select Publish from the context menu.
    Publish in project context menu
    The Publish Web wizard opens.

  6. In the Profile tab of the Publish Web wizard, click Import.
    Import button in Publish Web wizard

  7. Select the .publishsettings file you downloaded earlier, and then click Open.

  8. In the Connection tab, click Validate Connection to make sure that the settings are correct. When the connection has been validated, a green check mark is shown next to the Validate Connection button.

  9. Click Next.
    connection successful icon and Next button in Connection tab

  10. In the Settings tab, click Next.
    You can accept all of the default settings on this page. You are deploying a Release build configuration and you don't need to delete files at the destination server. The UsersContext (DefaultConnection) entry under Databases comes from the UsersContext:DbContext class which uses the DefaultConnection string.


    connection successful icon and Next button in Connection tab

  11. In the Preview tab, click Start Preview.
    The tab displays a list of the files that will be copied to the server. Displaying the preview isn't required to publish the application but is a useful function to be aware of. In this case, you don't need to do anything with the list of files that is displayed.
    StartPreview button in the Preview tab

  12. Click Publish.
    Visual Studio begins the process of copying the files to the Windows Azure server. The Output window shows what deployment actions were taken and reports successful completion of the deployment.

  13. The default browser automatically opens to the URL of the deployed site.
    The application you created is now running in the cloud.
    To Do List home page running in Windows Azure

Add a database to the application

Next, you'll update the MVC application to add the ability to display and update contacts and store the data in a database. The application will use the Entity Framework to create the database and to read and update data in the database.

Add data model classes for the contacts

You begin by creating a simple data model in code.

  1. In Solution Explorer, right-click the Models folder, click Add, and then Class.
    Add Class in Models folder context menu

  2. In the Add New Item dialog box, name the new class file Contact.cs, and then click Add.
    Add New Item dialog box

  3. Replace the contents of the Contacts.cs file with the following code.

     using System.Globalization;
     namespace ContactManager.Models
     {
     	public class Contact
     	{
     		public int ContactId { get; set; }
     		public string Name { get; set; }
     		public string Address { get; set; }
         	public string City { get; set; }
     		public string State { get; set; }
     		public string Zip { get; set; }
     		public string Email { get; set; }
     		public string Twitter { get; set; }
     		public string Self
     		{
         		get { return string.Format(CultureInfo.CurrentCulture,
     		         "api/contacts/{0}", this.ContactId); }
         		set { }
     		}
     	}
     }
    

The Contacts class defines the data that you will store for each contact, plus a primary key, ContactID, that is needed by the database.

Create web pages that enable app users to work with the contacts

The ASP.NET MVC the scaffolding feature can automatically generate code that performs create, read, update, and delete (CRUD) actions.

Add a Controller and a view for the data

  1. In Solution Explorer, expand the Controllers folder.
  2. Build the project (Ctrl+Shift+B). (You must build the project before using scaffolding mechanism.)
  3. Right-click the Controllers folder and click Add, and then click Controller....
    Add Controller in Controllers folder context menu
  4. In the Add Controller dialog box, enter "HomeController" as your controller name. Set the Scaffolding options Template to MVC Controller with read/write actions and views, using Entity Framework.
  5. Select Contact as your model class and <New data context...> as your data context class.
    Add Controller dialog box
  6. On the New Data Context dialog box, accept the default value ContactManager.Models.ContactManagerContext.
    Add Controller dialog box
  7. Click OK, then click Add in the Add Controller dialog box.
  8. On the Add Controller overwrite dialog, make sure all options are checked and click OK.
    Add Controller message box
    Visual Studio creates a controller methods and views for CRUD database operations for Contact objects.

Enable Migrations, create the database, add sample data and a data initializer

The next task is to enable the Code First Migrations feature in order to create the database based on the data model you created.

  1. In the Tools menu, select Library Package Manager and then Package Manager Console.
    Package Manager Console in Tools menu

  2. In the Package Manager Console window, enter the following command:

     enable-migrations -ContextTypeName ContactManagerContext
    


enable-migrations
You must specify the context type name (ContactManagerContext) because the project contains two DbContext derived classes, the ContactManagerContext we just added and the UsersContext, which is used for the membership database. The ContactManagerContext class was added by the Visual Studio scaffolding wizard.
The enable-migrations command creates a Migrations folder and it puts in that folder a Configuration.cs file that you can edit to configure Migrations.

  1. In the Package Manager Console window, enter the following command:

     add-migration Initial
    

    The add-migration Initial command generates a class named <date_stamp>Initial that creates the database. The first parameter ( Initial ) is arbitrary and used to create the name of the file. You can see the new class files in Solution Explorer.
    In the Initial class, the Up method creates the Contacts table, and the Down method (used when you want to return to the previous state) drops it.

  2. Right-click the Migrations folder and open the Configuration.cs file.

  3. Add the following namespaces.

      using ContactManager.Models;
    
  4. Replace the Seed method with the following code:

     protected override void Seed(ContactManager.Models.ContactManagerContext context)
     {
         context.Contacts.AddOrUpdate(p => p.Name,
            new Contact
            {
                Name = "Debra Garcia",
                Address = "1234 Main St",
                City = "Redmond",
                State = "WA",
                Zip = "10999",
                Email = "debra@example.com",
                Twitter = "debra_example"
            },
             new Contact
             {
                 Name = "Thorsten Weinrich",
                 Address = "5678 1st Ave W",
                 City = "Redmond",
                 State = "WA",
                 Zip = "10999",
                 Email = "thorsten@example.com",
                 Twitter = "thorsten_example"
             },
             new Contact
             {
                 Name = "Yuhong Li",
                 Address = "9012 State st",
                 City = "Redmond",
                 State = "WA",
                 Zip = "10999",
                 Email = "yuhong@example.com",
                 Twitter = "yuhong_example"
             },
             new Contact
             {
                 Name = "Jon Orton",
                 Address = "3456 Maple St",
                 City = "Redmond",
                 State = "WA",
                 Zip = "10999",
                 Email = "jon@example.com",
                 Twitter = "jon_example"
             },
             new Contact
             {
                 Name = "Diliana Alexieva-Bosseva",
                 Address = "7890 2nd Ave E",
                 City = "Redmond",
                 State = "WA",
                 Zip = "10999",
                 Email = "diliana@example.com",
                 Twitter = "diliana_example"
             }
             );
     }
    

    This code above will initialize the database with the contact information. For more information on seeding the database, see Debugging Entity Framework (EF) DBs.

  5. In the Package Manager Console enter the command:

     update-database
    

    Package Manager Console commands

    The update-database runs the first migration which creates the database. By default, the database is created as a SQL Server Express LocalDB database. (Unless you have SQL Server Express installed, in which case the database is created using the SQL Server Express instance.)

  6. Press CTRL+F5 to run the application.

The application shows the seed data and provides edit, details and delete links.


MVC view of data

Edit the View

  1. Expand the Views\Home folder and open the Index.cshtml file.

  2. Replace the contents of the file with the following code.

     @model IEnumerable<ContactManager.Models.Contact>
     @{
         ViewBag.Title = "Home";
     }
     @section Scripts {
         @Scripts.Render("~/bundles/knockout")
         <script type="text/javascript">
             function ContactsViewModel() {
                 var self = this;
                 self.contacts = ko.observableArray([]);
                 self.addContact = function () {
                     $.post("api/contacts",
                         $("#addContact").serialize(),
                         function (value) {
                             self.contacts.push(value);
                         },
                         "json");
                 }
                 self.removeContact = function (contact) {
                     $.ajax({
                         type: "DELETE",
                         url: contact.Self,
                         success: function () {
                             self.contacts.remove(contact);
                         }
                     });
                 }
    
                 $.getJSON("api/contacts", function (data) {
                     self.contacts(data);
                 });
             }
             ko.applyBindings(new ContactsViewModel());	
     </script>
     }
     <ul id="contacts" data-bind="foreach: contacts">
         <li class="ui-widget-content ui-corner-all">
             <h1 data-bind="text: Name" class="ui-widget-header"></h1>
             <div><span data-bind="text: $data.Address || 'Address?'"></span></div>
             <div>
                 <span data-bind="text: $data.City || 'City?'"></span>,
                 <span data-bind="text: $data.State || 'State?'"></span>
                 <span data-bind="text: $data.Zip || 'Zip?'"></span>
             </div>
             <div data-bind="if: $data.Email"><a data-bind="attr: { href: 'mailto:' + Email }, text: Email"></a></div>
             <div data-bind="ifnot: $data.Email"><span>Email?</span></div>
             <div data-bind="if: $data.Twitter"><a data-bind="attr: { href: 'http://twitter.com/' + Twitter }, text: '@@' + Twitter"></a></div>
             <div data-bind="ifnot: $data.Twitter"><span>Twitter?</span></div>
             <p><a data-bind="attr: { href: Self }, click: $root.removeContact" class="removeContact ui-state-default ui-corner-all">Remove</a></p>
         </li>
     </ul>
     <form id="addContact" data-bind="submit: addContact">
         <fieldset>
             <legend>Add New Contact</legend>
             <ol>
                 <li>
                     <label for="Name">Name</label>
                     <input type="text" name="Name" />
                 </li>
                 <li>
                     <label for="Address">Address</label>
                     <input type="text" name="Address" >
                 </li>
                 <li>
                     <label for="City">City</label>
                     <input type="text" name="City" />
                 </li>
                 <li>
                     <label for="State">State</label>
                     <input type="text" name="State" />
                 </li>
                 <li>
                     <label for="Zip">Zip</label>
                     <input type="text" name="Zip" />
                 </li>
                 <li>
                     <label for="Email">E-mail</label>
                     <input type="text" name="Email" />
                 </li>
                 <li>
                     <label for="Twitter">Twitter</label>
                     <input type="text" name="Twitter" />
                 </li>
             </ol>
             <input type="submit" value="Add" />
         </fieldset>
     </form>
    
  3. Right-click the Content folder and click Add, and then click New Item....

    Add style sheet in Content folder context menu

  4. In the Add New Item dialog box, enter Style in the upper right search box and then select Style Sheet.
    Add New Item dialog box

  5. Name the file Contacts.css and click Add. Replace the contents of the file with the following code.

     .column {
         float: left;
         width: 50%;
         padding: 0;
         margin: 5px 0;
     }
     form ol {
         list-style-type: none;
         padding: 0;
         margin: 0;
     }
     form li {
         padding: 1px;
         margin: 3px;
     }
     form input[type="text"] {
         width: 100%;
     }
     #addContact {
         width: 300px;
         float: left;
         width:30%;
     }
     #contacts {
         list-style-type: none;
         margin: 0;
         padding: 0;
         float:left;
         width: 70%;
     }
     #contacts li {
         margin: 3px 3px 3px 0;
         padding: 1px;
         float: left;
         width: 300px;
         text-align: center;
         background-image: none;
         background-color: #F5F5F5;
     }
     #contacts li h1
     {
         padding: 0;
         margin: 0;
         background-image: none;
         background-color: Orange;
         color: White;
         font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif;
     }
     .removeContact, .viewImage
     {
         padding: 3px;
         text-decoration: none;
     }
    
  6. Expand the App_Start folder and open the BundleConfig.cs file.

  7. Add the following statement to register the Knockout plugin.

     bundles.Add(new ScriptBundle("~/bundles/knockout").Include(
                 "~/Scripts/knockout-{version}.js"));
    

    This sample using knockout to simplify dynamic JavaScript code that handles the screen templates.

  8. Modify the contents/css entry to register the contacts.css style sheet. Change the following line:

     bundles.Add(new StyleBundle("~/Content/css").Include("~/Content/site.css"));
    

To:

    bundles.Add(new StyleBundle("~/Content/css").Include(
                "~/Content/site.css",
                "~/Content/contacts.css"));

Add a controller for the Web API Restful interface

  1. In Solution Explorer, right-click Controllers and click Add and then Controller....
  2. In the Add Controller dialog box, enter "ContactsController" as your controller name, select the API controller with read/write actions, using Entity Framework template.
  3. In Model Class select Contact (ContactManager.Models) and in Data Context Class select ContactManagerContext (ContactManager.Models).
    Add API controller
  4. Click Add.

Run the application locally

  1. Press CTRL+F5 to run the application.
    Index page
  2. Enter a contact and click Add. The app returns to the home page and displays the contact you entered.
    Index page with to-do list items
  3. In the browser, append /api/contacts to the URL. The resulting URL will resemble http://localhost:1234/api/contacts. The RESTful web API you added returns the stored contacts.
    FireFox and Chrome will display the data in XML format.


Index page with to-do list items
IE will prompt you to open or save the contacts. Web API save dialog
You can open the returned contacts in notepad or a browser. This output can be consumed by another application such as mobile web page or application.
Web API save dialog

XSRFAdd XSRF Protection

Cross-site request forgery (also known as XSRF or CSRF) is an attack against web-hosted applications whereby a malicious web site can influence the interaction between a client browser and a web site trusted by that browser. These attacks are made possible because web browsers will send authentication tokens automatically with every request to a web site. The canonical example is an authentication cookie, such as ASP.NET’s Forms Authentication ticket. However, web sites which use any persistent authentication mechanism (such as Windows Authentication, Basic, and so forth) can be targeted by these attacks. An XSRF attack is distinct from a phishing attack. Phishing attacks require interaction from the victim. In a phishing attack, a malicious web site will mimic the target web site, and the victim is fooled into providing sensitive information to the attacker. In an XSRF attack, there is often no interaction necessary from the victim. Rather, the attacker is relying on the browser automatically sending all relevant cookies to the destination web site. For more information, see the [Open Web Application Security Project](https://www.owasp.org/index.php/Main_Page) (OWASP) [XSRF](https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)).
  1. In Solution Explorer, right click Filters and click Add and then click Class.

  2. Name the file ValidateHttpAntiForgeryTokenAttribute.cs and add the following code:

     using System;
     using System.Collections.Generic;
     using System.Linq;
     using System.Net;
     using System.Net.Http;
     using System.Web.Helpers;
     using System.Web.Http.Controllers;
     using System.Web.Http.Filters;
     using System.Web.Mvc;
    
     namespace ContactManager.Filters
     {
         public class ValidateHttpAntiForgeryTokenAttribute : AuthorizationFilterAttribute
         {
             public override void OnAuthorization(HttpActionContext actionContext)
             {
                 HttpRequestMessage request = actionContext.ControllerContext.Request;
                 try
                 {
                     if (IsAjaxRequest(request))
                     {
                         ValidateRequestHeader(request);
                     }
                     else
                     {
                         AntiForgery.Validate();
                     }
                 }
                 catch (HttpAntiForgeryException e)
                 {
                     actionContext.Response = request.CreateErrorResponse(HttpStatusCode.Forbidden, e);
                 }
             }
             private bool IsAjaxRequest(HttpRequestMessage request)
             {
                 IEnumerable<string> xRequestedWithHeaders;
                 if (request.Headers.TryGetValues("X-Requested-With", out xRequestedWithHeaders))
                 {
                     string headerValue = xRequestedWithHeaders.FirstOrDefault();
                     if (!String.IsNullOrEmpty(headerValue))
                     {
                         return String.Equals(headerValue, "XMLHttpRequest", StringComparison.OrdinalIgnoreCase);
                     }
                 }
    
                 return false;
             }
    
             private void ValidateRequestHeader(HttpRequestMessage request)
             {
                 string cookieToken = String.Empty;
                 string formToken = String.Empty;
     			IEnumerable<string> tokenHeaders;
                 if (request.Headers.TryGetValues("RequestVerificationToken", out tokenHeaders))
                 {
                     string tokenValue = tokenHeaders.FirstOrDefault();
                     if (!String.IsNullOrEmpty(tokenValue))
                     {
                         string[] tokens = tokenValue.Split(':');
                         if (tokens.Length == 2)
                         {
                             cookieToken = tokens[0].Trim();
                             formToken = tokens[1].Trim();
                         }
                     }
                 }
    
                 AntiForgery.Validate(cookieToken, formToken);
             }
         }
     }
    
  3. You can add the [ValidateHttpAntiForgeryToken] attribute to the ContactsController to protect it from XSRF threats. A better approach is to add the ValidateHttpAntiForgeryToken attribute globally to the App_Start\WebApiConfig.cs file as shown below:

     public static class WebApiConfig
     {
         public static void Register(HttpConfiguration config)
         {
             config.Routes.MapHttpRoute(
                 name: "DefaultApi",
                 routeTemplate: "api/{controller}/{id}",
                 defaults: new { id = RouteParameter.Optional }
             );
    
             GlobalConfiguration.Configuration.Filters.Add(new ValidateHttpAntiForgeryTokenAttribute());
             //config.EnableQuerySupport();
         }
     }
    

Publish the application update to Windows Azure and SQL Database

To publish the application, you repeat the procedure you followed earlier.

  1. In Solution Explorer, right click the project and select Publish.
    Publish

  2. Click the Settings tab. Settings tab of Publish Web wizard
  3. Under ContactsManagerContext(ContactsManagerContext), click the v icon to change Remote connection string to the connection string for the contact database.
  4. The remote connection string box for the ContactsManagerContext(ContactsManagerContext) database now contains the SQL Database connection string that was provided in the publishsettings file. Click on the ellipsis (...) to see the ContactDB settings.

    DB settings

  5. Close the Destination Connections String Dialog and in the Publish Web dialog check the box for Execute Code First Migrations (runs on application start) for the UsersContext(DefaultConnection) database.
    Settings tab of Publish Web wizard
  6. You can click the ^ icon next to the UsersContext(DefaultConnection) database, that is the connection information for the membership database and we're not using it in this tutorial. A real application would require authentication and authorization, and you would use the membership database for that purpose. See Deploy a Secure ASP.NET MVC application with OAuth, Membership and SQL Database which is based on this tutorial and shows how to deploy a web application with the membership database.
  7. Click Next and then click Preview. Visual Studio displays a list of the files that will be added or updated.
  8. Click Publish.
    After the deployment completes, the browser opens to the home page of the application.
    Index page with no contacts
    The Visual Studio publish process automatically configured the connection string in the deployed Web.config file to point to the SQL database. It also configured Code First Migrations to automatically upgrade the database to the latest version the first time the application accesses the database after deployment. As a result of this configuration, Code First created the database by running the code in the Initial class that you created earlier. It did this the first time the application tried to access the database after deployment.
  9. Enter a contact as you did when you ran the app locally, to verify that database deployment succeeded. When you see that the item you enter is saved and appears on the contact manager page, you know that it has been stored in the database.
    Index page with contacts

The application is now running in the cloud, using SQL Database to store its data. After you finish testing the application in Windows Azure, delete it. The application is public and doesn't have a mechanism to limit access.

Next Steps

A real application would require authentication and authorization, and you would use the membership database for that purpose. The tutorial Deploy a Secure ASP.NET MVC application with OAuth, Membership and SQL Database is based on this tutorial and shows how to deploy a web application with the membership database.
Another way to store data in a Windows Azure application is to use Windows Azure storage, which provide non-relational data storage in the form of blobs and tables. The following links provide more information on Web API, ASP.NET MVC and Window Azure.

This tutorial and the sample application was written by Rick Anderson (Twitter @RickAndMSFT) with assistance from Tom Dykstra, Tom FitzMacken and Barry Dorrans (Twitter @blowdart).

Please leave feedback on what you liked or what you would like to see improved, not only about the tutorial itself but also about the products that it demonstrates. Your feedback will help us prioritize improvements. We are especially interested in finding out how much interest there is in more automation for the process of configuring and deploying the membership database.