Posts tagged 'ASP.NET MVC'

21

May 2011

Configuring ELMAH to send emails without putting your password in the config file

Today I was configuring ELMAH to send emails when an exception occurs on my new blog. While looking for the config options, I noticed that a lot of the snippets being posted around suggests people are putting usernames and passwords in their config files to make this work. That's pretty scary! :(

Because SMTP is a bit crap, you don't actually need to authenticate to send email. Most SMTP servers are locked down to stop relaying, but if you deliver directly to the recipients server, the mail will (usually) be accepted anonymously. I sayusually because your email could be rejected based on the From header if something like DomainKeys is set up for that domain.

To configure ELMAH to send mail without authentication, simply look up an MX record for the domain you wish to send the email to, and use that as the SMTP Server. Eg., if you're using Google Apps (like me), you could do something like this:

<errorMail
    from="&quot;Blog Error&quot; &lt;blog+errors@fakedomain.com&gt;"
    to="&quot;Blog Errors&quot; &lt;blog+errors@fakedomain.com&gt;"
    smtpServer="aspmx.l.google.com" />

This means you don't need to put your email username/password in the config file to receive emails about your exceptions.

08

May 2011

Extending MarkdownHelper/MarkdownDeep.NET to support Google Code's Prettify Syntax Highlighter

I'm in the process of rewriting my blog in ASP.NET MVC to move it from Google App Engine to AppHarbor. One of the important changes is that all my articles will be stored as Markdown instead of HTML.

I've blogged previously about the MarkdownHelper class I created and put on NuGet to make using Markdown in views as trivial as typing:

@Html.Markdown(Model.Body)

One thing that I didn't take care of was adding syntax highlighting to code blocks. On this blog I currently use Google Code's Prettify syntax highlighter, and this requires a CSS class be applied to code blocks:

<pre class="prettyprint">
// Code here
</pre>

By default, MarkdownDeep (which my MarkdownHelper uses) doesn't add these classes, so I had to make some changes to support it. I didn't want to build this into MarkdownHelper as it's fairly specific to using this particular syntax highlighter. Instead, I decided to take advantage of partial classes to allow the functionality to be customised without having to modify the MarkdownHelper.cs file added by MarkdownHelper/NuGet.

First I amended the MarkdownHelper class, adding "partial" to the declaration. This was pushed to NuGet as MarkdownHelper 1.2:

public static partial class MarkdownHelper
{
// ...
}

With this done, I loaded my blog in Visual Studio and opened the Library Package Manager, which showed the update and replaced the class with one click. With this done, I then created a new file named "MarkdownHelper.CodeFormatting.cs" alongside "MarkdownHelper.cs" in my Helpers folder. This is where my customisations should go, which will allow MarkdownHelper.cs to be updated by NuGet without affecting the customisations.

As it turned out, customising the code blocks with MarkdownDeep was pretty easy. The class has several extension points, the interesting one for me being:

public Func<Markdown, string, string> FormatCodeBlock;

If you set this property, when a code block is encountered, your code will be called instead of the default. To make sure I wasn't losing any functionality, I checked the source code of MarkdownDeep to see exactly what it did with a code block:

b.Append("<pre><code>");
foreach (var line in children)
{
    m.HtmlEncodeAndConvertTabsToSpaces(b, line.buf, line.contentStart, line.contentLen);
    b.Append("\n");
}
b.Append("</code></pre>\n\n");

This seemed simple enough, and actually, the code path when you had a custom method was almost the same, it just didn't put the pre/code blocks in:

var sb = new StringBuilder();
foreach (var line in children)
{
    m.HtmlEncodeAndConvertTabsToSpaces(sb, line.buf, line.contentStart, line.contentLen);
    sb.Append("\n");
}
b.Append(m.FormatCodeBlock(m, sb.ToString()));

This meant the only thing I needed to do was surround the string with the pre/code tags. Adding class="prettyprint" was rather trivial:

/// <summary>
/// Overrides the Markdown formatting for code blocks to inject "prettyprint" classes for syntax highlighting.
/// </summary>
private static string FormatCodeBlock(Markdown md, string code)
{
	// Wrap the code in <pre><code> as the default MarkdownDeep.NET implementation does, but add a class of
	// "prettyprint" which is what Google Code Prettify uses to identify code blocks.
	// http://google-code-prettify.googlecode.com/svn/trunk/README.html
	var sb = new StringBuilder();
	sb.Append("<pre class=\"prettyprint\"><code>");
	sb.Append(code);
	sb.Append("</code></pre>\n\n");
	return sb.ToString();
}

Then in my partial class, I simply assigned this method to the FormatCodeBlock property of the Markdown transformer in a static constructor (since this is a partial class, it has direct access to the "markdownTransform" object):

/// <summary>
/// Static constructor to set MarkdownHelper options.
/// </summary>
static MarkdownHelper()
{
    // Override code formatting to support syntax highlighting.
    markdownTransformer.FormatCodeBlock = FormatCodeBlock;
}

With those changes, all my code blocks have the correct class and highlight correctly :-) You can see a sample of a code block on the homepage of the development site where I'm building the blog. You can also see the full source code on Bitbucket (MarkdownHelper.CodeFormatting.cs).

07

May 2011

Setting up NuGet to Automatically Fetch Packages When Deploying to AppHarbor Without Storing Binaries in Source Control

Over the last few days I've been blogging and tweeting about using NuGet without committing the packages folder to source control. David Ebbo blogged about using a pre-build event to fetch packages at build time.

Unfortunately, this doesn't work on AppHarbor because build events are not supported. If you try, you'll find the pre-build step doesn't fire and the build fails due to the missing dependencies :(

I voted on (and tweeted about, lots) a feature request about supporting NuGet natively on AppHarbor. The request has had quite a few votes, and Friism said they'll probably implement it, but in the meantime, this meant I couldn't deploy to AppHarbor. I didn't want to add my packages folder to source control, because even once I remove it when AppHarbor supports NuGet natively, it'll still be in the history (and therefore every clone), which I'd like to avoid.

I scratched my head a little, and re-read the proposed spec for baking this functionality into NuGet/MSBuild (to be honest, I don't actually understand what there is to improve!). The mentions of MSBuild got me thinking - custom build targets!

I opened up my csproj file in Notepad, and scanned through for the "BeforeBuild" step that's included by default but commented out. I removed the comment, and moved my pre-build event into the target:

<Target Name="BeforeBuild">
<Exec Command="&quot;$(SolutionDir)Tools\NuGet&quot; install &quot;$(ProjectDir)packages.config&quot; -o &quot;$(SolutionDir)packages&quot;" />
</Target>

First I checked whether this worked locally, by deleting my packages folder and running MSBuild from the command line. Success! I added in MarkdownHelper and added some test code to a view:

@Html.Markdown("We can use **Markdown!**")

Everything worked fine locally. An "hg ci" and "hg push" later, Bitbucket notified AppHarbor, AppHarbor checked out, built, and successfully deployed!

To show it working, you can see the test page at dev.dantup.com that will form the basis of the ASP.NET MVC / Razor version of this blog, and view the source code that AppHarbor is pulling to see there's no packages folder!

So, it turned out to be quite simple to get it working. I've also notified David Ebbo to see if he'd update his post with this info for anyone reading there that's using AppHarbor! :-)

04

May 2011

Vote for Native NuGet Support on AppHarbor to save your Repositories from The Bloatmonster

I was hoping to post tonight about how awesome BitBucket, AppHarbor and NuGet all worked together. Sadly, I hit a problem with getting NuGet to fetch packages on AppHarbor. First, some background...

Binaries in distributed version control systems are evil.

The problem with binaries in DVCS is that every clone pulls an entire copy of the repository (this is good, normally). If you have ten different revisions of a 10mb binary file, then your clone will include all of these copies - 100mb in total.

David Ebbo posted about using NuGet without committing packages to source control. The idea is that when you check out, you can use NuGet.exe to fetch all the packages based on your packages.config file. This means you can keep your repository lean, but still get all the required dependencies with little effort. In fact, David suggests a pre-build event that will run NuGet automatically! Unfortunately...

AppHarbor does not support build events

This means the pre-build event that executes NuGet to fetch the packages on a clean checkout, doesn't run, and the AppHarbor build will fail due to missing dependencies.

The Fix?

The fix is for AppHarbor to either support build events (tricky, for security reasons), or support NuGet natively, and allow us to tell AppHarbor to automatically execute NuGet to fetch our packages after checking the code out, but before running MSBuild.

So, what are you waiting for? Go and vote for NuGet support on AppHarbor so you can host your ASP.NET MVC applications there (for free, if not very big!) without needing to bloat your repositories with 400MB of NHibernate ;)

27

April 2011

MarkdownHelper on NuGet, using MarkdownDeep

Last month I posted a small HtmlHelper to make transforming Markdown in an ASP.NET MVC application a little easier. Unfortunately, getting it up and running wasn't quite so easy... You had to go and download MarkdownSharp (or copy the code file from the Google Code site) and put it in your project, then copy/paste my code into a file, add the namespace to a Views/Web.config, and blah blah, you gave up already.

Not any more!

I created a package called MarkdownHelper on NuGet. It took me less time to create the package than it took to get up and running previously, but now using the package is as simple as typing the following into the Package Manager Console...

PM> Install-Package MarkdownHelper

... that's it! All done! Now in your views, you can simply type:

@Html.Markdown(Model.YourMarkdownPropertyHere)

This means you no longer have to copy/paste code around. This is mighty useful if you're using Markdown in multiple ASP.NET MVC applications.

Rather than creating another assembly to import, the helper class will be put directly into your project (inside a cryptically named "Helpers" folder), though if this isn't the done thing, I can change it easily enough.

Also worth noting that I changed from MarkdownSharp to MarkdownDeep.NET. In addition to being faster (which isn't really important unless you're transforming a lot of text), it has a Javascript version that works transforms 100% the same, which will come in handy if you're writing an editor. Currently the package imports only the .NET version, though this might change as I add functionality.

« Older posts