Access SharePoint Document Libraries from Windows Explorer

SharePoint is a great way to share documents across a team. You can upload documents, track version history, and control access via checkouts. The document libraries on the website have a few shortcomings, though. You can’t move a file, for example. Copying the file to another location is painful, too.

You can make things better by accessing the document library through Windows Explorer. It can be accessed as a UNC path. To get the UNC path, just convert the URL like so:

SharePoint document library URL UNC path
http://mysharepoint/foo/documents \\mysharepoint\foo\documents

Using this little trick, you get all of the Windows functionality you’re used to with none of the restrictions of the SharePoint website. You can rename, drag & drop, and copy/paste just like you would with any network share. Using the SharePoint site isn’t bad, but this provides a better experience.

Advertisements

Real-time Validation with Knockout

Knockout gives you a slick way to do real-time validation on your data with its built-in extenders. At first glance, it may not seem like an entirely intuitive process, but it’s actually pretty clever. When you use an extender, you’re extending the property to have additional sub-properties and behaviors. Makes sense, right?

Let’s look at a simple example: validating a date value.

We begin by creating a simple view model and UI.

var viewModel = function () {
    var self = this;
    this.dateValue = ko.observable();
};
ko.applyBindings(new viewModel());
<div>
    <input data-bind="value: dateValue" />
</div>

Now we can create our extender. We introduce a new hasError property that we’ll bind to the UI and use to show & hide validation messages. There’s a validate function that contains the validation logic. The validate method is called to perform the initial validation, and subscribe is called so that validate will be called when the value changes. Note that we also add valueUpdate: ‘afterkeydown’ to the input data-binding. This allows the validation to perform after each keystroke.

var viewModel = function () {
    var self = this;
    this.dateValue = ko.observable().extend({
        validDate: true
    });
};

ko.extenders.validDate = function (target) {
    target.hasError = ko.observable();

    function validate(value) {
        var invalid = isNaN(Date.parse(value));
        target.hasError(invalid);
    }

    validate(target());
    target.subscribe(validate);
    return target;
};

ko.applyBindings(new viewModel());
<div>
    <input data-bind="value: dateValue, valueUpdate: 'afterkeydown'" />
    <span data-bind="visible: dateValue.hasError">Invalid!</span>
</div>

That’s it for the hard stuff. All that’s left is to figure out what should be shown or hidden when the value is invalid or valid. I chose to show an alert icon and added some CSS to make the input box red.

.invalid input {
    border: 1px solid red;
}
.ui-icon {
    display: inline-block;
    vertical-align: middle;
}
<div data-bind="css: { invalid: dateValue.hasError }">
    <input data-bind="value: dateValue, valueUpdate: 'afterkeydown'" />
    <span class="ui-icon ui-icon-alert" title="Invalid value" data-bind="visible: dateValue.hasError"></span>
</div>

Check out this Fiddle for the working example.

Keep Your Open Source Licenses Straight

It’s hard to keep track of the ins and outs of the various open source licenses. I was putzing around online earlier today and came across a site that makes it easy to see the differences between them, though: choosealicense.com. The site is brought to you by GitHub, and it’s intended to help you pick an open source license for your open source project. What I like about it, though, is the list of open source licenses.

For each open source license, it shows you three categories of information: requirements, permitted, and forbidden. I’m nearly always working on closed source, commercial projects. In order to use open source software in my projects, they need to be permitted for commercial use and not have the requirement to disclose source code. Choosealicense.com’s list makes it easy to see which licenses do and don’t meet this criteria.

Of course, the list is not a complete one, so it doesn’t answer all open source license questions that you may run into, but it’s a nice resource, nonetheless. (Now it’s time for some good, common-sense legal advice! I’m not sure if there are lawyer’s reviewing the information at choosealicense.com, and I do not know how correct any of the information truly is. I am not a lawyer. Make sure you do adequate research before making use of any open source projects in the software that you develop.)

Breathtaking Animations with jQuery UI Easings

I was building a small web application for a customer, and I wanted to display a login prompt in a modal dialog box when the user isn’t authenticated. jQuery gives me an easy way to do that with its dialog command, so no problem there. The core functionality I’m looking for is done with one line of javascript.

// simple dialog
$("#dialog").dialog();

The dialog shows and hides just fine, but I thought I’d add some visual flair by slapping an animation on it. An easy way to do this would be to use jQuery UI’s effect methods. There are a number of basic effects to choose from: fadeIn/fadeOut, slideUp/slideDown, or even just hide/show with a delay.

// basic animations
$("#dialog").dialog({
    hide: function () {
        $(this).fadeOut();
    },
    show:  function () {
        $(this).fadeIn();
    }
});

On their own, these are okay, ho-hum animations. If you really want to snazz it up, give jQuery UI’s easings a look. Easings can be used to control the animation progression to create interesting visual effects. So, I wanted my dialog box to spring open and quickly snap into place, then do the opposite when closing. The easeOutBack and easeInBack easings combined with the scale effect are exactly what I wanted.

// animations with easings
$("#dialog").dialog({
    hide: {
        effect: "scale",
        easing: "easeInBack",
    },
    show: {
        effect: "scale",
        easing: "easeOutBack",
    }
});

I created this Fiddle as a working example. Breathtaking, right?

Re-Format Strings to Title Case in C#

I was just working on a small project that was importing data into one system from another. The data in the source system was formatted using all-caps, but the data entry practice for the destination system was to enter values using mixed or title case.

No problem, right? Reformatting the string values seems like a reasonably simple task. Make the whole thing lowercase, then capitalize the first letter. Improve the solution by using regular expressions to capitalize letters that follow spaces and hyphens.

But hold on a sec! It turns out it’s even easier than that. The .NET Framework has a culture-based TextInfo class that has a ToTitleCase method. Nice–way to have exactly what I need, Microsoft!

var textInfo = CultureInfo.CurrentCulture.TextInfo;
return textInfo.ToTitleCase(value);

ToTitleCase will format each word in a string to title case, with the first letter uppercase and subsequent letters lowercase. It respects whitespace as a word boundary as well as certain punctuation, such as commas, periods, question marks, and exclamation points. It’s not title case in the strictest sense since all words–including prepositions, articles, and conjunctions–will be capitalized, but it’s definitely good enough to satisfy my needs. The algorithm assumes words in all-caps are abbreviations or acronyms and ignores them, but you can get around that by using string‘s ToLower method.

Here are a few example uses:

Console.WriteLine(textInfo.ToTitleCase("hello, world!"));
Console.WriteLine(textInfo.ToTitleCase("this and that"));
Console.WriteLine(textInfo.ToTitleCase("words.with.periods"));
Console.WriteLine(textInfo.ToTitleCase("WORDS WITH ALL CAPS"));
Console.WriteLine(textInfo.ToTitleCase("WORDS WITH ALL CAPS (TOLOWER EDITION)".ToLower()));

// Output:
//    Hello, World!
//    This And That
//    Words.With.Periods
//    WORDS WITH ALL CAPS
//    Words With All Caps (Tolower Edition)

WCF Client Closal & Disposal

Say you’re consuming a WCF service. You’ve added a service reference, and you’ve got a client proxy. It implements IDisposable. So, when it’s time to use it, you should just chuck it in a using statement and not worry about additional resource cleanup, right?

Not so fast. There can be problems with the using statement. The problem is prevalent enough to warrant an article on MSDN demonstrating the improper use of using to automatically clean up resources when using a typed client.

So what should you be using instead of using? One option, which is outlined in the aforementioned MSDN article, is to use a try/catch block. If an exception occurs while closing the client, the client’s Abort method should be called. MSDN’s guidance suggests reporting errors and calling Abort for expected exceptions and calling Abort then re-throwing unexpected exceptions. The article explains, “Typically there is no useful way to handle unexpected errors, so typically you should not catch them when calling a WCF client communication method.”

// MSDN recommendation for WCF client cleanup
try
{
    client.Close();
}
catch (CommunicationException e)
{
    ...
    client.Abort();
}
catch (TimeoutException e)
{
    ...
    client.Abort();
}
catch (Exception e)
{
    ...
    client.Abort();
    throw;
}

There’s a lot of quick & dirty advice online that suggests using a try/finally block to first Close the client if it’s not in a faulted state, then Abort it if it’s not in a closed state. This is probably fine for small, simple applications, but hiding all exceptions can lead to maintenance woes later by reducing the visibility of underlying problems.

// effective but hides errors
try
{
    if (client.State != CommunicationState.Faulted)
    {
        client.Close();
    }
}
finally
{
    if (client.State != CommunicationState.Closed)
    {
        client.Abort();
    }
}

I like the suggestion laid out in this blog article. The author suggests re-implementing IDisposable in a partial class. The problem I have with this approach is that it may be confusing to other developers. When the client is used in the application, it will be wrapped in a using. There’s no good way for a developer to know whether that class has been properly re-implemented without doing further investigation. I think it’s easier for developers to have a hard rule: don’t use using with WCF clients.

So, instead of using a partial class, I’d suggest creating a wrapper that implements IDisposable. Developers using the client don’t need to worry about closing connections or error-handling; they can just throw a using around it an move on.

Here’s what that might look like. You could implement the service contract interface to ensure all methods are exposed, or have a generic method that accepts a lambda expression.

// An IDisposable client wrapper
public class Client : IDisposable
{
    private WcfClient _client;
    
    public Client()
    {
        _client = new WcfClient();
    }
    
    public void SomeMethod()
    {
        _client.SomeMethod();
    }
    
    void IDisposable.Dispose()
    {
        Dispose(true);
    }
 
    protected virtual void Dispose(bool disposing)
    {
        if (disposing)
        {
            if (_client == null)
            {
                return;
            }
            
            try
            {
                if (_client.State != CommunicationState.Faulted)
                {
                    _client.Close();
                }
            }
            catch (CommunicationException e)
            {
                //...
                _client.Abort();
            }
            catch (TimeoutException e)
            {
                //...
                _client.Abort();
            }
            catch (Exception e)
            {
                //...
                _client.Abort();
                throw;
            }
            finally
            {
                if (_client.State != CommunicationState.Closed)
                {
                    _client.Abort();
                }
                _client = null;
            }
        }
    }
 
    ~Client()
    {
        Dispose(false);
    }
}

Convert Latitude/Longitude Between Decimal and Degrees/Minutes/Seconds in C#

Latitude and longitude are usually represented in one of two formats: signed decimal and degrees/minutes/seconds (DMS). Signed decimal values range from -90 to 90 for latitude and -180 to 180 for longitude. DMS values, on the other hand, are broken into four parts: degrees, minutes, and seconds–obviously–plus a compass direction.

Converting between the two formats is not terribly difficult if you keep the following formula in mind:

Decimal Degrees = Degrees + minutes/60 + seconds/3600

Computers are good at math and converting things, so let’s write a converter to do the work for us! First, we need to define some types to work with. We have two different formats, so it makes sense for us to have a DecimalLocation and a DmsLocation. We can also get some re-use out of a DmsPoint type, and we’ll need an enumeration for PointType to help with displaying N/S & E/W directional indicators. I threw in some overloads for ToString to help with displaying results, too. Also note that N/S/E/W are determined based on the sign of Degrees for DMS points.

class DecimalLocation
{
    public decimal Latitude { get; set; }
    public decimal Longitude { get; set; }

    public override string ToString()
    {
        return string.Format("{0:f5}, {1:f5}",
            Latitude, Longitude);
    }
}

class DmsLocation
{
    public DmsPoint Latitude { get; set; }
    public DmsPoint Longitude { get; set; }

    public override string ToString()
    {
        return string.Format("{0}, {1}",
            Latitude, Longitude);
    }
}

class DmsPoint
{
    public int Degrees { get; set; }
    public int Minutes { get; set; }
    public int Seconds { get; set; }
    public PointType Type { get; set; }

    public override string ToString()
    {
        return string.Format("{0} {1} {2} {3}",
            Math.Abs(Degrees),
            Minutes,
            Seconds,
            Type == PointType.Lat
                ? Degrees < 0 ? "S" : "N"
                : Degrees < 0 ? "W" : "E");
    }
}

enum PointType
{
    Lat,
    Lon
}

Now that we’ve got our data types out of the way, we can work on the conversion. Our conversion formula shows how to calculate decimal degrees from DMS, so let’s do that first. It’s really straightforward–we just plug the formula into a function and call it for both latitude and longitude.

DecimalLocation Convert(DmsLocation dmsLocation)
{
    if (dmsLocation == null)
    {
        return null;
    }

    return new DecimalLocation
        {
            Latitude = CalculateDecimal(dmsLocation.Latitude),
            Longitude = CalculateDecimal(dmsLocation.Longitude)
        };
}

decimal CalculateDecimal(DmsPoint point)
{
    if (point == null)
    {
        return default(decimal);
    }
    return point.Degrees + (decimal)point.Minutes/60 + (decimal)point.Seconds/3600;
}

Going the other direction is a little more complicated. Ultimately, we’re just working backwards. Peel off the degrees, then calculate minutes, and seconds are left.

DmsLocation Convert(DecimalLocation decimalLocation)
{
    if (decimalLocation == null)
    {
        return null;
    }

    return new DmsLocation
        {
            Latitude = new DmsPoint
                {
                    Degrees = ExtractDegrees(decimalLocation.Latitude),
                    Minutes = ExtractMinutes(decimalLocation.Latitude),
                    Seconds = ExtractSeconds(decimalLocation.Latitude),
                    Type = PointType.Lat
                },
            Longitude = new DmsPoint
                {
                    Degrees = ExtractDegrees(decimalLocation.Longitude),
                    Minutes = ExtractMinutes(decimalLocation.Longitude),
                    Seconds = ExtractSeconds(decimalLocation.Longitude),
                    Type = PointType.Lon
                }
        };
}

int ExtractDegrees(decimal value)
{
    return (int)value;
}

int ExtractMinutes(decimal value)
{
    value = Math.Abs(value);
    return (int)((value - ExtractDegrees(value)) * 60);
}

int ExtractSeconds(decimal value)
{
    value = Math.Abs(value);
    decimal minutes = (value - ExtractDegrees(value)) * 60;
    return (int)Math.Round((minutes - ExtractMinutes(value)) * 60);
}

That’s it–we’ve got some lightweight methods to go between the two formats. Let’s whip up a quick test to verify the conversions:

void Main()
{
    DecimalLocation decimalLocation;
    DmsLocation dmsLocation;

    decimalLocation = new DecimalLocation
        {
            Latitude = 38.898611m,
            Longitude = -77.037778m
        };
    dmsLocation = Convert(decimalLocation);
    Console.WriteLine("{0} -> {1}", decimalLocation, dmsLocation);

    dmsLocation = new DmsLocation
        {
            Latitude = new DmsPoint
                {
                    Degrees = 38,
                    Minutes = 53,
                    Seconds = 55,
                    Type = PointType.Lat
                },
            Longitude = new DmsPoint
                {
                    Degrees = -77,
                    Minutes = 2,
                    Seconds = 16,
                    Type = PointType.Lon
                }
        };
    decimalLocation = Convert(dmsLocation);
    Console.WriteLine("{0} -> {1}", dmsLocation, decimalLocation);
}

// output:
//    38.89861, -77.03778 -> 38 53 55 N, 77 2 16 W
//    38 53 55 N, 77 2 16 W -> 38.89861, -76.96222

The converted values are off slightly, presumably due to some loss of precision, but the values produced are in the same general vicinity. (See here, here, and here.)

Full example:

void Main()
{
    DecimalLocation decimalLocation;
    DmsLocation dmsLocation;

    decimalLocation = new DecimalLocation
        {
            Latitude = 38.898611m,
            Longitude = -77.037778m
        };
    dmsLocation = Convert(decimalLocation);
    Console.WriteLine("{0} -> {1}", decimalLocation, dmsLocation);

    dmsLocation = new DmsLocation
        {
            Latitude = new DmsPoint
                {
                    Degrees = 38,
                    Minutes = 53,
                    Seconds = 55,
                    Type = PointType.Lat
                },
            Longitude = new DmsPoint
                {
                    Degrees = -77,
                    Minutes = 2,
                    Seconds = 16,
                    Type = PointType.Lon
                }
        };
    decimalLocation = Convert(dmsLocation);
    Console.WriteLine("{0} -> {1}", dmsLocation, decimalLocation);
}

class DecimalLocation
{
    public decimal Latitude { get; set; }
    public decimal Longitude { get; set; }

    public override string ToString()
    {
        return string.Format("{0:f5}, {1:f5}",
            Latitude, Longitude);
    }
}

class DmsLocation
{
    public DmsPoint Latitude { get; set; }
    public DmsPoint Longitude { get; set; }

    public override string ToString()
    {
        return string.Format("{0}, {1}",
            Latitude, Longitude);
    }
}

class DmsPoint
{
    public int Degrees { get; set; }
    public int Minutes { get; set; }
    public int Seconds { get; set; }
    public PointType Type { get; set; }

    public override string ToString()
    {
        return string.Format("{0} {1} {2} {3}",
            Math.Abs(Degrees),
            Minutes,
            Seconds,
            Type == PointType.Lat
                ? Degrees < 0 ? "S" : "N"
                : Degrees < 0 ? "W" : "E");
    }
}

enum PointType
{
    Lat,
    Lon
}

DecimalLocation Convert(DmsLocation dmsLocation)
{
    if (dmsLocation == null)
    {
        return null;
    }

    return new DecimalLocation
        {
            Latitude = CalculateDecimal(dmsLocation.Latitude),
            Longitude = CalculateDecimal(dmsLocation.Longitude)
        };
}

DmsLocation Convert(DecimalLocation decimalLocation)
{
    if (decimalLocation == null)
    {
        return null;
    }

    return new DmsLocation
        {
            Latitude = new DmsPoint
                {
                    Degrees = ExtractDegrees(decimalLocation.Latitude),
                    Minutes = ExtractMinutes(decimalLocation.Latitude),
                    Seconds = ExtractSeconds(decimalLocation.Latitude),
                    Type = PointType.Lat
                },
            Longitude = new DmsPoint
                {
                    Degrees = ExtractDegrees(decimalLocation.Longitude),
                    Minutes = ExtractMinutes(decimalLocation.Longitude),
                    Seconds = ExtractSeconds(decimalLocation.Longitude),
                    Type = PointType.Lon
                }
        };
}

decimal CalculateDecimal(DmsPoint point)
{
    if (point == null)
    {
        return default(decimal);
    }
    return point.Degrees + (decimal)point.Minutes/60 + (decimal)point.Seconds/3600;
}

int ExtractDegrees(decimal value)
{
    return (int)value;
}

int ExtractMinutes(decimal value)
{
    value = Math.Abs(value);
    return (int)((value - ExtractDegrees(value)) * 60);
}

int ExtractSeconds(decimal value)
{
    value = Math.Abs(value);
    decimal minutes = (value - ExtractDegrees(value)) * 60;
    return (int)Math.Round((minutes - ExtractMinutes(value)) * 60);
}

Delete Another User’s Workspace in TFS

I’ve run into this problem several times. A build blows up for some reason and creates an orphaned workspace. Other builds then fail with the message The path […] is already mapped in workspace […].

tfsbuild_alreadymapped

The way that I’ve dealt with this in the past is to simply delete the workspace, which you can do easily enough by using the tf workspace command.

tf workspace /delete someworkspace;somedomain\someuser

When you run the command, you’ll be warned that deleted workspaces cannot be recovered and prompted to confirm.

tfsbuild_reallydeleteworksp

Type “Yes” and the deed is done. Run another build, and you should be good!

 

Get Cute with Predecessors in Microsoft Project

I’ve known about Microsoft Project for a long time, but I’ve never really done anything with it until recently. There are several Project aficionados around the office. I’ve taken a peek here and there at their projects, but I just didn’t see the value. I don’t think I was ready for it. My team recently adopted Project as its primary planning tool, though, and so I’ve been using it more frequently. Little by little, I’m learning and becoming more comfortable with it, and I’m liking it more each day. I’m not a zealot yet, but I may very well be on my way.

The coolest feature I’ve learned about is the Predecessors field for tasks. If you’ve seen project at all, you’ve probably seen this. It allows you to say, “Task A must be finished before Task B, and Task B must be finished before Task C.” That makes sense, but it’s not all that impressive. What’s cool about it, and much less obvious, is that you can specify the dependency type for a predecessor. You can also specify lead time and lag time. These two features allow you to plan for more complex–and realistic–scenarios: “Task A must be finished before Task B, and Task C should start two weeks after Task B is completed.”

Dependency Type Description
FS (Finish-to-Start) Start the day after the predecessor finishes
FF (Finish-to-Finish) Finish the day the predecessor finishes
SS (Start-to-Start) Start the day the predecessor starts
SF (Start-to-Finish) Finish the day the predecessor starts

That’s all good and well, but how is any of this useful? Well, by using these different dependency types, you can pick the task or milestone that’s most important to your project and build a plan around it. Then, if the date of that all-important item changes, the rest of your plan can adjust automatically.

My team is responsible for creating small, custom projects for our customers. We have a backlog of work, and we want to schedule our development work based on a projected deployment date. We enter the deployment task first and build the plan backward from that. In order to deploy, development needs to be done two weeks before. In order for development to begin, we need a completed design. To create a design, a requirements document must be signed by the customer. And so on.

In Project, that plan might look like this. Note that the dates in italics are calculated from the predecessors.

ID Task Duration Date Predecessor
1 Requirements 1 wk 5/6/13 2SF-1 wk
2 Design 1 wk 5/20/13 3SF-1 wks
3 Develop 4 wk 6/3/2013 4SF-2 wks
4 Deploy 1 wk 7/15/2013

To create this plan, I picked my targeted deployment date. The development task’s predecessor says, “The deployment task’s start date should be my finish date with 2 additional weeks of lead time.” Similarly, the design task should start so that it will be finished 1 week before the development task is scheduled to start, and the requirements task should be done 1 week before the design task begins.

Now let’s throw a curveball at the plan. Say that something comes up, and the customer needs an upgrade before I can do my deployment. I can insert a new task, and make it the deployment task’s predecessor. Everything else adjusts automatically.

ID Task Duration Date Predecessor
1 Requirements 1 wk 5/27/13 3SF-1 wk
2 Design 1 wk 6/10/13 4SF-1 wks
3 Develop 4 wk 6/24/2013 5SF-2 wks
4 Customer upgrade 0 days 8/5/13
5 Deploy 1 wk 8/5/2013  4

That’s so awesome! I just shifted the entire project plan to reflect a new milestone that nobody ever saw coming.

Fill-In Field Prompts in Word 2013

I was creating a Word document template for my team to use, and I wanted to include a reference number in the header to make it appear on each page. I initially created a field for the user to click and enter the value. The problem with using a simple entry field and sticking it in the header is that it’s grayed-out and easily forgotten.

So, instead of using a textbox field, I decided to prompt the user for the value by using a fill-in field. It’s an easy thing to do, and users of the template will never forget to enter the value. (Of course, they might choose to ignore the prompt, but that’s a different problem!)

To create a fill-in field in Word 2013, do the following:

  1. Put your cursor in the document where you want the field to appear
  2. In the INSERT bar in the ribbon, choose Quick Parts > Field…

    Word2013_FIllIn_QuickParts

  3. In the Field dialog, choose Fill-In as the field name, enter the prompt text, and click OK

    Word2013_FIllIn_FieldPrompt

  4. Be sure to save your document as a Word Template

    Word2013_FIllIn_SaveAs

That’s all there is to it. When you create a new document from the template, you’ll be prompted, and the value will be filled in.
Word2013_FIllIn_ValuePrompt

Good stuff!