2013-03-25

ViewSource - View Source in Mobile Browsers

ViewSource Screenshot

Here's another small app that I created to play around with some code, but mostly because I felt I had a need for it.

ViewSource is an app for viewing the HTML-source of any website from your web-browser. Which enables you to view source from mobile browsers.

Just enter any URL and view the HTML-source. You also get a list of CSS-files and JavaScript-files, which you can view the source of, instantly in your browser.

You can quickly reach the app through bit.ly/vsource.

Fork on GitHub

As always, the source is available on GitHub for forking.

2013-03-19

IIS URL Rewrite-Rules Skipping Files-types

IIS Welcome

If you need to put in a rule for the IIS URL Rewrite Module, but need the rule to skip some file-endings and/or targets that are directories or actual files on disk, this is the post for you.

Following some SEO best-practices that tells us to use trailing slashes on our URLs I used the IIS Manager and added the IIS URL Rewrite-module's built-in rule "Append or remove the trailing slash symbol", which creates the following rule:

 <rule name="Add trailing slash" stopProcessing="true">
  <match url="(.*[^/])$" />
  <conditions>
    <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
    <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
  </conditions>
  <action type="Redirect" redirectType="Permanent" url="{R:1}/" />
</rule>

This rule takes into account and doesn't apply the rule to files and directories that exists on disk. But there is a big problem with this generic rule.

If you are dynamically serving up files with extensions, then an URL like:

http://website.com/about.html

will become:

http://website.com/about.html/

Adding conditions for specific file-endings

To solve this you can add conditions for certain file-endings, like .html and .aspx:

<conditions>
  <!-- ... -->
  <add input="{REQUEST_FILENAME}" pattern="(.*?)\.html$" negate="true" />
  <add input="{REQUEST_FILENAME}" pattern="(.*?)\.aspx$" negate="true" />
</conditions>

Since the rules above already don't apply for files physically on disk, you don't need to add file-endings like .css, .png or .js.

Update: Match ANY file-ending

If you want to match just any file-ending at all, you use the following pattern:

<conditions>
  <!-- ... -->
  <add input="{URL}" pattern=".*/[^.]*\.[\d\w]+$" negate="true" />
</conditions>

2013-02-20

ASP.NET: Transform Web.config with Debug/Release on Build

Web.config Transformation

Did you ever wish you could run your web application with the Web.config being transformed according to the current Solution Configuration for Debug or Release directly from Visual Studio? Well, with some pre-build-magic we can do this.

Files in project

Create a file named Web.Base.config, besides the existing Web.Debug.config and Web.Release.config. This file will be the equivalent to your old Web.config, as it will be the base for the tranformation. You will end up with these files:

  • Web.config
  • Web.Base.config
  • Web.Debug.config
  • Web.Release.config

Web.config

Add the following configuration to the bottom of your .csproj-file, just before the closing </Project>-tag:

<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\WebApplications\Microsoft.WebApplication.targets" />
<Target Name="BeforeBuild">
    <TransformXml Source="Web.Base.config" Transform="Web.$(Configuration).config" Destination="Web.config" />
</Target>

UPDATE: From a reminder in the comments I realized that I also have a problem with Visual Studio transforming the XML twice, when Publishing a project. The solution to this is to add a Condition to the Target-tag like this:

<Target Name="BeforeBuild" Condition="'$(PublishProfileName)' == '' And '$(WebPublishProfileFile)' == ''">

You can now build, run your project or publish it all depending on what Solution Configuration you have selected. Debug or Release. Just press your CTRL+SHIFT+B and see the Web.config-file be transformed.

Version control

I recommend that you leave Web.config out of your Version Control. This solution for transforming the Web.config on the fly would mean that this specific file would constantly be modified and if one person is working with Debug and another person is working with Release the Web.config would probably get big changes constantly.

Testing-tool

The people over at elmah.io has created the Web.config Transformation Tester, where you can try out what the result will be of combining a Web.config-file with a transformation.

The tool can even show you what the diff from the original file is when the transformation is applied.

2013-01-23

MVC: Get Current Action and Controller in View

Have you ever needed to know what Action and/or Controller that is currently used in your View? This might be most helpful in an Layout-file, used by another View.

string currentAction =
    ViewContext.Controller.ValueProvider.GetValue("action").RawValue.ToString();
string currentController =
    ViewContext.Controller.ValueProvider.GetValue("controller").RawValue).ToString();

Then you can do customization code like this in your _Layout.cshtml-file.

bool isIndexPage = currentAction.Equals("index", StringComparison.InvariantCultureIgnoreCase)
    && currentController.Equals("blog", StringComparison.InvariantCultureIgnoreCase);

Disclaimer: Of course this breaks the fundamental rules of separation of concerns in MVC, between the View and the Controller, but sometimes you just don't want, or can, pass around sufficient data between the View and the Controller.

2013-01-16

Create Human-Readable File Size Strings in C#

After needing functionality in C# for getting a human-readable file-size string I posted a question about it on Stackoverflow, as one does.

The accepted answer had about 72 lines of code. One explanation for this could be that I did specify that I wanted the solution to implement IFormatProvider. Not sure why I did that, probably seemed right at the time, in the end of 2008.

One creative solution was to use a Win32 API call to StrFormatByteSizeA

[DllImport("Shlwapi.dll", CharSet = CharSet.Auto)]
    public static extern long StrFormatByteSize(long fileSize, [MarshalAs(UnmanagedType.LPTStr)] StringBuilder buffer, int bufferSize);

Compact, clean, cross-platform solution

For the sake of simplicity, readability and the bonus of cross-platform I re-implemented an earlier solution I found, that was written in JavaScript. But the solution was easily translateble into C#.

public static class FileSizeHelper
{
    private static readonly string[] Units = { "B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" };

    private static string GetReadableFileSize(long size) // Size in bytes
    {
        int unitIndex = 0;
        while (size >= 1024)
        {
            size /= 1024;
            ++unitIndex;
        }

        string unit = Units[unitIndex];
        return string.Format("{0:0.#} {1}", size, unit);
    }
}

2013-01-10

FTP Upload File Using Only .NET Framework

Here an example of how to upload a file to a FTP-server, using the class FtpWebRequest, which is included in the .NET Framework.

string ftpPath = string.Format("ftp://{0}/{1}", urlOrIpNumber, filePath);
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftpPath);
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = new NetworkCredential (userName, password);

byte[] fileContents = GetFileContent();
request.ContentLength = fileContents.Length;

using(var requestStream = request.GetRequestStream())
{
    requestStream.Write(fileContents, 0, fileContents.Length);
    requestStream.Close();
}

All you need to do is reference the System.Net namespace.

Update: Shorter code version

This code comes from Mads Kristensen, written in the middle of 2006.

private static void Upload(string ftpServer, string userName, string password, string filename)
{
   using (var client = new WebClient())
   {
      client.Credentials = new NetworkCredential(userName, password);
      client.UploadFile(ftpServer + "/" + new FileInfo(filename).Name, "STOR", filename);
   }
}

I'm not sure if there are any scenarios that this code doesn't work with.

2012-08-30

Squishify - Minify JavaScript & CSS Online

Squishify Screenshot

Squishify was created out of the need of a minifier for JavaScript. I quickly put together a web-app on AppHarbor to make minification always available quickly. The code is hosted on GitHub.

The application is an ASP.NET MVC-app, using Justin Etheredge's framework for minification called SquishIt. The app also uses ASP.NET Web API together with some simple jQuery to display the results of the minifications without any page-reloads.

The SquishIt-framework is a very easy to use and provides multiple minifiers for both JavaScript and CSS.

JavaScript minifiers:

* At the moment of writing this post, Google Closure is not working as expected, but should hopefully work soon.

CSS minifiers:

Enjoy it at squishify.apphb.com and fork it on GitHub.

2012-05-21

ASP.NET MVC 4 Razor v2 - New Features

Reference

With the imminent release of ASP.NET MVC 4 my previous post ASP.NET MVC 3 Razor - The Ultimate Quick Reference needed a follow-up on what's new in the view-engine Razor v2, that comes with MVC 4.

App-relative URLs automatically resolved

In Razor v1 your views would be littered with code like this:

<script src="@Url.Content("~/content/scripts.js")"></script>

But in Razor v2 you can shorten it with a tilde in front of the URL, which was used a lot in WebForms:

<script src="~/content/scripts.js"></script>

This will work for any HTML-attribute that starts with the title-sign.

Conditional attributes hides null-valued attributes

Razor v1 treated null-valued attributes as empty string, writing out attributes empty values. Razor v2 will instead skip even writing out the attribute that has a null value:

@{
    string itemId = string.Empty;
    string itemClass = "class-of-item";
    string itemValue = null;
}
<div id="@itemId" class="@itemClass @itemValue" rel="@itemValue"></div>

Will result in this HTML:

<div id="" class="class-of-item"></div>

Note that string.Empty still makes Razor v2 to write out the attribute. Any data-attribute will ignore this rule and always write out the attribute.

Support for unclosed HTML-tags

The HTML5-specs clearly states that unclosed HTML-tags are supported, but Razor v1 didn't have an advanced enough parser to support this. Razor v2 now supports this with the elements listed in W3C's spec.

What else?

There has been some major improvements on how the syntax-trees are structured and other deep functionality in the language. The focus was internal clean-up and future-proofing.