sebnilsson.com | Liquid Development Is What I Do

Seb Nilsson

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.

0 Comments

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.

0 Comments

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\v11.0\WebApplications\Microsoft.WebApplication.targets" />
<Target Name="BeforeBuild">
    <TransformXml Source="Web.Base.config" Transform="Web.$(Configuration).config" Destination="Web.config" />
</Target>

The \v11.0\ part is for Visual Studio 2012. If you're using VS 2010 you change this to \v10.0\.

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.

0 Comments

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.

0 Comments

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);
    }
}
0 Comments