Tim's Blog
Another code blog
-
Using ASP.NET MVC and Shibboleth Authentication
If you’re using Shibboleth as your resource authentication method, there’s a few things you need to do in order to use it effectively with ASP.NET MVC.
The first thing to do is to configure routing correctly. Shibboleth uses a special route against your website that is intercepted by the ISAPI filter that is part of the Shibboleth install on your web server. However, in integrated pipeline mode, your application will receive these Shibboleth requests and won’t know what to do with them and issue a 404 not found. The solution is to ignore the routes that Shibboleth uses and let them pass through to the Shibboleth system:
routes.IgnoreRoute("Shibboleth.sso/{*pathInfo}");
The ‘routes’ variable is a RouteCollection type passed to your RegisterRoutes() method in the RouteConfig.cs file of an MVC 4 project. This ensures that the Shibboleth routes are never processed by your application.
The second thing is to turn off all authentication for your web site. Since Shibboleth’s single sign-on is going to handle protecting your resources, you will not need to configure any authentication in your web.config or in IIS. Instead, you will configure it with your shibboleth2.xml file.
Categories: ASP.NET MVC
-
RavenDB Survival Tip #1: Indexing Gotcha
This series of posts is going to cover some things I’ve learned using RavenDB, a document database solution for .NET.
I was working on a class (a User class) where I needed to add a property to the class that didn’t exist in the original version of the application. So, I went and added it to the C# class (User) and I also updated an Index in RavenDB to use this new property so that I could filter by it in a query. It built and when I deployed I could see that Raven was updating the index and did so in a timely manner.
I then went and wrote some code to filter by that new property in a query. The property I had added was a boolean type and so all of the models that I had in the database (some 50,000+ User documents) would just get the default value of false for this new property. However, when I went to run this query, no documents were returned. What happened was that when you add a new property to a model, it isn’t going to go and update all of your existing documents with a property value even if a default is implied or provided (as is the case with a bool being false by default). There is simply no property in the JSON store in the User document that matches this property I was querying by.
The solution is that when you do something like that, you need to run a Patch in RavenDB. This will ensure that all of your documents get synced to the new additional property you have made. Perhaps if this was some integer or string property that had to be set to something specific I would have picked up on the problem before even attempting the query.
Categories: RavenDB
-
First Impressions on Durandal
I’ve been working with Durandaljs for a few weeks now. It’s an open-source single page application (SPA) framework written to use technologies that you might already know. So far, I’m really impressed and I’ve enjoyed working with it. Since I already do a fair bit of Knockout development, I like the fact that Durandal uses KO and several other things I know such as Requirejs.
I’ve made SPA-like parts to web apps before but I always found it hard to manage all of the bits and pieces that go together to make an app. For example, modal dialogs were typically a pain to implement. In Durandal, it basically handles the management of the modal’s appearance and how its view is retrieved and dynamically bound to the view model that you create. The development of a Durandal app basically goes like this:
- Break up your app into views with complementary view models (the views are HTML files with KO bindings and the view models are just JavaScript classes or object literals). The view model is written as one RequireJS module. The modularity of your application is one of the great strengths of this framework and really is more of a RequireJS thing than a Durandal thing. But Durandal does tie all of it together so think of it as a coordinator between libraries rather than its own implementation.
- You then setup your navigation and routing. Currently, Durandal is route-engine agnostic and supports a plug-in model to support routing. It ships with a SammyJS-based routing engine which is pretty easy to use. This is one area that I personally lacked some knowledge in, but SammyJS is pretty easy to learn to do most common tasks.
- Once you get views and view models together, you can move on to advanced stuff like view composition and eventing in Durandal.
I think one of the biggest strengths of Durandal is that it has a very powerful view composition system. This basically allows you to find views, merge them with a view model and inject them into your DOM with ease. You can use composition to swap out or render sub-sections of a page (such as a tab content area) or you can even do awesome things like recursive composition to build tree views or menus with sub-menu capabilities.
If you are a Pluralsight member, I suggest checking out John Papa’s course on SPAs where he talks about Durandal (and many other aspects of SPAs).
The only bad part so far for me is that I wish I had known about this framework six months ago to use it in my current project. I am currently thinking of refactoring to using Durandal.
Categories: JavaScript
-
JavaScript Libraries and Frameworks
I’ve been doing a lot of client-side development lately. Our web browsers are becoming more capable with each new version. Browser inconsistencies are disappearing behind standards, polyfills, and abstractions in good JavaScript libraries. I thought that in this post I would list all of the JavaScript libraries that I use or have used and found to be quite good. These libraries are extensible, documented, and are well-tested. They have worked for me in professional and personal projects. I will probably be adding to this list over time:
- Durandal.js – a SPA (single page application framework) that adds powerful view composition. It uses what you might already know (like Knockout.js, SammyJS, and RequireJS). If you are building a SPA and aren’t using a formal framework like AngularJS, you should check this out.
- Knockout.js – an MVVM (model-view-viewmodel) library for the web. This adds data-binding capabilities to your app so your UI stays in sync with your JavaScript models through two-way data binding. Also known as KO.
- KoLite – this is small collection of KO extensions that I find useful. In particular, I like the “command” binding handling that adds a way to add XAML like ICommand-ness to KO.
- RequireJS – I use this in conjunction with Durandal as it is a requirement of Durandal. It allows you to organize your code into “modules” – a programming feature lacking from JS.
- SammyJS – this is a client-side routing engine that is a default routing plugin for Durandal.
- jQuery and jQuery UI – everybody knows these two.
- toastr – a small and effective notification library that “toasts” a message to the user. It is so simple and looks very beautiful too.
- accounting.js – this small library helps with parsing and formatting monetary amounts in JS. I use this a lot with professional projects because most of the work I do involves capturing and displaying monetary amounts (as do a great deal of applications).
- mustache.js – a small string template system for when you want to generate HTML using string templates (as opposed to Knockout’s or Angular’s DOM-based templating). I use this only when I need to work with a third-party control that allows custom templating but templates must be delivered as strings. In general, DOM templates tend to be better in my opinion.
- date.format.js – a small date/time parsing and formatting library that works quite well. I also hear that moment.js is really good, but have not used it. JS’s support for Dates is pretty bad so these libraries help ease the pain, considerably.
Most of these libraries have packages on NuGet. Some are on npm too.
Categories: JavaScript
-
Expectations
On two occasions I have been asked, 'Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out?' I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question.
-Charles Babbage
Categories: Musings
-
Creating a Type Safe AppSettings Accessor for ASP.NET
Many times I place settings in the <appSettings> section of the web.config file for an ASP.NET application. These settings could be things like the title of the application, a URL for support, or maybe e-mail settings if your application sends out email. Retrieving this information involves the use of the ConfigurationManager class in the System.Configuration namespace.
One technique that I like to use is to wrap each of the settings into a type-safe read-only property accessor that is a static member on a static helper class. The type of the property is the correct type that we expect in order to use it in code. For example, if you have a on/off switch in your settings you probably want the value of the setting to be a bool. Many times your settings are just strings, which are the easiest to parse but maybe you also want to ensure that the string is actually there and not null.
The following code snippet shows an implementation of a static helper class that does all these things:
public static class AppSettings { /// <summary> /// Gets the application's title. /// </summary> public static string ApplicationTitle { get { return Retrieve("Application.Title"); } } private static string Retrieve(string key, bool required = true) { string value = ConfigurationManager.AppSettings[key]; if (required && string.IsNullOrEmpty(value)) throw new InvalidOperationException( string.Format("{0} is missing but is required to be defined in appSettings.", key)); return value; } private static bool RetrieveBool(string key) { string s = Retrieve(key); bool result = false; if (!bool.TryParse(s, out result)) throw new InvalidOperationException( string.Format("{0} is missing or has an invalid setting. " + "'true' or 'false' are acceptable values for this setting.", key)); return result; } private static int RetrieveInt(string key) { string s = Retrieve(key); int result = 0; if (!int.TryParse(s, out result)) throw new InvalidOperationException( string.Format("{0} is missing or has an invalid setting. " + "An integer value was expected.", key)); return result; } private static DateTime RetrieveDateTime(string key) { string s = Retrieve(key); DateTime result; if (!DateTime.TryParse(s, out result)) { throw new InvalidOperationException( string.Format("{0} is missing or has an invalid setting. A valid date/time format was expected.", key)); } return result; } private static T RetrieveEnum<T>(string key) where T : struct { T result = default(T); if (!Enum.TryParse<T>(Retrieve(key), out result)) throw new InvalidOperationException(string.Format("{0} is not a valid enumeration value.", key)); return result; } }
You can see that there are several private helpers that all Retrieve a particular data type given a key name. There’s one for strings, bools, ints, date/times, and even enums. If the wrong data type or a missing value is detected, an exception is thrown so you can catch mis-configured apps easily.
To use this class, you’d simply place in your code like so (in a Razor view, but it could be anywhere):
<h1 class='title'>@AppSettings.ApplicationTitle</h1>
Categories: ASP.NET MVC
-
ASP.NET MVC Action Filter Example: Ensuring an Entity Exists
Many times in ASP.NET MVC action methods, you are passing in a key (such as an id parameter) that you will use to lookup an entity in your database with. Typically this lookup is done with an ORM such as NHibernate or Entity Framework or it could be RavenDB or something else. The point is, you spend a lot of time taking the key parameter and looking it up in your database and checking to see if the database returned the correct object.
Since this is such a common task, we should make an ActionFilter that can do the check for us and ensure that the entity really exists in the database. This example uses RavenDB to access the database, but it could be replaced with any code that you use for your particular implementation. It uses a domain existing of an Order type that represents a customer’s order at a store:
public class OrderExistsAttribute : ActionFilterAttribute { protected string parameterName = "id"; protected Order order; public override void OnActionExecuting(ActionExecutingContext filterContext) { base.OnActionExecuting(filterContext); if (!filterContext.ActionParameters.ContainsKey(ParameterName)) { throw new InvalidOperationException("Missing parameter: " + ParameterName); } string id = filterContext.ActionParameters[ParameterName] as string; if (id == null) { throw new ArgumentNullException("id is required."); } order = RavenDb.CurrentSession.Load<Order>(id); if (order == null) { throw new Exception("Specified Order does not exist."); } } /// <summary> /// Gets/sets the parameter name that is used to identify the parameter that will act /// as an order key. Default is 'id'. /// </summary> public string ParameterName { get { return parameterName; } set { parameterName = value; } } }
The RavenDb class is just a helper that I use that puts the current request’s IDocumentSession in a static accessor called CurrentSession (this in turn reads it out of the HttpContext.Items collection to get a thread-local session for that particular request).
You can set the ParameterName property to the name of the parameter in your action method. Typically this is just ‘id’ so that is the default that is used.
Here’s how to use this attribute on an action method:
[OrderExists] public ActionResult Index(string id) { // you are guaranteed at this point that the // order specified by id actually exists }
If you were using NHibernate or RavenDB for this (as I was), you can call the Load() method of the database session to retrieve the Order instance by that id and since it was already loaded by the action filter, it will be instantly returned by the session cache.
You could also derive from this class to create new scenarios such as not only checking for the existence of the Order but also that it is in a particular status/state. For example, if we have a Save() action method, we probably don’t want to allow saving an order that has already completed. Once the Order is loaded, you can do any logic you wish on it. Security or access to the Order could be enforced in this attribute too.
The bottom line here is that the attribute can be used on any action method and saves us a lot of effort by not having to repeat ourselves.
Categories: ASP.NET MVC
-
Setting Up RavenDB as IIS Website
Over the past year, I’ve gotten to know RavenDB which is an excellent NoSQL document database product from Hibernating Rhinos. It’s an open source project built in .NET that fits in well with .NET technologies like LINQ. I love the process of taking my domain objects and simply dumping them into a database and being able to retrieve them with very little effort. The programming experience is excellent.
But since this is new to most people (and organizations), getting started setting up a RavenDB server to connect to can be a little challenging getting everything right, especially if you don’t have the infrastructure support of IIS experts and/or DBAs. This post shows step-by-step instructions on how to set up RavenDB on an IIS 7.x system. These instructions have worked well for me and make the following assumptions:
- You want to use IIS to host RavenDB (you can also embed it or use Windows Services – I won’t talk about that right now).
- You want to use HTTPS as your transport protocol.
- You want to use integrated Windows security to authorize users to access your DB.
Here’s what you should do to achieve this (this is for version 2.0 of RavenDB, build 2261 or higher):
- Ensure you have the following software installed on your server:
- IIS 7.5
- .NET Framework 4.0 – it might not be installed if you are on Windows Server 2008 (it shipped with 3.5 SP1)
- Get the .zip of the latest stable RavenDB build (or an unstable build if you wish). Unzip to a directory on the server. The sub-directory /Web is where the web site will run from. I put this on same disk as the Raven Data directory.
- Install Windows Authentication service.
- Server Manager –> Roles –> Web Server, then click on Add Role Services link.
- Check “Windows Authentication” and then continue.
- Setup proper DNS to point to your server’s IP address (this is probably already done).
- If you are behind a corporate firewall, have them open port 8080 (or whatever port you are using). You probably want it open to your entire subnet including a VPN IP range if you have that.
- Obtain and install an SSL certificate for the domain for the machine.
- Create a new application pool for the web site.
- Set it to use .NET 4.0 and Integrated Pipeline.
- Give it a name such as “RavenAppPool”
- Disable overlapped recycle on the app pool. Raven doesn’t want multiple instances attempting to write to its files.
- On the app pool you just created –> Advanced Settings –> Disable Overlapped Recycle set to True.
- Set the app pool so that IIS never shuts it down. You want your DB up at all times.
- The setting for this can’t be applied in the GUI for IIS 7.5.
- Find C:\Windows\System32\inetsrv\config\applicationHost.config and open it. Make a backup copy.
- Find the app pool entry for the app pool you created for Raven.
- Add the attribute startMode=”AlwaysRunning” to it and save the file.
- Create a new website or set Default Web Site.
- Right click Sites under Web Server and choose Add New Site.
- Set site name to “RavenDB” or whatever you want.
- Set the app pool to the RavenAppPool you created in step 6.
- Set the physical path to the /Web folder of the RavenDB install.
- Set HTTP binding if not already.
- Uncheck start web site immediately.
- Click OK.
- Create a RavenDB user group. This is a Windows group that represents the users that can login to RavenDB.
- Server Manager –> Configuration –> Local Users and Groups…
- Right-click on Groups folder, select New Group…
- Give group a name and description ("RavenDB”)
- Click OK.
- If you are connecting with an application, create a new user now for the proxy account that will use this database. This user should belong to the \RavenDB group you just created. You should also create any DBA or developer accounts now and give them this group as well.
- Turn on Require SSL for the website.
- Configure where Indexes and Data directories are. You should have two different disks for best parallel I/O – one for the Indexes and one for the Data.
- Open the web.config file in the /Web folder of the RavenDB install.
- In <appSettings>, add a setting for data path - <add key=”Raven/DataDir” value=”[your path here]” />
- Also add a setting for indexes - <add key=”Raven/IndexStoragePath” value=”[your path here]” />
- Start the web site.
- In a web browser with Silverlight plugin installed, navigate to https://[yoursitedomain]:[port]/ to make sure the Management Studio opens. If it works, you know that RavenDB started, created the default database and that your website is serving data correctly over HTTPS and your firewall rules are correct.
- Turn on Windows Authentication
- Click on RavenDB web site just created.
- Select Authentication from IIS categories.
- Click on Windows Authentication from the list and click Enable link on the actions panel.
- Turn off anonymous access in Raven: open its web.config file and add the following setting to the <appSettings> section - <add key=”Raven/AnonymousAccess” value=”None” />
- Configure Raven to only allow that specific Windows group you created earlier.
- In Raven Management studio, click on the databases link at the top right.
- Click on the <system> database button on the right. It will warn you about modifying the system database, just click OK.
- Now click the “gear” icon at the top next to the <system> database name to open the settings for the db.
- Select Windows Authentication from the left pane.
- On the Groups tab, click Add Group Settings.
- In the Name text box, add the name of your windows group preceded by a slash (“\RavenDB”).
- Check Enabled.
- Add the specific databases to the group (such as the default database or a specific tenant you may have created).
- Click Save Changes button to complete.
- Open Management Studio again. You should be prompted by your browser for a username and password.
These instructions will create you a running RavenDB instance in IIS that has HTTPS transport security, Windows security, and does not allow anonymous access. It also configured where indexes and data are written to and made sure IIS doesn’t recycle your process or start two of them at once.
The official documentation can also help you out if you are having any trouble: http://ravendb.net/docs/2.0/server/deployment/as-iis-application
Categories: RavenDB
-
Alternative Approach to Extenders in Knockout.js
ko.observable.fn.booleanValue = function () { var formattedValue = ko.computed({ read: function () { if (this() === true) return "True"; else if (this() === false) return "False"; }, write: function (newValue) { if (newValue) { if (newValue === "False") this(false); else if (newValue === "True") this(true); } } }, this); this.formattedValue = formattedValue; this.formattedValue(this()); return this; };
This code is an alternative to the previous post of how to do an extender for a Boolean value. It works exactly like the extender, but instead attaches functionality to the .fn extension point of ko.observable. To use this, do the following:
this.wantsFriesWithThat = ko.observable(true).booleanValue();
This is a bit cleaner than using the extend() method. If we wanted, we could send in parameters to further configure how this extension works, we could simply pass them to the booleanValue() function. If you want to add another extender, you would simply chain another onto the call to booleanValue(). This is why the function returns this because the this in the function refers to the observable itself.Categories: Uncategorized
-
Building a Knockout.js Extender for Boolean Values
Many times in my UI, I have a pair of radio buttons that represent two Boolean values such as a question that has a Yes/No answer that the user must make. By default, a KO observable bound to these radio buttons will be set to the value of the input element that represents the radio button. For these types of situations, this is not what I want. What I really want to do is have the underlying value of the observable stay as a Boolean value (true/false) rather than as a string. I want this because this underlying value is what I want to POST to the server. Even though radio buttons deal in string values, they are actually modifying a Boolean value in this case.
What we need is a Knockout.js extender that adds new functionality to these specific observables so that the underlying Boolean value can be preserved. Here’s the code:
ko.extenders["booleanValue"] = function (target) { target.formattedValue = ko.computed({ read: function () { if (target() === true) return "True"; else if (target() === false) return "False"; }, write: function (newValue) { if (newValue) { if (newValue === "False") target(false); else if (newValue === "True") target(true); } } }); target.formattedValue(target()); return target; };
This code uses a technique that I really like. It attaches a KO computed observable as a property of the actual observable (in this case, target). This sub-observable is called formattedValue and this is what you actually bind to in your HTML data-bind attribute. This technique is cool because this observable is hidden away from ko.toJS() and other functions that don’t see it. When you serialize your observable back to the raw data values you want to POST, it melts away.
Since the formattedValue computed is a writeable computed, you can read and write to it. The read function will test the underlying observable (remember this is a true JS Boolean value). It will then convert this to a string value (by convention, “True” or “False”). The write function will do the opposite: it will test the incoming string value (this is from the HTML control), and will convert to the proper Boolean value on the actual observable.
To use the extender on your model, you’d do something like the following:
function Order() { this.wantsFries= ko.observable(false).extend({ booleanValue: null }); }
The answer property now has a sub-observable (formattedValue) that can be bound to a series of radio buttons to get the correct behavior:
<span>Do you want fries with that?</span> <label> <input type="radio" name="question" value="True" data-bind="value: wantsFries.formattedValue" /> Yes </label> <label> <input type="radio" name="question" value="False" data-bind="value: wantsFries.formattedValue" /> No </label>
When the user clicks one of the radio buttons, the correct true/false value will be sent into the underlying observable and is ready to be unwrapped and sent to your server. The main point of this example, I believe, is the power in these sub-observables. I’ve found this technique to be very clean and useful.
Categories: JavaScript
Tags: Knockoutjs