AnkhSVN 2.0 Released - How’s it look?

11 07 2008

When I first started using Subversion full time for all of my personal projects, I stuck with the VisualSVN server and AnkhSVN as a Visual Studio client.  Both were free, easy to install, and easy to use.

However, after a few weeks, the AnkhSVN client could almost be called “annoying.”  It trampled over the existing SCC plugins for SourceSafe (for work) and made a mess out of several of my project uploads.  I ended up going back to using TortioiseSVN and doing everything through Explorer.

When AnkhSVN 2.0 was released, I figured I’d give it another shot.

The site claims quite a bit—including several unique additions:

  • Pending changes window; subversion status and commands available in one place
  • Full support for Visual Studio 2005 and 2008; AnkhSVN is now a SCC package instead of just an addin
  • Better log viewer
  • Merge support
  • Property editor
  • AnkhSVN now supports most project types previously unsupported via the SCC api
  • All solution explorer actions (rename, copy&paste, drag&drop) keep subversion history now
  • Enhanced build process and setup
  • Automatic check for updates
  • And last but certainly not least end user documentation

All of those look great—especially the SCC package and changes window.  But how does it compare once installed?

After installation and starting up VS2008, everything looks normal.

Brief Look

Pending Changes Window

The new pending changes window is FANTASTIC—much improved over the old 1.x versions.  I did run into a snafu when trying to resize the window where the scrollbars didn’t update on the screen; however, I’m not sure if it’s a VSS or AnkhSVN issue.

SCC Package

Under Options > Source Control, AnkhSVN shows up just like it should.

What does boggle me is that all of the Subversion commands and menus are available no matter what—even when the VSS SCC is enabled.  It still has the stink of VSS and SVN trying to step on one another (“pick me! control your project with me! no, I’m better! pick me!”).

Log/History Viewer

I really like the new history viewer.  It’s clean and easy to read; however, if you change the options at the top—there doesn’t appear to be a way to “change it back” and see the history again, close the view and review.

Annoyances

  • Opening a project from Subversion (File > Subversion > Open from Subversion) will open a project just fine, copy it down, but never opens it.  You have to go back and open the solution after it’s created the local structure.  Not huge, but annoying.
  • When viewing history; you cannot view the history of a single file (that I’ve found) in the Repository Explorer. 

I’m still planning to give it a whirl for the next couple of weeks and see what happens.  Hopefully over a couple weeks I’ll have more time to code—it’s been a busy July so far!





Wrapping TabPanel Tabs With A Simple CSS Change

10 07 2008

The last few weeks have been filled with taking an old ASP legacy application and updating it to ASP.NET.  Fun stuff and not to challenging.

However, a “feature” of the AJAX Control Toolkit’s TabContainer finally hit a nerve.  In the past, I’ve ignored the fact that I couldn’t “wrap” the tabs or set how many rows of tabs to create.  I chalked it up to an annoyance and designed applications with this in mind.

After hunting through the Control Toolkit’s source code, the problem is simple.  There’s a line in the CSS explicitly telling it not to wrap.

Well, recompiling the toolkit can get annoying and hurts mobility of your applications—it’s no fun to bundle “custom” copies for a simple styling change.

.ajax__tab_header

{

    white-space: normal !important;

}

That will override the nowrap that is built into the Toolkit’s CSS.

Hopefully, someday, this will be a boolean property on the TabContainer control.





ReSharper 4.0 - Cool Features

13 06 2008

There are quite a few new features to ReSharper 4.0 that are great, but it’s the little things that really can impress and speed up usage.  A few of my favorites are below.

camelHumps. :)

ReSharper now supports Go To > and statement completion according to camel casing.  If you’re like me, you tend to write normal sentences in camel case—it’s just habit.

Using the camel casing, it picks up the variable I just created, not the class.

Lambda support.

I’ve become addicted to the simplicity of lambdas—they express intent and you can read them like sentences.  ReSharper 4 does an excellent job of digging into the anonymous type and pulling up IntelliSense information.

ResponseChoicesController()

.SelectOne(x =>

x.IsDefault &&

x.ResponseTypeId == responseTypeId)

From the ResponseChoicesController, select one that meets the requirements that IsDefault is true and ResponseTypeId is equal to the specified responseTypeId.  To me, and I’m sure I’m odd, that is easier to read than the “written” LINQ code.

Convert Static to Extension.

This is FANTASTIC for revamping existing code to take full advantage of the .NET 3.5 Framework.  I’ve been working on a project the past few weeks to migrate a .NET 2.0 project using Enterprise Library 3 up to 3.5 and LINQ-to-SQL and this addition has been fantastic to move data and business logic into controllers and the LINQ data context.

 





ReSharper 4.0 is now RC!

5 06 2008

The first RC for ReSharper 4.0 is out—pick it up! Nice!





Using the CLR Profiler with VS2008 Web Projects

13 05 2008

Download CLR Profiler for .NET 2.0 Framework.

The CLR profiler is great; it’s sweet to be able to see where memory is allocated and how well objects are disposed of (and whether or not I missed something that GC just isn’t catching). 

The form is pretty easy to use, but there’s a bit of a trick for VS 2008 web application profiling when using the built-in Web Development Server.

NOTE:  This isn’t anything like the ANTS Profiler (which I wish I had a license for, but don’t).  ANTS will tell you where code slowdowns are and more, this simply returns back histographs of object usage, memory, and the stack/heap.  Still very useful none the less.

Here’s how to get started:

1. Download the CLR profiler (see the link at the beginning of this article or click here).

2. Extract the profiler into a directory (it defaults to C:\CLRProfiler); it will extract two directory structures (binaries, source) and a readme document.

3. To start using the application immediately, browse into the Binaries directory and execute the CLRProfiler. 

Use the x86 version. I haven’t been able to get the x64 version to work correctly (even though I’m on a x64 machine) when profiling .NET web applications ala the built-in web development server.

4. Under File > Set Parameters, modify the “Command Line” to reflect the parameters required to start the built-in web development server.  After the parameters have been set, click OK.

Usually, you have a Port parameter and a Path parameter.  Here’s an example:

/port:1234 /path:“J:\Projects\Work\Current\ERC\web\”

5. Click ‘Start Application’.  A browse window will open.  Visual Studio 2008’s web development server is located in the Common Files directory.

%CommonProgramFiles%
    \Microsoft Shared\DevServer\9.0
or
%CommonProgramFiles(x86)
    \Microsoft Shared\DevServer\9.0

6. After selecting the WebDev.WebServer.Exe application file, your server will kick off with the parameters you set.

Now you’re ready to open up a web browser, begin browsing around, and evaluate your application.  When finished, click the ‘Kill Application’ button on the Profiler or simply close the WebServer application.





Visual Studio 2008 and .NET 3.5 SP1 Beta

13 05 2008

The blogs are abuzz this morning after the first beta release of the VS2008 and .NET 3.5 SP1.   Download it here.

In my opinion, this isn’t a service pack—this is a new version!

There are quite a few bug fixes (what you normally associate with a service pack), but also a huge list of new additions and improvements.

From Somasegar:

Traditionally our service packs address a range of issues found both through customer and partner feedback as well as our own internal testing.  While this service pack holds true to that theme and delivers updates for these types of issues, it also builds on the tremendous value that Visual Studio 2008 and .NET Framework 3.5 deliver today and enables an improved developer experience by adding a number of additional components that cover a range of highly requested customer features. For example, the service pack is the first release for Visual Studio 2008 that delivers full support for SQL Server 2008 and the ADO.NET Entity Framework.

I’ve posted a few links at the end of the post to the more extensive sources right now, take a look and get ready for the plunge.

So, what am I most excited about?

  • ADO.NET Entity Framework – I’m hoping that the “real” release motivates Oracle to develop provides for the entity framework and my dream of LINQ-esque connections to Oracle will be realized.
  • ASP.NET Routing Engine – As the MVC framework gets closer to a production reality, it’s very motivating to see the underpinnings already in place.
  • VS2008 Performance Improvements – Anything has to be an improvement. :(
  • JavaScript Code Formatting – Sweet, now if I can only get JavaScript intellisense to work. :(
  • LINQ Debug Support – Very nice, love seeing the generated SQL right there at debug time.

There are also lots of updates to WCF and WPF.  Hopefully this summer I’ll have more time to use these .NET 3.0 technologies and maybe be a bit more excited. ;)

Visual Studio 2008 GUI/Tools

The Web Developer Tools team has released a comprehensive list of designer bug fixes, IIS templates and modules, formatting changes, intellisense upgrades, and more on their blog.

MVC and URL Routing

Phil Haack details the effects of the URL routing changes on the MVC Preview releases as well as how it affects the upcoming Preview 3.

Everything

ScottGu, as always does an excellent job tying everything up together—designer, framework, and tooling.

Now, if ReSharper 4.0 would EVER get to RTW before we’re ready to VS2009, it’d be super!





Bubbling up Methods in Composite Controls

9 05 2008

A while back, I wrote a couple of articles (here and here) regarding encapsulating the ModalPopupExtender into a spiffy little template control that you could toss onto a page.  It’s worked GREAT over the past few months, however, I hit a snag today.

I needed to call the base ModalPopupExtender’s .Show() method from code behind; however, I hadn’t bubbled that up to the Composite Control.

At first, I expected to simply add a private instance of the MPE (which is assigned to when the control is built) and then add a method to my composite control that calls the .Show() method.

private ModalPopupExtender _control;

public void Show()

{

       _control.Show();

}

That sounds good, but it never fired and the _control field was always null (even though I could step through and it was assigned).

What it needed was a little reminder—a reminder to EnsureChildControls existed before trying to call Show().  Now, a quick update to the code:

public void Show()

{

       this.EnsureChildControls();

       _control.Show();

}

Now I can call the Show() method of the Composite Control and it works like a charm!  Here’s an example (for what I’m working with at the moment) of dynamically iterating through an IDictionary and returning the values in a Modal Popup.

ASPX:

<tiredstudent:ModalPopupTemplate HeaderText=”ERC” runat=”server”

        ID=”PopupDialogBox” DefaultStyle=”YUI” TargetControlId=”fakeButton” />

<asp:Button ID=”fakeButton” runat=”server” style=”display: none” />

Code-behind:

foreach (var entry in results)

{

       sb.AppendLine(string.Format(“<p>{0} - {1}</p>”,

                     entry.Key, entry.Value));

}

 

PopupDialogBox.BodyText = sb.ToString();

 

PopupDialogBox.Show();

 





Basic Benchmarking in ASP.Net

10 04 2008

I’m not sure why I’ve always rewrote this “simple” code—over and over again, project after project.  I should know better, but perhaps time has gotten the best of me (though I’m betting on lazy).

What code might this be?  The basic “stopwatch” for evaluating page performance and outputing the results to Page.Trace. You can do page speed analysis using Visual Studio 2008, but for quick Trace output, I prefer this method.

The class is almost totally private, but could be expanded later on to log to console, log to files, whatever.

public class BenchmarkToTrace

{

private TimeSpan ElapsedTime { get; set; }

       private DateTime StartTime { get; set; }

       private DateTime EndTime { get; set; }

       private Page PageToTrace { get; set; }

       private string TraceCategory { get; set; }

 

       public BenchmarkToTrace(Page pageToTrace, string category)

       {

              PageToTrace = pageToTrace;

TraceCategory = category;

PageToTrace.Trace.IsEnabled = true;

}

 

       public void Start()

       {

              StartTime = DateTime.Now;

}

 

       public void Stop()

       { 

EndTime = DateTime.Now;

ElapsedTime = EndTime - StartTime;

PageToTrace.Trace.Write(

TraceCategory,

string.Format(

“Start: {0} “ + Environment.NewLine +

“Stop: {1} “ + Environment.NewLine +

“Elapsed: {2}”,

StartTime, EndTime, ElapsedTime));

}

}

As far as usage, here’s how I am using the benchmarker to evaluate different data retrieval methods (in this example, measuring Oracle performance):

BenchmarkToTrace bench =

new BenchmarkToTrace(this.Page, “Reports-GetAllBy”);

 

bench.Start();

Reports.GetAllBy(123465789, 3, “2007-2008″);

bench.Stop();

           

bench.Start();

Reports.GetAllBy(123456789, 4, “2007-2008″);

bench.Stop();

When I load up the page, I see the trace log:

BenchmarkToTest Results

Cool, and I won’t rewrite this NEXT time.





FIX: Find/Replace Crashes Visual Studio 2008

8 04 2008

For the past few months, I’ve “tolerated” Visual Studio 2008 crashing whenever I tried to do a Find/Replace.  I’m not sure why… I just did.

Today, I set out and finally found a fix—it’s a known issue, but the patch hasn’t been widely distributed.  The problem revolves around not Visual Studio, but Windows itself—any x64 bit version of Windows.

The full feedback submission on Microsoft Connect is available here.

The solution is to go to this HotFix request site and for the “Product and version affected”, request 947841.  A few hours later, you’ll get an email with the downloadable hotfix and a password to unlock the file.

Unfortunately—NOTHING I’ve found explains what the hotfix resolves, changes, etc, but it works.

 





Verifying Extensions and MIME Types of FileUpload

7 04 2008

The FileUpload control is REALLY handy to upload files from a client, through the web, into a database table or the web server.  The control wraps up the HttpPostedFile object (into .PostedFile); however, there isn’t a way to “filter” on the fly.  This was a recent discussion in the Microsoft newsgroups today, so I figured I’d work out what it’d take to implement a “better” file upload control.

The control, inheriting the FileUpload class as a base class, implements quite quickly.  I’m sure you could go farther, but this works out nicely.

NOTE: In my experience, filtering by MIME type (aka content type) is much more reliable than parsing out the uploaded file’s file name and trying to grok the extension.  Extensions are far too easily changed. ;)

public partial class BetterFileUpload : FileUpload

{

public BetterFileUpload()

       {

              ValidContentTypes = new List<string>();

}

 

public IList<string> ValidContentTypes { get; private set; }

 

public void AddValidContentType(string contentType)

{

              ValidContentTypes.Add(contentType);

}

 

public void AddValidContentType(string[] contentTypes)

{

              foreach (var contentType in contentTypes)

{

ValidContentTypes.Add(contentType);

}

}

 

public bool HasValidContentType()

{

return

ValidContentTypes.Contains(PostedFile.ContentType);

}

}

This partial class simply adds a few methods and a single property to the FileUpload class—ValidContentTypes.

HasValidContentType looks through the ValidContentTypes and tries to match it to the PostedFile’s content type—then returns a boolean.

Using this code is simple.

To setup a few valid content types, you can either pass them one-by-one or as an array (you could also pass in a collection of some sort and use the ToArray() method to convert it back into an array).  You could also store these in the web.config file or another reusable source to keep the code clean.

protected void Page_Load(object sender, EventArgs e)

{

betterFileUpload.AddValidContentType(“text/plain”);

 

betterFileUpload.AddValidContentType(

              new[] {“application/msword”, “application/pdf”});

}

After the valid content types have been added and we’re ready to fetch the stream from the FileUpload object, we now have a tidy boolean method to check.

protected void ReadFileButton_Click(object sender, EventArgs e)

{

if (betterFileUpload.HasValidContentType())

       {

              InfoLabel.Text = “Valid ContentType: “ +

                     betterFileUpload.PostedFile.ContentType;

}

else

       {

              InfoLabel.Text = “Invalid ContentType: “ +

                     betterFileUpload.PostedFile.ContentType;

}

}

Works well and is reusable!