Windows 8 IIS Express with Windows Authentication Prompts for Credentials

If you’re seeing a credentials prompt every time you launch a local IIS or IIS Express web application that requires Windows Authentication, you’ll likely grow as tired of typing in your password as I was. To add to the annoyance, the Remember my credentials checkbox doesn’t work (nothing is saved).

image

The setup:

  • Windows 8
  • Visual Studio 2012, .NET 4.5,
  • ASP.NET MVC web application
  • Non domain-joined computer (it’s on my home network)
  • Using a Microsoft account (FKA Live ID) as the local account
  • Using IIS Express/IIS
  • Windows Authentication Enabled
  • Anonymous Logon Disabled
<system.webServer>
    <security>
        <authentication>
            <windowsAuthentication enabled="true" />
            <anonymousAuthentication enabled="false" />
        </authentication>
    </security>
</system.webServer>

While there are a few proposed solutions, this is the only one that worked for me so far.

  1. Start Internet Explorer
  2. Click the settings Menu
  3. Select Internet options
  4. Click the Security tab
  5. Select Local intranet
  6. Click Sites
  7. Click Advanced
  8. Add http://localhost to the Local intranet zone
  9. Close.
  10. Verify it’s now working.

image

image

image

image

image

Done.

Alternatives welcomed. :)

Knockout binding for JavaScript route fixup

Part one.

After the first round, I felt compelled to KnockOut the code a bit more. I’d mentioned I wasn’t pleased with the code exactly. It needed some refactoring.

So, I’ve created a new Knockout binding handler. This binding handler replaces  named parameters with a model’s properties in a path.

For example, given this object:

Property Name Value
id A123
first_name Aaron
state WI

The following paths would be converted thusly:

Original Replaced
/person/{id} /person/A123
/person/{state}/{id} /person/WI/A123

You get the idea. Here’s the JavaScript code:

ko.bindingHandlers['route'] = {
    // Examples: 
    //      <a data-bind="route: {model: $data, url: 'person_details', attr: 'href' }" >
    // or, you can shortcut the syntax to default to the currently bound object and just pass 
    // the url or the route name as a string directly
    //      <a data-bind="route: 'person_details' }" >
    update: function (element, valueAccessor, allBindingsAccessor, $data) {
        var valueUnwrapped = ko.utils.unwrapObservable(valueAccessor());
        var options = ko.bindingHandlers.route.options || {};

        // look for the model property 
        var model = ko.utils.unwrapObservable(valueUnwrapped['model']);
        if (typeof model !== 'object') {

            model = ko.utils.unwrapObservable($data);
            if (typeof model === 'undefined' || model === null) {
                throw new Error('set route model to object (or nothing bound?)');
            }
        }

        // look for the url property first
        var url = ko.utils.unwrapObservable(valueUnwrapped['url']);
        // validate we've got something as a url (might be a name, might be a full url)        
        if (typeof url !== 'string' || url == "") {
            url = valueUnwrapped;
            if (typeof url !== 'string' || url == "") {
                throw new Error("set route url property to route name or url directly");
            }
        }

        // is it on the keyed collection?
        var map = options.map;
        if (typeof map !== 'undefined' && map !== null) {
            if (map.hasOwnProperty(url)) {
                url = map[url];
            }
        }
        // check for a routing function as well
        var fn = options.routeNameToUrl;
        if (typeof fn === 'function') { url = fn.call(null, url); }
        // did we get something meaningful?
        if (url !== null && url !== '' && url.length > 0) {
            url = ko.bindingHandlers.route.buildUrl(url, model);            
        }
        // the url might need some fixin after a routing, anything goes here (might just be a default)
        fn = options.fixUrl;
        if (typeof fn === 'function') { url = fn.call(null, url); }
        element.setAttribute(ko.utils.unwrapObservable(valueUnwrapped['attr']) || 'href', url);
    },    

    // given a model, this function replaces named parameters in a simple string 
    // with values from the model
    //     /path/to/some/{id}/{category}
    // with object { 'id' : 'abc', 'category' : 'cars' }
    // becomes
    //     /path/to/some/abc/cars
    buildUrl : function(url, model) {
        // unfixed if there's not a thing
        if (typeof model === 'undefined' || model === null) { return url; }

        var propValue;
        for (var propName in model) {                
            if (model.hasOwnProperty(propName)) {
                propValue = model[propName];
                if (ko) { propValue = ko.utils.unwrapObservable(propValue); }

                if (typeof propValue === 'undefined' || propValue === null) {
                    propValue = "";
                } else {
                    propValue = propValue.toString();
                }
                url = url.replace('{' + propName.toLowerCase() + '}', propValue);
            }
        }
        return url;
    },

    options: {
        // ** convert a route name to a url through whatever means you'd like
        // routeNameToUrl : function(routeName) { return url; } 

        // ** anything you want, called after routeNameToUrl, might add a virtual directory
        // ** for example
        // fixUrl: function(url) { return url;  }  

        // ** A map route names to URLs **
        // all other functions are called if set (to possibly override this)
        // this is not required if you use one of the other functions
        // map : { 'a_route_name' : '/path/to/something/{id}/{action}' }        
    }
};

In another JavaScript file, I did initialize some of the options:

ko.bindingHandlers.route.options.routeNameToUrl = getRoute;
ko.bindingHandlers.route.options.fixUrl = app_url;

The getRoute function just maps a route name to a path, and the app_url prepends the virtual directory to the path as needed.

Here it is in use:

<div data-bind="foreach: data.persons">
    <h3 class="title" data-bind="text: Title"></h3>
    <div>
        <a data-bind="route: { model: $data, url: 'person_details', attr: 'href' } ">Details2</a>
        <a data-bind="route: '/data/details/{id}/{title}' ">Details</a>
        <a data-bind="route: 'person_details' ">Details</a>
    </div>
</div>

You’ll probably like the new way better syntactically at least compared to the old way. A route binding requires one input when used in it’s most basic form:

  • url = the URL or route name to use as the template for the replacement. It should contain (or later resolve to) curly-braced enclosed property name keys which will be substituted by values from the model. The value of the property could be either a route name (see options below) or a path.

When using just the basic form you can use the shortened syntax:

<a data-bind="route: 'research_details' ">Details</a>

This handily binds to the current object (via the bindingContext.$data property of the bindingHandler update function call, which is also the fourth parameter, which I’ve renamed to $data rather than the typical viewModel). So, you won’t need to necessarily (explicitly) set the model for the binding.

If you need a a bit more control, you can change the syntax and get access to a few other options (including direct access to the model you want to bind to if the current item isn’t directly what you want to use).

  • model = this is the object that contains the properties and values to be used as replacements within the url
  • attr (optional) = the name of the attribute to set the generated url into. Defaults to href if not set.

There are a few global options you can control as well:

  • routeNameToUrl = (function)(routeName) optionally, given a route name, should return the path (or the original value). Here you can do a lookup of routeName to path.
  • map = {object} the object properties should be route names and set equal to the path. this optional lookup is performed before the routeNameToUrl function is called.
  • fixUrl = (function)(url) do anything here. this is called after the mapping and routeNameToUrl is optionally called. I use this to correct javascript Ajax request paths by appending the application virtual directory

(Thanks to Ryan for the suggestion to use the $data on the bindingContext, and then again for the nudge to just use the 4th parameter. Smile )

Return of syntax highlighting and code completion for KnockoutJS in VS2010 (when using Razor)

OK, admittedly, this is a workaround for an issue where the syntax of jQuery Templates (used by KnockoutJS) doesn’t lend itself to the most pleasant editing experience in Visual Studio, but eh.

This was inspired after talking with Ryan a bit and seeing a recent post on his new web site. Here’s what I came up with.

Following a similar pattern to the BeginForm Helper, I created a “Template” helper. It’s simple to use as the code below demonstrates (the example is taken from the KnockoutJS web site).

<div data-bind='template: "personTemplate"'> </div>

@using (Html.Template("personTemplate"))
{ <text>    
    ${ name } is ${ age } years old
    <button data-bind='click: makeOlder'>Make older</button>
</text> }
     
<script type='text/javascript'>
    var viewModel = {
        name: ko.observable('Bert'),
        age: ko.observable(78),
        makeOlder: function () {
            this.age(this.age() + 1);
        }
    };
    ko.applyBindings(viewModel);
</script>

Sometimes, the Razor compiler/engine is confused by the template syntax however, so to work around that, you’ll need to add the <text>…</text> block to prevent the template syntax from being parsed as Razor syntax. The example above shouldn’t require it. The one that causes problems I’ve found mostly right now is the conditional {{ if }} block which apparently looks like Razor/C# code, and fails. The <text> tag syntax isn’t tragic. The most annoying part is that it highlights as bright yellow.

The Template Helper emits the start and end <script> tags appropriately. There’s an optional second parameter that allows the developer to override the default of the type being text/html.

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

namespace TestMVC.Web
{
    public static class MvcExtensions
    {
        /// <summary>
        /// Automatically generates a script block, useful for non-typical script
        /// tags that have HTML content inside (like those in jquery templates for example)
        /// Always use this within using statement as Dispose must be called to properly close
        /// the script tag.
        /// </summary>
        /// <param name="helper">Html Helper object</param>
        /// <param name="id">The ID for the generated script tag.</param>
        /// <returns>TemplateBlock object which must be disposed to properly emit
        /// the necessary script tags.</returns>
        public static TemplateBlock Template(this HtmlHelper helper, string id)
        {
            return Template(helper, id, "");
        }

        /// <summary>
        /// Automatically generates a script block, useful for non-typical script
        /// tags that have HTML content inside (like those in jquery templates for example)
        /// Always use this within using statement as Dispose must be called to properly close
        /// the script tag.
        /// </summary>
        /// <param name="helper">Html Helper object</param>
        /// <param name="id">The ID for the generated script tag.</param>
        /// <param name="type">Defaults to text/html, but may be overriden by setting
        /// this parameter.</param>
        /// <returns>TemplateBlock object which must be disposed to properly emit
        /// the necessary script tags.</returns>
        public static TemplateBlock Template(this HtmlHelper helper, string id, string type)
        {
            return new TemplateBlock(helper.ViewContext, id, type);
        }
    
    }

    public class TemplateBlock : IDisposable
    {
        private bool _disposed = false;
        public ViewContext ViewContext { get; private set; }
        
        public TemplateBlock(ViewContext context, string id, string type)
        {
            this.ViewContext = context;
            type = string.IsNullOrWhiteSpace(type) ? "text/html" : type;
            context.Writer.Write("<script type='{0}' id='{1}'>\n", type, id);
        }

        private void Disposing(bool disposing)
        {
            if (!_disposed)
            {
                _disposed = true;
                ViewContext.Writer.Write("</script>\n");
            }
        }
        public void Dispose()
        {
            this.Disposing(true);            
        }
    }

}

Enjoy.

Derserializing ASP.NET MVC JSON formatted Date strings

Have you called an Ajax based action in MVC, only to find that the Date format is being serialized into something that isn’t entirely useful on the client?

{“result”:[{“Author”:”Aaron”,”SentAt”:”\/Date(1296824894700)\/”,”Text”:”Blah Blah”,”Id”:1}],”runAt”:”\/Date(1297031297600)\/”}

You’ll see that the Date is:

\/Date(1296824894700)\/

Alas, that’s not very friendly. For a quick translation, I added the following to jQuery’s dataFilter property so that the date would be formatted in a more human readable format. The dataFilter function is used to sanitize a response from a web server.  Here’s what I added:

$(function () {
    $.ajaxSettings.dataFilter = function (data, type) {
        if (type === 'json') {
            // convert things that look like Dates into a UTC Date string
            // and completely replace them. 
            data = data.replace(/(.*?")(\\\/Date\([0-9\-]+\)\\\/)(")/g,
                function (fullMatch, $1, $2, $3) {
                    try {
                        return $1 + new Date(parseInt($2.substr(7))).toUTCString() + $3;
                    }
                    catch (e) {}
                    // something miserable happened, just return the original string            
                    return $1 + $2 + $3;
                });
        }
        return data;
    };
});

The trick for converting the /\Date(#)\/ syntax easily was from StackOverflow. It even handles time zone info.

I added a regular expression to look for the various elements that represent a Date in Microsoft JSON serialization format. The resulting date is reformatted to a human readable string. There are 3 capturing groups that I’ve named $1, $2, and $3 which need to be preserved otherwise the JSON string is mangled beyond recognition. Those are returned concatenated to preserve the original formatting of the string.

The resulting date is translated to something like:

Fri, 4 Feb 2011 13:08:14 UTC

Of course, you could do whatever formatting you’d like.

 

Bonus

And, as a bonus, you did notice that if you’re using IE9, that the developer tools now have a network trace? Cool. (I’ll still use fiddler for many things, but this will be very handy on machines that don’t have fiddler installed).

SNAGHTML51b4c85a

Translating Controller, Action, and Route Data to a JavaScript Object in ASP.NET MVC 3

To enable a more rich JavaScript/Ajax experience on a web page, I had need of more detailed information regarding the route that resulted in the current View being displayed. I checked around a few sites, and nothing popped out as obviously awesome.

As I was putting the JavaScript in the Layout/Master page, I had few direct assumptions about the location of the View/route that was currently being executed.

Here are the two options I created this evening.

Option one is admittedly more limited, but it serves to demonstrate the basic technique:

<script type="text/javascript">
        
    var _servedFromUrl = "@Url.RouteUrl(this.ViewContext.RouteData.Values)";
    @{ 
        string action = ViewContext.RouteData.Values["action"].ToString();
        string controller = ViewContext.RouteData.Values["controller"].ToString();
    }
    var action = "@action";
    var controller = "@controller";
    
</script>

Note that the code above is contained within a <script> block, as the final destination goal is to make these values available within JavaScript in the browser.

Above, there are actually 2 different options. The first option, results in a string that could look something like this:

/Discussions/Edit/5522

It could be useful to someone. However, it wasn’t useful to me. The next step was to discretely retrieve the action and controller. As you can see, these result in two JavaScript variables, aptly named, action and controller.

var action = "Edit";
var controller = "Discussions";

In this case though, I wanted access to all the values, in a more natural JavaScript format: A JavaScript Object with named (ad-hoc) properties.

<script type="text/javascript">        
    var route = {
        @{                 
            string comma = "";
            foreach (var name in ViewContext.RouteData.Values.Keys)
            { 
                string val = ViewContext.RouteData.Values[name].ToString();
                @: @comma'@name': '@val'
                comma = ",";
            }    
        }                   
        };
</script>

The code above loops through all of the RouteData Keys, and adds each and the corresponding value to a JavaScript object instance named route.

The results:

<script type="text/javascript">
    var route = {             'id': '5522'
                 , 'action': 'Edit'
                 , 'controller': 'Discussion'
    };

</script>

Simple, with discrete values.