Friday, October 12, 2012

Building a Feature Branch Configuration Template in TeamCity

I don’t know about you, but sometimes we have frequent feature branches on our projects. Sometimes we don’t go through the trouble of setting up a build configuration in TeamCity if it’s a quick feature, but sometimes we like to see the pretty green checkbox in TeamCity when our build finishes successfully…especially when more than one person is working on the feature. We also like to deploy straight to our testing environments from a feature branch occasionally for testing, so it’s important for adding a build configuration quickly and accurately in TeamCity. I thought I’d give a demonstration on how to create one.

There are two ways to make a template. From scratch and from an existing build configuration. I will not talk about the “Extract Template” option because it’s literally clicking a button and giving a name from within the “Edit Build Configuration” screen. However, there are two things you’ll need to look at in order to use the extracted template as a feature branch template. So look at steps 2 and 4 below for the details if you have an existing build to use as a template.

Step 1: Click “Create template” under “Edit Project Settings” (I’m using version 7.0.4 of TeamCity btw)

CropperCapture[1]

Step 2: Fill in the name…I called mine Feature Branch Template (original I know). If you have a different build number per feature branch, which we do on this project, you can put %BuildNumber%.{0}.0 for the “Build number format”, otherwise, just leave it as the default (like below). Specify your “Artifact paths”, ours usually looks something like “build\latest\*.zip”. Click “VCS settings”.

CropperCapture[3]

Step 3: Here’s where the fun comes in…click “Create and attach new VCS root”.

CropperCapture[5]

Here you will select your VCS and fill in the appropriate information. The only VERY important thing you need to do is input “%BranchName%” into the Branch name. What this does is creates a parameter that will be required by your build configurations that use this template. Obviously we are using Mercurial, but you would just do the same as above for the equivalent of a branch in your source control.

CropperCapture[6]

When you’ve completed filling out the required information and tested the connection, Save. (Pro Tip: Don’t put %BranchName% in that field until after you’ve done “Test connection” with a real branch name.)

You should see this after saving:

CropperCapture[7]

Step 4: I’ll just leave all the defaults on the “Version Control Settings” screen, but if you require any of those settings, please set them if they apply to all your feature branches. Click “Add Build Step”.

CropperCapture[8]

Step 5: Configure your build steps. We only have two steps because we use psake…so basically we call the build.bat in our repo root with specific params and the other step just runs our unit tests with coverage.

Step 6 (optional): Configure fail conditions if needed…the most common condition I’ve seen is looking for specific text in the build log.

Step 7: Configure Build Triggering…we use the VCS Trigger, which detects when code is checked in. After clicking “Add new trigger”, you should see this:

CropperCapture[9]

I just use the default values. Click Save.

Step 8: Click Build Parameters – You should see BranchName <value is required> and BuildNumber if you specified that one in step 1.

If no BuildNumber specified:

CropperCapture[11]

If BuildNumber specified:

CropperCapture[12]

Okay, you’re done. Now you can start using the template…here’s how:

Under “Edit Project Settings”, click “Feature Branch Template”. In the bottom right, you should see this:

CropperCapture[13]

Step 1: Click “Create Build Configuration from Template”

Step 2: Give it a name…typically I name it the branch name.

Step 3: Now click Build Parameters on the right

Step 4: Click the <value is required> for the parameters you specified above and set the value. Click Save.

You’re done.

The way we were handling this before was by copying the build configuration and then creating a new VCS root with the appropriate branch name and add to remember to change the build number…now it forces us to tell it and we don’t have to create the new VCS root.

Please provide any feedback or post a comment if you have any questions.

kick it on DotNetKicks.com

Sunday, September 23, 2012

Export to Excel with MVC

I’m sure you’ve all had to export to Excel at one point or another. I created a small wrapper around the EPPlus library for MVC. Basically my wrapper contains a few helpers for common formatting, an ActionResult, and a column definition. Here’s what the end result looks like in the simplest form:

Basically this exports all the columns and records in the SampleInfo collection. So if you want to specify the columns you want, you can do this:


The ExcelColumnDefinition.Create<> is kinda ugly, so you could create a small helper method for readability like this:


Now the above example looks like this:


So this is what the ExcelColumnDefinition looks like:


Here’s the actual ActionResult:


So that’s it. If you have any questions, please feel free to comment below.

You can browse or download the source on GitHub. The sample project has examples.

Shout it

kick it on DotNetKicks.com

Thursday, August 30, 2012

Simple Way to Toggle on Hover with CSS

Here’s a really simple way to toggle actions or more information to keep your pages clean.


View Demo

kick it on DotNetKicks.com

Saturday, August 25, 2012

A Method for Populating a Dropdown List in ASP.NET MVC

I’m asked quite a bit how to bind a dropdown list in ASP.NET MVC. So there are about 10,000 ways to do it, but here’s one.

First, we’ll create a simple interface to return a list of SelectListItem so we can use the built-in DropDownListFor() later on.

Then we can create a SelectListProviderAttribute to take in the Type of list provider we want. You can see in this example I'm instantiating the object with StructureMap...you could do this with Activator or something else.




Now we just implement an ISelectListProvider and add the attribute to our model like this:

Sample property on view model:
[SelectListProvider(typeof(CommunitySelectListProvider))]
[DisplayName("Community")]
public int CommunityId { get; set; }
Now we just call our new HtmlHelper in our view and we're done. So here's the helper:


And now we just call it from the view like this:

@Html.DropDownListFor(x => x.CommunityId)

I'm sure you all realized that I used some additional helpers in code samples above. So for the curious few, I uploaded the full sample project to github. Browse the source now

Shout it

kick it on DotNetKicks.com

Tuesday, July 31, 2012

Dynamically Generate Form with jQuery and ASP.NET MVC

Hopefully it’s obvious that you probably won’t need to do this very often, but when it’s needed, it’s nice to have available. I thought I’d share this little helper to dynamically create a form, append it to body, and submit it...without AJAX.

First I'll show you how I'm converting my view model to a parameter list and a query string. Basically I've created an extension method that loops through properties and checks if it's an IEnumerable or not. If it is, then I loop through the values of that property. Otherwise, I just add the value. This method does not work with complex types. Typically view models are flat, so this works well most of the time.

The ToQueryString method just calls the ToParameterList, adds a ? to the front and then just selects what it needs from the parameter list.

The jQuery is pretty straight forward. I get the body, create a form with an action, loop through my param list creating a hidden input for each param, append the form to the body, and then submit it.


As always, if you know of a different and/or better way, please let me know.

If you don't need to post, you can just use a get, you could do something like this:


You can download a sample project at GitHub.

Shout it

kick it on DotNetKicks.com

Monday, June 11, 2012

Making Prettier Forms: Converting Checkboxes into Images

A couple weekends ago I went to the Big Design Conference in Dallas (recap coming soon), and I always come back inspired to help the user’s experience with the applications I write. One of the things mentioned (several times) was making forms simpler. Basically, you don’t have to make the end-user feel like they’re filling out a form. There are ways to make it seem less intimidating. One way is to swap out the typically hard-to-click checkbox or radio button with an image. It gives the user a larger click area and it looks nice…at least in my opinion.

Basically, I’m helping a friend with a small project, and the image below is what I wanted to create.

image

If you buy Stephen Anderson's book "Seductive Interaction Design", you will see a similar form to the one above...primarily just the name and contact info stuff. By the way, I definitely recommend this book.

As you can see, the “Select Classification” is not your typical radio button setup. I googled for a bit if there was already a jQuery plugin to do this type of thing and came up empty. I’m sure you almighty readers know of one, but I couldn’t find it…so I made one.

So far I’ve tested it in Firefox, IE9, Chrome, and JAWS, and it works pretty good in all of them. The way I set it up to work is based on the input and label. So you’d have the most accessible standard markup with your preferred styles for the label, and that’s how you get the effect shown above. I think it’s probably better said with code:

So it looks like a pretty typical setup so far, right? You have an input with a label. To make it more accessible, you wrap it with a fieldset and give it a legend. The primary reason you’d do this is to give screen readers some context. If you don’t need to worry about that, you could just as easy wrap it all with a div. You’re going to want to wrap it so your jQuery selector is more precise. After you markup the form, you just add the following JavaScript.

Now you’re all wired up, and you just add in your styles to whichever stylesheet classes you specified. The default stylesheet class names I specified are:

  • .Selected-Checkbox – this class is added to the label after it has been clicked
  • .Checkbox-in-focus – this class is added to the label when the checkbox/radio button is in focus

If you’re not sure the plugin is working properly, you can put it in “testMode”, like this:

$('#classification_radio_wrapper label').checkMate({testMode: true });

If you need to override my default class names, you can do that too by specifying class or focusClass in the options. I might rename class to selectedClass in the near future.

Please leave a comment if you have any questions or feedback.

The source code is available on github at https://github.com/derans/checkMate

The demo is located on 1pg.it at http://1pg.it/v9etvtn5 (also on github as the example.htm file)



Shout it

kick it on DotNetKicks.com

Tuesday, May 22, 2012

File Icons using CSS Selectors

This post is for a friend that was asking how to easily show icons with different file extensions. What I’ve setup are some styles that can just be copied over to any stylesheet and used.

I converted the icons downloadable at famfamfam.com to base64 and placed them in the styles. Without further ado, here they are:

These are all the basic file types I could think of and obviously you could add more to the list. I also added the with-icon, but this could be easily removed so it applies to all your hrefs all the time. There are a couple “special” styles at the bottom of the list for email and http links that use the ~=, which means starts with. All the rest of the styles work off the $= selector, which means ends with. To give the same icon to multiple file types, you just separate the selector with a comma.

In order to use these styles, you just do this:


This ends up looking like this:

links_with_icons

kick it on DotNetKicks.com

Wednesday, May 09, 2012

Testing for StructureMap Default Instances

Have you ever received the good ole “No Default Instance defined for PluginFamily”? error while using StructureMap? I thought I’d share a quick test you can write to catch this error before you deploy the bug. This test is particularly useful when you mostly depend on the default conventions.

In the example provided, I’ll be verifying that I can get a default instance of all my controllers. So I’ve setup 5 controllers and 2 have constructors with some type of dependency.

Something like this:

So now I can setup my test, which looks like this:


If you’re not familiar with TestCaseSource, I blogged about it a few weeks ago on the Headspring blog, so you can read about it there. The test queries the assembly containing HomeController for all types that are a subclass of Controller and are not abstract. After it gets the type, it tries to get an instance of it from the object factory. If it fails, the test fails with what specifically it couldn’t return and which controller couldn’t be instantiated.

Here’s what the test looks like when they all pass:

CropperCapture[7]

Here’s what the tests look like when the two with dependencies fails:

CropperCapture[8]

Here’s a detailed view of one of the error messages:

CropperCapture[9]

Notice it says IAuthenticationService and it failed on the AccountController, so we know exactly where to start looking. The only other thing I probably need to mention is the TestBase, which contains the StructureMap initialization. You could simply register your StructureMap registry file there. Here’s what the example looks like:

If anyone has any suggestions on how to improve the test or if StructureMap already has a test built-in that I’m not familiar with, please share.

kick it on DotNetKicks.com

Tuesday, April 03, 2012

Generic L2S Repository

I’m sure you’re all tired of me blogging about L2S, but I still like it. It’s just so simple and easy to use. Obviously with .net 4.0, the big issues with L2S seem to be resolved. Alongside l2sprof, LINQ to SQL can be very effective. Anyhow, I thought I’d share a simple generic repository I made.

Here's how you'd use the repository. Basically, you just pass in the DataContext you want to use and then call the method needed. As usual, please let me know if you see any improvements that can be made or if you have any questions.

kick it on DotNetKicks.com

Monday, March 12, 2012

Refactoring with LINQ

So my little brother sent over the code below last week and asked me if there was a better way to do it. When I first read through it I was thinking…I can’t believe people still use the good ole to/from listbox style UI. I don’t remember the last time I had to write this code, but I’m pretty sure it was prior to LINQ.

So here’s what I came up with in my response using LINQ.

Basically I was able to get rid of all the for loops, sorting, adding items, and most importantly, the new version is more readable.

Shout it

kick it on DotNetKicks.com

Sunday, March 04, 2012

Create an ActionLink without Magic Strings

Updated: 3/7/2011

So it’s been a while. I have a new job working for Headspring in Austin, which is one of the reasons I haven’t blogged in a while. It’s tough moving and re-adjusting to a new area and job, but Austin is great and Headspring is terrific. I started blogging on the Headspring site too. I’m trying to alternate weeks for posting, so we’ll see how that goes. (also fyi, Headspring is hiring)

On to the good stuff, I started playing with an HtmlHelper extension to rid a project of magic strings for action links. It was definitely more tricky than I originally thought, but I have a first attempt ready to share. Here’s the code:

@(Html.ActionLinkFor<HomeController>(a=>a.Contact(Model), "Contact"
, new Dictionary<string, object>{{"style","color: #f90;background:#000"}})) <br />

@(
Html.ActionLinkFor<MainControllerController>(a=>a.Index(), "Main Home"))<br/>

@(Html.ActionLinkFor<HomeController>(a=>a.Index(), "Home")) <br />

@(Html.ActionLinkFor<HomeController>(a=>a.AnotherTest(new SampleModel{Id=5555
, Name =
"Just a test", Address = "123 Main"}), "Another Test"))<br/>

@(Html.ActionLinkFor<HomeController>(a=>a.TestYetAnother(new SampleModel{Id=12345678
, Name =
"Just another test yet"}), "Yet Another Test"))

The code above is what I wanted for the end result. The code below is what makes the code above work.

    public static class HtmlHelperExtensions
{
public static IHtmlString ActionLinkFor<TController>(this HtmlHelper htmlHelper
,
Expression<Func<TController, object>> expression,
string displayText) where TController : Controller
{
return ActionLinkFor(htmlHelper, expression, displayText, null);
}

public static IHtmlString ActionLinkFor<TController>(this HtmlHelper htmlHelper
,
Expression<Func<TController, object>> expression, string displayText
,
IDictionary<string, object> htmlAttributes)
where TController : Controller
{
var method = ((MethodCallExpression)expression.Body).Method;
var actionName = method.Name;
var parameters = method.GetParameters();
var arguments = ((MethodCallExpression)expression.Body).Arguments;

var routeValue = new RouteValueDictionary();
for (int i = 0; i < parameters.Length; i++)
{
if (arguments[i] as MemberExpression != null)
{
var memberExpression = (MemberExpression)arguments[i];
if (memberExpression.Expression as ConstantExpression == null)
AddRouteValuesForMemberExpression((
MemberExpression)arguments[i]
, parameters[i].Name, routeValue);

if (memberExpression.Expression as ConstantExpression != null)
AddRouteValuesForConstantExpression(((
MemberExpression)arguments[i])
, parameters[i].Name, routeValue);
}
if (arguments[i] as MemberInitExpression != null)
AddRouteValuesForMemberInitExpression((
MemberInitExpression)arguments[i]
, routeValue);
if (arguments[i] as MethodCallExpression != null)
AddRouteValuesForMethodCallExpression((
MethodCallExpression)arguments[i]
, parameters[i].Name, routeValue);
}

var controller = typeof(TController).Name;
var controllerName = controller.Remove(controller.LastIndexOf("Controller"));
return htmlHelper.ActionLink(displayText, actionName, controllerName, routeValue, htmlAttributes);
}

private static void AddRouteValuesForMethodCallExpression(MethodCallExpression methodCallExpression
,
string parameterName, RouteValueDictionary routeValue)
{
if (methodCallExpression.Object != null)
{
var value = ((PropertyInfo)((MemberExpression)methodCallExpression.Object).Member)
.GetValue(((
ConstantExpression)((MemberExpression)methodCallExpression.Object)
.Expression).Value,
null);
routeValue.Add(parameterName, value);
}
}

private static void AddRouteValuesForMemberExpression(MemberExpression memberExpression
,
string parameterName, IDictionary<string, object> routeValue)
{
object model;
if (((MemberExpression)memberExpression.Expression).Member is PropertyInfo)
model = ((
PropertyInfo)((MemberExpression)memberExpression.Expression).Member)
.GetValue(((
ConstantExpression)((MemberExpression)memberExpression.Expression)
.Expression).Value,
null);
else
model = ((FieldInfo)((MemberExpression)memberExpression.Expression).Member)
.GetValue(((
ConstantExpression)((MemberExpression)memberExpression.Expression)
.Expression).Value);

foreach (var p in model.GetType().GetProperties())
{
if (p.Name == memberExpression.Member.Name)
{
var value = p.GetValue(model, null);
if (value != null && !routeValue.ContainsKey(p.Name))
routeValue.Add(parameterName, value.ToString());
}
}
}

private static void AddRouteValuesForConstantExpression(MemberExpression memberExpression
,
string parameterName, IDictionary<string, object> routeValue)
{
var properties = ((PropertyInfo)memberExpression.Member)
.GetValue(((
ConstantExpression)memberExpression.Expression).Value, null)
.GetType()
.GetProperties();

foreach (var property in properties)
{
var value = property.GetValue(((PropertyInfo)memberExpression.Member)
.GetValue(((
ConstantExpression)memberExpression.Expression).Value, null), null);

if (value != null)
routeValue.Add(property.Name, value.ToString());
}

if (properties.Length == 0)
{
var value = ((PropertyInfo)memberExpression.Member)
.GetValue(((
ConstantExpression)memberExpression.Expression).Value, null);

if (value != null)
routeValue.Add(parameterName, value.ToString());
}
}

private static void AddRouteValuesForMemberInitExpression(MemberInitExpression memberInitExpression
,
IDictionary<string, object> routeValue)
{
foreach (var p in memberInitExpression.Bindings.Cast<MemberAssignment>())
{
if (p.Expression is ConstantExpression)
{
var value = ((ConstantExpression)p.Expression).Value;
var name = p.Member.Name;
if (value != null)
routeValue.Add(name, value.ToString());
}
if (p.Expression is UnaryExpression)
{
throw new NotImplementedException("Not able to handle UnaryExpressions yet.");
}
}
}
}

Basically the way this thing works is off the Expression<Func<TController, object>> parameter being passed into the ActionLinkFor method. From the expression, you can determine the route values and action name…by doing a lot of manipulation. So, if you would, try this helper out and let me know of any bugs or improvements that can be made.


Shout it

kick it on DotNetKicks.com

Related Posts Plugin for WordPress, Blogger...