Access IIS on Windows7 VM from the Mac OS

Challenge

Developing both native and web application components targeted to different platforms can prove to be challenging for developers running the Mac OS and Windows VM on the same physical machine.

When developing a native iOS client application using Xcode on the Mac and an ASP.NET MVC web application using Visual Studio 2012 running on Windows Internet Information Services (IIS), I needed the ability to make a Web API call from Xcode’s iOS Simulator on the Mac to the IIS web application running on the Win7 VM.

With a few simple steps you can setup your Mac to allow http access between the Mac OS and the Windows VM to make development and testing much easier.

Solution

Windows7 VM (Parallels)

  1. From the Windows Control Panel, open up the Windows Firewall client.
  2. From the Firewall client, click on Advanced Settings and select Inbound Rules.

    image

  3. Scroll down to the rule titled: World Wide Web Services (HTTP Traffic-In), right-click and select Properties.

    image

  4. Set to Enabled.
  5. Open a Windows Command Prompt and type: ipconfig to get your current IP address.

    image

Mac OS

  1. Use the current IP address when calling the web application URL within your iOS code on the Mac.

    image

  2. Now you can access the IIS web server on the Win7 VM from any browser or web tool residing on the Mac.

Amazing Hickory-Smoked Grilled Turkey

Over the years, I’ve tried many different ways of preparing our Thanksgiving turkey but none have produced a bird as succulent and delicious as charcoal grilling with hickory smoking chips.

Here’s my can’t miss, do-it-yourself guide to grilling the perfect bird.

Food Preparation

We always prefer naturally grown, organic foods. Today’s turkey is vegetatian fed and contains no antibiotics preservatives or added hormones.

Brining the turkey is the process of soaking the bird in a salt-water ‘brine’ for 12-24 hours prior to cooking. There’s many different opinions on whether the brining process actually contributes to cooking a moister, more tender turkey. After years of trying it both ways, I’m convinced that brining is always the best way to go.

The night before grilling, I mix up a simple brine concoction of mostly salt water, seasonings and vegetables. Use any brine recipe you’d like, I happen to be partial to Matha Stewart’s recipe.

Put the turkey inside doubled plastic cooking bags, inside a large cooking pot. Pour the brine mixture over the turkey, inside the cooking bags. Seal up the bags and place in the refrigerator overnight.

Grill Preparation

I use a Weber, kettle-style, charcoal grill which works great for turkeys up to about 22 pounds. Today’s turkey weighs in at a bit over 13 pounds which is a perfect size for a smaller gathering.

Before starting, get yourself a bag of decent quality charcoal briquettes and a bag of hickory smoking chips.

Starting with a clean grill, fire up about 60-80 charcoal briquettes. I prefer to use a stovepipe charcoal starter which holds about 80 regular sized briquets (yes, I counted).

When coals are mostly white hot (20-30 minutes), spread out evenly in a 12-16 inch diameter. Place clean grill grate directly over hot coals.

Prepare the smoking bags by filling two pieces of heavy duty aluminum foil (approximately 12” x 24”) with hickory chips. 

Fold the foil into 6” x 6” packets and make sever holes in the top of the foil.

Fully open the top and bottom vents on the gril.

The Grilling Process

The general rule of thumb for grilling a turkey is approximately one hour per 5 pounds of bird. Using this formula, our 13 pound turkey should take a little over 2.5 hours to grill but depending on grill size, charcoal and even outdoor temperature, your actual cooking time will vary. I recommend using a meat thermometer to be sure you don’t under or over cook your bird.

Remove the turkey from the brine mixture and pat dry.

Brush the turkey liberally with olive or grapeseed oil to prevent bird skin from sticking to grill.

Place bird directly onto grill, rolling slightly every 2 minutes until all sides of the turkey have kissed the grill grate and have a niced browned tone.

Remove turkey and grate from the grill.

Add a few handfuls of briquets and throw on the foil smoking bags containing the hickory chips.

After 5-10 minutes, spread the charcoals around the outside edges of the grill, leaving the center of the grill open.

Place the smoking bags directly onto the hot coals on either side of the grill, leaving the center open.

Place the grill grate onto the grill.

Put the turkey in a disposable foil pan or some rolled up heavy duty aluminum oil big enough to catch and contain the drippings.

Pour 1 cup of water into the body cavity, place turkey onto grill and cover.

Check every 30 minutes. Baste the turkey and add additional coals as needed (depending on bird size and cooking time).

Begin checking meat temperature well in advance of the predetermined cooking time. The grill should have a steady stream of sweet smelling hickory smoke for most of the cooking cycle.

When the temperature deep within the breast reaches 160º F, remove the bird from the grill. Remove the turkey from cooking pan, cover with aluminum foil and let stand for 30-40 minutes before carving.

The Finale 

Our 13 pound turkey hit 160º F at exactly the 2 hour mark. After setting for 45 minutes, here’s what we have to carve:

This grilled turkey was simple to make and may be the very best we’ve ever eaten. Give it a try yourself and let me know what you think. I can guarantee you won’t be disappointed.

Bon appétit

Mark Chouanard

Executing Cross Domain POST Using jQuery and ASP.NET Web API

Challenge

Many of us find ourselves developing and supporting basic HTML websites without the ability to do much, if any, server side programming on the hosting domain. One reoccurring requirement I see is to provide the user the ability to submit form information to a web service which could be used for simple contact, email or event sign-up processing. 

The problem with executing this seemingly trivial task is the inability to POST data from a form on one domain to a web service residing on another domain. This is for good reason. Web browsers by default, do not allow XMLHttpRequest (Ajax) requests to be made from one domain to another. This is to prevent cross-site request forgery which can occur when a malicious website causes a user’s browser to perform an unwanted action on a trusted site for which the user is currently authenticated.

There are however, valid reasons to allow the use of this cross domain functionality which has led to the development of the Cross-Origin Resource Sharing (CORS) specification from the World Wide Web Consortium (W3C). This specification allows the server to process POST requests from the client based on the use of custom HTTP headers, as well as the browsers native ability to support the CORS standard. As of this writing, CORS is fully supported in the most current versions of Chrome, Firefox and Opera. CORS is partially supported in IE8 and above via the XDomainRequest object.

Objective

My goal here was to build a simple web service using the new ASP.NET Web API that would receive and process contact information submitted from multiple websites. Each website would have a simple form containing Name, Email Address and a general comment type field. The user would fill out and submit the form which will POST to an ASP.NET Web API. The service would determine which domain the request came from and process it accordingly (logging to database, email response or forward, etc.).

Solution

To accomplish this task, we’ll need to employ the Cross-Origin Resource Sharing Specification. I found a great article by Carlos Figueira describing in detail how you can overcome this cross domain challenge by using a custom MessageHandler in our WebAPI to add the CORS required HTTP Headers to the request. I’ve also added my own twists on his solution and created a CrossDomainDemo application to demonstrate this functionality. This demo application is a solution containing two projects:

  1. WebAPIApp is the application containing the Web API Controller which is called to process the form data posted from the client html site.
  2. SimpleWebApp is the html web client from which the POST is executed.

Here are the basic steps involved in creating this solution.

SERVER SIDE

Build the CORS MessageHandler

I’ve used Carlos Figueira’s example to create the CorsHandler class. Each HTTP request is passed through a series of message handlers. The handler will then use the routing table to route the request to a Web API controller. Our CorsHandler will add the required headers which will enable the controller to process the cross-domain request successfully.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Net.Http;
using System.Threading.Tasks;
using System.Threading;
using System.Net;

namespace WebAPIApp.Handlers
{
    public class CorsHandler : DelegatingHandler
    {
        const string Origin = "Origin";
        const string AccessControlRequestMethod = "Access-Control-Request-Method";
        const string AccessControlRequestHeaders = "Access-Control-Request-Headers";
        const string AccessControlAllowOrigin = "Access-Control-Allow-Origin";
        const string AccessControlAllowMethods = "Access-Control-Allow-Methods";
        const string AccessControlAllowHeaders = "Access-Control-Allow-Headers";

        protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            bool isCorsRequest = request.Headers.Contains(Origin);
            bool isPreflightRequest = request.Method == HttpMethod.Options;
            if (isCorsRequest)
            {
                if (isPreflightRequest)
                {
                    HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
                    response.Headers.Add(AccessControlAllowOrigin, request.Headers.GetValues(Origin).First());

                    string accessControlRequestMethod = request.Headers.GetValues(AccessControlRequestMethod).FirstOrDefault();
                    if (accessControlRequestMethod != null)
                    {
                        response.Headers.Add(AccessControlAllowMethods, accessControlRequestMethod);
                    }

                    string requestedHeaders = string.Join(", ", request.Headers.GetValues(AccessControlRequestHeaders));
                    if (!string.IsNullOrEmpty(requestedHeaders))
                    {
                        response.Headers.Add(AccessControlAllowHeaders, requestedHeaders);
                    }

                    TaskCompletionSource tcs = new TaskCompletionSource();
                    tcs.SetResult(response);
                    return tcs.Task;
                }
                else
                {
                    return base.SendAsync(request, cancellationToken).ContinueWith(t =>
                    {
                        HttpResponseMessage resp = t.Result;
                        resp.Headers.Add(AccessControlAllowOrigin, request.Headers.GetValues(Origin).First());
                        return resp;
                    });
                }
            }
            else
            {
                return base.SendAsync(request, cancellationToken);
            }
        }
    }
} 

Register the new MessageHandler

Add the new CorsHandler to our list of message handlers from the Application_Start method in Global.asax

        
       protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            // Use LocalDB for Entity Framework by default
            Database.DefaultConnectionFactory = new SqlConnectionFactory("Data Source=(localdb)\v11.0; Integrated Security=True; MultipleActiveResultSets=True");

            RegisterGlobalFilters(GlobalFilters.Filters);
            RegisterRoutes(RouteTable.Routes);

            BundleTable.Bundles.RegisterTemplateBundles();
            GlobalConfiguration.Configuration.MessageHandlers.Add(new CorsHandler());
        }

Build the Model

Create a Contact class containing the 3 basic data elements passed in from the form.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace WebAPIApp.Models
{
    public class Contact
    {
        public string Name { get; set; }
        public string Email { get; set; }
        public string Message { get; set; }
    }
}

Build an API Controller with Post Method

[HttpPost]
public HttpResponseMessage Post(Contact contact)
{
    // Process the Form data
    // contact.Name, contact.Email and contact.Message

    // Send the client an HTML message indicating the status of processing the Form
    string responseMessageHTML = ('"Thank You! Thanks for contacting XYZ Company. Someone from our marketing team will be contacting '" + contact.Name + '", at '" + contact.Email);

    // Build an HTTPResponseMessage and return to client
    HttpResponseMessage responseMessage = new HttpResponseMessage();
    responseMessage.Content = new StringContent(responseMessageHTML);
    responseMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("text/html");
    return responseMessage;
}

CLIENT SIDE

Add the web form to your html page

Add the jQuery AJAX call

$("#submit").click(function () {

    if ($("#contact-form").valid()) {
        var formData = $('#contact-form').serialize();
        $.support.cors = true;
        $.ajax({
            url: "http://apidomain/api/Contactform/Post",
            type: "POST",
            crossDomain: true,
            data: formData,
            dataType: "html",
            success: function (result) {
                $('#contactForm').html(result);
            },
            error: function (jqXHR, tranStatus, errorThrown) {
                $('#contactForm').html('"POST Error! Browser may not support Cross Origin Resource Sharing ');
        });
    }
});

Summary

Using these basic steps outlined above, I’ve now successfully built and deployed a single web service which processes form data posted from multiple html sites.

It’s a simple way to provide extended functionality when you don’t have access to server side programming on the hosting site’s domain or when you want to use a single web service to process and manage this common form data posted from multiple sites.

For more information I would highly recommend Carlos Figueira’s article and checkout the simple CrossDomainDemo project I’ve built and published over on Github.

Solving SQL Server Management Studio Connection Errors: 64 and 10054

I recently encountered an interesting problem when connecting SQL Server Management Studio client to a remote Windows Server 2008 R2 database server. When connecting using Windows Authentication, I received the following error message:

After some investigation, I discovered several potential causes but honed in on one in particular relating to kerberos. I found that there can be connection issues using Windows Authentication when the user belongs to ‘too many’ Active Directory groups.

Turns out the kerberos token (ticket to communicate) can actually become too big as a result of membership in a large number of AD groups. The solution to this problem is to increase the token size (default is 12000 bytes). Due to HTTP’s base64 encoding of authentication tokens limit, it’s recommended that the token size also not exceed 48000 bytes.

A simple fix for this issue is to set, or add, a MaxTokenSize Registry Key on the server offending database server. 

  1. Locate or create the following key in the registry:
    System\CurrentControlSet\Control\Lsa\Kerberos\Parameters
  2. Add the following registry value:
    Name: MaxTokenSize
    Data type: REG_DWORD
    Radix: Decimal
    Value: 48000
  3. Reboot server

I discovered this error on multiple database servers throwing both Error 64 and Error 10054. The above solution fixed all issues on all servers.

 

Changing Menu Case in Visual Studio 2012

EMBRACE THE CASE?

Much has been made of the menu styling for the Visual Studio 2012 IDE being in ALL CAPS. Although I am not a big fan of the all caps menu, I do think some tend to go a bit overboard with the intense level of criticism of this UI design decision.

Nevertheless, if you’re not one who likes your IDE menu SHOUTING at you all day, there is a simple resolution to all of this. Install the VSCommands for Visual Studio 2012 extension from Squared Infinity.

Procedure

1) From the VS2012 menu, select TOOLS —> Extensions and Updates…

2) Go the the Visual Studio Gallery and search for ‘vscommands’.

3) Download and install the extension, then restart VS2012.

4) From the VS2012 menu, select TOOLS —> Options

5) The VSCommands options should now appear in your list

6) Click the Open Configuration button

7) Under IDE Enhancements, select Main Menu.

8) Change Main Menu letter case to Sentence Case and Save.

Result

And there you have it:

The menu should now appear in sentence case, as normal.

There are several other interesting configuration options you may want to check out as well, so download the VSCommands for Visual Studio 2012 extensions today.