Dealing with Fractional values

The question Convert a text fraction to a decimal arose and though I’d post a solution to it using a class with the implicit operator. Admittedly I didn’t do a lot of testing on this, but it should handle a great deal of situations as-is. If you need more flexibility, feel free to extend it yourself (and post your modification here so I can update any edge cases).

With that said, here’s the class:

public class FractionalNumber
  1. {
  2.     public Double Result
  3.     {
  4.         get { return this.result; }
  5.         private set { this.result = value; }
  6.     }
  7.     private Double result;
  8.  
  9.     public FractionalNumber(String input)
  10.     {
  11.         this.Result = this.Parse(input);
  12.     }
  13.  
  14.     private Double Parse(String input)
  15.     {
  16.         input = (input ?? String.Empty).Trim();
  17.         if (String.IsNullOrEmpty(input))
  18.         {
  19.             throw new ArgumentNullException("input");
  20.         }
  21.  
  22.         // standard decimal number (e.g. 1.125)
  23.         if (input.IndexOf('.') != -1 || (input.IndexOf(' ') == -1 && input.IndexOf('/') == -1 && input.IndexOf('\\') == -1))
  24.         {
  25.             Double result;
  26.             if (Double.TryParse(input, out result))
  27.             {
  28.                 return result;
  29.             }
  30.         }
  31.  
  32.         String[] parts = input.Split(new[] { ' ', '/', '\\' }, StringSplitOptions.RemoveEmptyEntries);
  33.  
  34.         // stand-off fractional (e.g. 7/8)
  35.         if (input.IndexOf(' ') == -1 && parts.Length == 2)
  36.         {
  37.             Double num, den;
  38.             if (Double.TryParse(parts[0], out num) && Double.TryParse(parts[1], out den))
  39.             {
  40.                 return num / den;
  41.             }
  42.         }
  43.  
  44.         // Number and fraction (e.g. 2 1/2)
  45.         if (parts.Length == 3)
  46.         {
  47.             Double whole, num, den;
  48.             if (Double.TryParse(parts[0], out whole) && Double.TryParse(parts[1], out num) && Double.TryParse(parts[2], out den))
  49.             {
  50.                 return whole + (num / den);
  51.             }
  52.         }
  53.  
  54.         // Bogus / unable to parse
  55.         return Double.NaN;
  56.     }
  57.  
  58.     public override string ToString()
  59.     {
  60.         return this.Result.ToString();
  61.     }
  62.  
  63.     public static implicit operator Double(FractionalNumber number)
  64.     {
  65.         return number.Result;
  66.     }
  67. }

Now your integration should resemble something like:

Double fractional = new FractionalNumber("3 1/2"); // = 3.5

Flattr this!

Suggestive JavaScript save file name using Blob

If you’ve ever wondered how to suggest a file name using JavaScript, I found a method that’s proven to work. Using a Blob, some AJAX and copying an example provided by Google I came up with the following code. I used this successfully within a GreaseMonkey script to be able to automate saving files off, but it should work universally. the only hurdle would be saving files that cross the domain boundary (where GM_xmlhttpRequest can bypass this boundary natively, where as a traditional AJAX request cannot). With that said, here is the code:

  // Here we setup the path to the content (to be retrieved using AJAX)
  var contentUrl  = "/path/to/file.jpg";

  // Helper function that's going to take the data and bundle it in
  // to a blob using whatever Blob method available for the current
  // client's browser
  function dataToBlob(data,mimeString){
    // convert data to ArrayBuffer
    var buffer = new Int8Array(new ArrayBuffer(data.length));
    for (var i = 0; i < data.length; i++){
      buffer[i] = data.charCodeAt(i) & 0xff;
    }

    // http://stackoverflow.com/a/15302872/298053
    try {
      return new Blob([buffer],{type:mimeString});
    } catch (e1) {
      try {
        var BlobBuilder = window.MozBlobBuilder || window.WebKitBlobBuilder || window.BlobBuilder;
        if (e.name == 'TypeError' && window.BlobBuilder){
          bb = new BlobBuilder();
          bb.append([buffer.buffer]);
          return bb.getBlob(mimeString);
        } else if (e.name == 'InvalidStateError'){
          return new Blob([buffer.buffer],{type:mimeString});
        }
      } catch (e2) {
      }
    }
    return null;
  }

  // Perform the actual download (remember that GreaseMonkey can cross domain
  // boundaries. if you find this doesn't work when you port it to an $.ajax
  // call, make sure you're on the same domain (or using JSONP)!
  GM_xmlhttpRequest({
    'method': 'GET',
    'url': contentUrl, // we assign this above
    'overrideMimeType': 'text/plain; charset=x-user-defined',
    'onload': function(response){
      // try to get as much of the metadata from the response as possible. this way
      // all we really need is the contentURL and the rest will come.
      var fileName = response.finalUrl.replace(/^.*[\\\/]/, ''),
          mimeString = response.responseHeaders.match(/^Content-Type: (\w+\/\w+)$/m)[1];

      var blob = dataToBlob(response.responseText, mimeString);
      if (blob){
        // if we were able to process it to a blob, let's create an anchor we can
        // assign the blob to. You can either create a new anchor, or assign it to
        // an existing one. if you do use an existing one, just make sure you set
        // the download, href & dataset.downloadurl properties!
        var a = document.createElement('a');
        a.download = fileName; // or whatever you want to name it
        a.href = (window.webkitURL || window.URL).createObjectURL(blob);
        a.innerHTML = 'Click to save ' + fileName;
        a.dataset.downloadurl = [mimeString, a.download, a.href].join(':');
        a.draggable = true;
        a.style.color = 'white';
        document.body.apendChild(a);
      } else {
        // warn user it's unavailable or do nothing--it's up to you
      }
    }
  });

All of this could just as easily be assigned to a click function (instead of at page load). It’s up to you how you want to implement it.

Flattr this!

Pass HTML to extension method

Lately I’ve been working in MVC a lot and playing around with refactoring page generation approaches to make it more flexible and easier to customize. One method I wanted to pass along was how to pass HTML to a helper (extension) method.

I got the following from (once again) a post over on StackOverflow by Darin Dimitrov and thought I’d post a synopsis here for reference. Let’s say you want to register JavaScript code on your master page/root layout from a DisplayTemplate or EditorTemplate (my purpose was to attach the jQuery tokenInput library to a form in an EditorTemplate). Normally you’d need to bring the code to the top layout and implement it on all pages, but make it only activate when necessary. But below you can take advantage of passing html to a helper (and use the HttpContext to cache the registrations) then output anything registered from any other view. I’ll show you the code:

  1. public static MvcHtmlString RegisterScript(this HtmlHelper htmlHelper, Func<Object, HelperResult> script)
  2. {
  3.   String scriptKey = String.Format("_JavaScript_{0}", Guid.NewGuid());
  4.   htmlHelper.ViewContext.HttpContext.Items.Add(scriptKey, script);
  5.   return MvcHtmlString.Empty;
  6. }
  7. public static MvcHtmlString RenderScripts(this HtmlHelper)
  8. {
  9.   foreach (var key in htmlHelper.ViewContext.HttpContext.Items.Keys)
  10.   {
  11.     if (key.ToString().StartsWith("_JavaScript_"))
  12.     {
  13.       Func<Object, HelperResult> helper = htmlHelper.ViewContext.HttpContext.Items[key] as Func<Object, HelperResult>;
  14.       if (helper != null)
  15.       {
  16.         htmlHelper.ViewContext.Writer.Write(helper(null));
  17.       }
  18.     }
  19.   }
  20. }

And then in a view you’d use something like:

  1. @Html.RegisterScript(
  2.   @<script type="text/javascript">
  3.     $(function(){
  4.       $('#someControl').somePlugin()
  5.     });
  6.   </script>
  7. )

And then back in your _Layout file:

  1. @Html.RenderScripts()

Flattr this!

Install .NET 4 on IIS 7

As with a lot of my posts, a question was asked on StackOverflow how to Setup .NET 4 on IIS 7 (Windows 7). The process is quite simple as the framework takes care of a lot of it for you. It’s just a matter of finding the tools the framework uses and calling them.

Although I already answered it on StackOverflow, I thought I would also post it here with a tad more detail. So, without further ado…

If I describe something you should type, the quotes around the term(s) are unnecessary and are only there to visually display the command that should be type. e.g. If I ask you to type “cmd” all you should be typing is cmd.

  1. Install .NET 4 Framework
    The downloads page can be found directly on Microsoft.com/net, but I’ll make it easy and say it can be found here: http://www.microsoft.com/net/…
  2. Open your command prompt
    1. Open an Elevated Command Prompt
  3. Navigate to the directory where the framework is. For my installation (and I believe most) the following command should work:
    cd %SystemDrive%\Windows\Microsoft.NET\Framework\v4.0.30319
  4. Install the Framework on IIS
    1. type “aspnet_regiis.exe -ir” and press ENTER
      1. If this is a fresh install of IIS or you have sites hosted that won’t be affected by a framework change, you can use the “-i” flag (dropping the “r”). This will effectively make all currently-hosted sites use the new framework.
      2. If you’re curious about “-ir”/”-i”, or what other options are available, please see this MSDN article on aspnet_regiis.exe.
    2. The framework is now beginning to install on IIS.
    3. Once it’s completed, you can close the command prompt.

At this point the framework should be installed on IIS. To confirm, let’s make sure that the application pool successfully installed.

  1. Open IIS Management
    1. Open Start Menu, right-click Computerand select Manage
      1. Like shortcuts? “compmgmt.msc” in the console works, too.
    2. Locate and expand Services and Applications
    3. Select Internet Information Services
      1. You’re now within the IIS applet.
  2. Change the Application Pool(s)
    1. Expand out your computer node under Connections to the left within the IIS applet.
    2. Select the Application Pools node.
    3. Confirm that you see the ASP.NET v4.0 and ASP.NET v4.0 Classic pools.

Now, if you did use the “-ir” flag and need to switch over some sites to use the new framework, perform the following tasks:

  1. Update site to use new application pool
    1. Expand the Sitesnode
      1. You now have a list of all the sites IIS is hosting. Repeat the following steps for each site you’d like to update.
    2. Locate and select (click) the site you’d like to manage.
    3. Click Basic Settings… link on the right hand side in the Actions bar.
    4. Click the Select… button and select the ASP.NET v4.0 AppPool and click OK.
    5. Click OK again to accept the new AppPool.
    6. Restart the website (Restart link to the right below Manage Web Site.

Everything should be good-to-go now, and that site will now run .NET 4.0. If you have any other sites that need changing, follow the last set of instructions for each site you need to update.

Flattr this!

Disable Validation on Hidden Controls

While working on a website this week I needed the ability to disable the form validation on a control that was hidden from view using a style sheet. e.g.

  1. <div style="display:none;">
  2.   <asp:TextBox runat="server" ID="foo" />
  3.   <asp:RequiredFieldValidator runat="server" ID="foo_req" ControlToValidate="foo" ErrorMessage="Required field" />
  4. </div>

After a little bit of searching, I found a ValidatorEnable method that comes with ASP:

  1. // Disable the valiation
  2. ValidatorEnable(document.getElementByID('<%= foo.ClientID %>'), false);
  3.  
  4. // Enable the validation
  5. ValidatorEnable(document.getElementByID('<%= foo.ClientID %>'), true);

Unfortunately I had a little trouble getting this to work. It would either not work altogether, work but then I couldn’t make the field visible again, or the validation was still working but because the element was hidden you just doesn’t see the error message (inevitably preventing the form from submitting).

Through a little bit of debugging I think I realized the issue; even though the ValidatorEnable method is supposed to accept a control reference (an actual DOM element through a call such as document.getElementById() then a true/false representing the enabled status) it doesn’t even touch an array I care passionately about: Page_Validators.

  1. var Page_Validators =  new Array(document.getElementById("ctl00_MainContentPlaceHolder_foo_req"), /*…*/);

You see, this little array is assigned by ASP and is used by the validation code that ASP provides. In it is a list of every validator that should be applied and which control it applies to. With every form submission, ASP loops through this array and checks to make sure everything is acceptable before proceeding (despite be thinking I disabled a few of them).

So what’s the solution? I decided to write my own method that takes this array in to consideration (and it appears to work very well). Is it the correct way? Not sure. Does it get the job done? Yes. (and that’s all I care about for now).

  1. function _ValidatorEnable(control, enabled) {
  2.   enabled = enabled || false;
  3.   ValidatorEnable(control, enabled);
  4.   control.style.visibility = !enabled ? 'hidden' : ''; // necessary?
  5.   if (typeof Page_Validators === 'undefined')
  6.       return;
  7.   for (var v = 0; v < Page_Validators.length; v++) {
  8.     var validator = Page_Validators[v];
  9.     if (validator.controltovalidate == control.id) {
  10.       validator.enabled = enabled;
  11.     }
  12.   }
  13. }

That’s what I came up with. Basically, in addition to calling a function that should always work, it also loops through the validator list (if existing) and finds any that relate to the control in question and sets them as enabled/disabled as well. I also have a little CSS style change in there that may or may not be necessary, but (as I mentioned) I was getting controls staying invisible on me and this was the best-fit solution (i.e. best hack).

If anyone else knows a better way, by all means please share it. I have yet to come up with a better way, or find a better solution out there (which is also why I’m making a post).

Flattr this!

Authorize controller or action for domain

A user on StackOverflow asked if it was possible to allow all users from a domain to access a controller or action in MVC. Yes, it is possible. The immediate answer is to apply the AuthorizeAttribute to the controller or action and specify that the roles fall within “MYDOMAIN\Domain Users”. e.g.

  1. [AuthorizeAttribute(Roles = @”DOMAIN\Domain Users")]

Though this is effective, it still isn’t as clean as I would like. So, I have written a simple extension to the AuthorizeAttribute making it more concise. The extension should be placed within your project, and will allow you to decorate the controller in the same fashion, but make it more legible (at least I think) what your intent is. Anyways, here’s the class:

  1. /// <summary>
  2. /// Specified which domains a user should belong to in order to access the decorated
  3. /// controller/action
  4. /// </summary>
  5. public class DomainAuthorizeAttribute : AuthorizeAttribute
  6. {
  7.     private String[] domains = new String[0];
  8.  
  9.     /// <summary>
  10.     /// List of acceptable domains
  11.     /// </summary>
  12.     public String[] Domains
  13.     {
  14.         get { return this.domains; }
  15.         set { this.domains = value; }
  16.     }
  17.  
  18.     protected override bool AuthorizeCore(HttpContextBase httpContext)
  19.     {
  20.         if (httpContext == null)
  21.         {
  22.             throw new ArgumentNullException("httpContext");
  23.         }
  24.  
  25.         // User not logged in
  26.         if (!httpContext.User.Identity.IsAuthenticated)
  27.         {
  28.             return false;
  29.         }
  30.  
  31.         // No roles to check against
  32.         if (this.Domains.Length == 0)
  33.         {
  34.             return true;
  35.         }
  36.  
  37.         // check if they're on any of the domains specified
  38.         String[] roles = this.Domains.Select(d => String.Format(@”{0}\Domain Users", d)).ToArray();
  39.         if (roles.Any(httpContext.User.IsInRole))
  40.         {
  41.             return true;
  42.         }
  43.  
  44.         return false;
  45.     }
  46. }

Now you can decorate your controller like so:

  1. [DomainAuthorize(Domains = new[]{ "DOMAIN1", "DOMAIN2" })]

A little cleaner I think.

Flattr this!

VLOOKUP For JavaScript

A user on StackOverflow wanted to know if VLOOKUP for Excel existed in JavaScript. Short answer is: no. However, it can be mimicked quite easily using the following:

Array.prototype.vlookup = function(needle,index,exactmatch){
  1.     index = index || 0;
  2.     exactmatch = exactmatch || false;
  3.     for (var i = 0; i < this.length; i++){
  4.         var row = this[i];
  5.  
  6.         if ((exactmatch && row[0]===needle) || row[0].toLowerCase().indexOf(needle.toLowerCase()) != -1)
  7.             return (index < row.length ? row[index] : row[0]);
  8.     }
  9.     return null;
  10. }

Short, but sweet. Basically, call this method off any (double) array variable and it will simulate the VLOOKUP of Excel. If no entry is found, it will return null. If the index specified exceeds that row’s element length, the first element is returned.

Flattr this!

Reverse two numbers without an additional variable

So I came across a post on StackOverflow today that intrigued me. It was a question on reversing two numeric values without the use of additional variable (i.e. temp, or what ever you’d like to call it). The code went as follows:

i = i + j; j = i - j; i = i - j;

Simple, right? Arguably not as simple to pick up on when you don’t know what to look for, but certainly alleviates an additional variable, which I am all for.

Just thought I’d pass this tiny little piece of code along.

Flattr this!

Convert Date to ISO Format

An instance came up on StackOverflow where a user wanted to convert a date stamp to the UTC facsimile, but in ISO format. So, with several other responses, and some playing around, I wanted to come up with a nice stream-line version. Here is what I came up with:

Number.prototype.pad = function(width,chr){
  1.  chr = chr || '0';
  2.  var result = this;
  3.  for (var a = 0; a < width; a++)
  4.  result = chr + result;
  5.  return result.slice(-width);
  6. }
  7. Date.prototype.toISOString = function(){
  8.  return this.getUTCFullYear().pad(4) + '-'
  9.  + (this.getUTCMonth()+1).pad(2) + '-'
  10.  + this.getUTCDay().pad(2) + 'T'
  11.  + this.getUTCHours().pad(2) + ':'
  12.  + this.getUTCMinutes().pad(2) + ':'
  13.  + this.getUTCSeconds().pad(2) + 'Z';
  14. }
  15. // usage
  16. var d = new Date;
  17. alert(d.toISOString());

It’s very simple, but in-line and convenient. This can be called directly off a date object, and returns the date in UTC YYYY-MM-DDTHH:MM:SSZ format (also known as ISO 8601 Format).

Flattr this!

Well, it’s officially up

I’ve conformed; I am officially a blogger.

I don’t know how this will all work honestly. I am anticipating using this for the purpose just posting tidbits of code I come across along the way. Basically, if I develop something I think others could use, if I find a piece of code that was hard to search for but is useful, or just general cool solutions to problems I come up with I’ll post it here.

In recent months I’ve been expanding my horizons and have come to know the MSDN Social site, the [in]famous StackOverflow website, and other personal blogs. This has been helpful in countless ways and I feel it’s my time to contribute.

So, with all that being said here is my blog. I hope you find something helpful on it, even if it’s a determination of what not to do. As always, feel free to comment on things I’ve posted (community involvement is a powerful tool).

Flattr this!