Error Handling in ASP.NET MVC 1 [Part 2 of 2]

In the first post in this series, I provided a little info on the HandleError attribute in MVC 1.  In case you don’t want to flip back, the HandleError attribute can decorate a method or a class and will push your users to a generic errors view provided customErrors is “On” or “RemoteOnly”.  There’s a little more to it, but that’s all the background we need for this post.

The out-of-the-box HandleError attribute works well, until you’re in a scenario where you need to do more than hide your errors.  Typically, you may want to do some logging or fire-off some alerts.  Now, as luck should have it, I did some searching before writing this up and Danny Tuppeny already has a great post on this very subject…I encourage you to take a peak at his post, as I’ve provided a very high-level, yet functional summary below.

The facts are these…

- System.Web.Mvc.Controller contains an OnException method that gets fired when an exception occurs [provided custom errors are On/RemoteOnly in the web.config]

- The OnException method can easily be overridden, allowing you to either completely change behavior or add behavior (by calling base.OnException)

- This method will fire regardless of whether your class or method is decorated with HandleError

This means that your could will look like this:

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Linq;
   4: using System.Web;
   5: using System.Web.Mvc;
   6:  
   7: namespace MvcErrorHandling.Controllers
   8: {
   9:     public class ControllerBase : System.Web.Mvc.Controller
  10:     {
  11:         protected override void OnException(ExceptionContext filterContext)
  12:         {
  13:             //Do whatever stuff you'd like
  14:             DoSomeOtherStuff();
  15:             
  16:             //Displays a friendly error, doesn't require HandleError
  17:             filterContext.ExceptionHandled = true;
  18:             this.View("Error").ExecuteResult(this.ControllerContext);
  19:             
  20:             //Displays a friendly error, *requires* HandlError
  21:             //base.OnException(filterContext);
  22:         }
  23:  
  24:         protected void DoSomeOtherStuff() { /* brevity */ }
  25:     }
  26: }

To get the above code to work you’d simply make your controller inherit from ControllerBase.  Of course, you’d likely have additional utility-methods in this class that you’d need in multiple controllers. 

Lines 17 and 18 can be used to push the user to your error view after you execute the DoSomeOtherStuff() method – this would not require the HandleError attribute.  Alternatively, you can execute System.Web.Mvc.Controller’s OnException by calling it explicitly as it’s done on line 21.  In this case, the HandleError would be required to push your use down the custom-error path you’ve got configured. 

And that’s pretty much all there is to centralizing & customizing your error-handling in MVC 1.  

kick it on DotNetKicks.com

Share this post :

Technorati Tags: ,

Error Handling in ASP.NET MVC 1 [Part 1 of 2]

I’ve been using ASP.NET MVC Release 1 for a bit now, and while it’s definitely not for every application, I happen to like it quite a bit.  There has been a lot of activity on MS-centric blogs regarding MVC, but there are still some really mundane tasks that there could be more information on.  So, this series of posts isn’t going to be anything crazy; it will, however, illustrate what options you have to do centralized error-handling using MVC 1.

We’ll start at the beginning…

The System.Web.Mvc.dll comes with the HandleErrorAttribute class, which contains..wait for it…the HandleError attribute.   This information won’t be important until later in this series, but the HandleErrorAttribute class inherits from the FilterAttribute class, and implements the IExceptionFilter interface – the interface requires a method with the following signature. 

public virtual void OnException(ExceptionContext filterContext);

This method is really where the brunt of the work is done when you use the provided [HandleError] attribute.  In case you’ve never taken a look using Reflector, this HandleErrorAttribute’s implementation of OnException looks like this:

public virtual void OnException(ExceptionContext filterContext)
  {
      if (filterContext == null)
      {
          throw new ArgumentNullException("filterContext");
      }
      if (!filterContext.ExceptionHandled && filterContext.HttpContext.IsCustomErrorEnabled)
      {
          Exception innerException = filterContext.Exception;
          if ((new HttpException(null, innerException).GetHttpCode() == 500) && this.ExceptionType.IsInstanceOfType(innerException))
          {
              string controllerName = (string) filterContext.RouteData.Values["controller"];
              string actionName = (string) filterContext.RouteData.Values["action"];
              HandleErrorInfo model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName);
              ViewResult result = new ViewResult();
              result.ViewName = this.View;
              result.MasterName = this.Master;
              result.ViewData = new ViewDataDictionary<HandleErrorInfo>(model);
              result.TempData = filterContext.Controller.TempData;
              filterContext.Result = result;
              filterContext.ExceptionHandled = true;
              filterContext.HttpContext.Response.Clear();
              filterContext.HttpContext.Response.StatusCode = 500;
              filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
          }
      }
  }

Essentially, you’re grabbing some information from the ExceptionContext, and you’re using the HandleErrorInfo class to pass this information back to your view.

Using [HandleError] is really as easy as using any other attribute.  You simply decorate your method or class with the attribute and your errors will be pushed to the default view for errors (Views/Shared/Error.aspx)

Sample usage of [HandleError]:

namespace MvcErrorHandling.Controllers
{
    [HandleError]
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            if (true)
            { 
                throw new ApplicationException("Some error...");
            }
            return View();
        }
        //removed...

Alternatively, you can provide the HandleError attribute with some arguments to specify a view other than the default error-view, or specify a specific view based on the exception type.  Here’s an example of the usage for that…

[HandleError(ExceptionType = typeof(ApplicationException), View = "AppErrorPage")]
public class HomeController : Controller
{
    public ActionResult Index()
    {
        if (true)
        { 
            throw new ApplicationException("Some error...");
        }
        return View();
    }
    //removed...

The only other thing you’ll want to make sure you do is ensure your web.config <customErrors> section is configured appropriately.  That is, you’ll want to make sure customErrors mode=”On” to test this out.

Hope this helps somebody; the next part in this series will demonstrate how to add functionality to the existing OnException method that the HandleErrorAttribute class implements, such as logging.

kick it on DotNetKicks.com

Share this post :

Technorati Tags: ,

Adventures in WF 3.0/3.5

Until redesign of WF 4.0 is completed & released, I’m going to have to put up with this.  I’ve been working some WF stuff the past few days.  One of the very annoying things about working with the VS designer environment is, well, frankly – the designer.  It’s entirely inconsistent.  Sometimes, when I need to add a normal property (not a dependency property) – doing things the normal way gets me there.  In other words, I add this code to the activity code:

public int MyProperty { get; set; }

and in the designer (right click activity > properties > under “Misc”), I see what I’m supposed to see (umm..right? I’m supposed to see this??)

WFDesignerSupposedToSee

…and everything is right in the world.  Then, 10 minutes you take the identical steps, only with a new property and to your amazement, absolutely nothing happens and you’re left wondering if someone killed a butterfly in a rainforest or something.  Well, I have no idea what happened…but I can tell you that a restart of the IDE is what works for me.  Yep, that’s right…it’s the old Windows 98 solution to things.  Try it.

Now, the above scenario was with a “normal” property – not a dependency property.  Well, turns out the same thing can happen with dependency properties – which I was fortunate enough to have experienced yesterday.  I would assume the above restart-the-ide “solution” would work for that, as well.  In case it doesn’t, though, it turns out you can actually access dependency properties by doing this…It’s not that pretty – but it definitely works.

someLocalVarFoo = ((SourceNamespace.SourceClassName)this.GetActivityByName("ActivityName")).PropertyName;

Get the index of a given item using LINQ [quick-tip]

It took a bit for me to get comfortable enough with LINQ-to-objects to write ‘queries’ off the top of my head…but once you’re used to it you realize it’s much more concise, easier to interpret/read, and well..it’s less code.  Here are some real quick examples…

This first example selects the string array value as well as its position from the someItems array.  Note, the user of new{} creates a new generic type that has the properties ItemName and Position.  I could have called these two properties whatever I pleased, because I’m creating them at query-time.

string[] someItems = { "cat", "dog", "purple elephant", "unicorn" };
 
var selectedItems = someItems.Select((item, index) => new
{
    ItemName = item,
    Position = index
});

After you run this, selectedItems will look like this….

selItems 

And if you needed to just get the position as an int to use that for some other logic, your code may look like this..

int firstItem = someItems.Select((item, index) => new
{
    ItemName = item,
    Position = index
}).Where(i => i.ItemName == "purple elephant")
  .First()
  .Position;

In which case, firstItem would equal 2.  Naturally, this is only the beginning of what LINQ to objects can do for you – but it definitely illustrates how LINQ can ease your daily coding.

Technorati Tags: ,,,

Returning values from your LINQ queries [quick tip]

Just a quick tip that I found handy while doing some writing yesterday; chances are if you’ve played with LINQ you probably wrote something like this…

var outputString = from s
                   in inputString
                   where s.Length > 1
                   select s;
 
//Do some stuff with outputString in your method...

Code like the above will work perfectly well if what you’re going to work with your implicit variable, outputString, within the body of the same method.  But, as it stands, you can’t return outputString, or any implicit variable from your method.  Try it, I dare you.  At this point, you’re probably thinking “Wait, can’t I just do a outputString.ToList() or .ToArray() and return that?  Yes – you can.  The catch with doing that, though, is that your LINQ expression is going to be evaluated right there and then.  This might be fine for you, or it might not – but you should be aware of the deferred query execution model that LINQ embraces. 

In any case, the easy way out of this assuming you’d prefer to defer execution until you enumerate is actually very straightforward….You can simply return an IEnumerable<T>.  So, something like…

static IEnumerable<string> DoLinqStuff(string[] inputString)
{
    //You can do this and return an IEnumerable<string>
    IEnumerable<string> outputString =  from s
                                        in inputString
                                        where s.Length > 1
                                        select s;
 
    return outputString;
}

That way, you can do the following to leverage your LINQ expression in an external method while leaving the deferred execution model in-tact…

//Remember this isn't evaluated yet...
IEnumerable<string> myReturnedStuff = DoLinqStuff(myStrings);
 
//It's getting evaluated now...
foreach (string s in myReturnedStuff) {
    Console.WriteLine(s);
}

Or if you want to be a bit more concise about it…

//Same thing but slightly less code...
foreach (string s in DoLinqStuff(myStrings)){
    Console.WriteLine(s);
}

Okay, so it wasn’t exactly rocket-science but I figure it may be helpful. 


kick it on DotNetKicks.com

 

Share this post :

 

Technorati Tags: ,,,

If you are thinking about using Windows Work-Flow…you should know…

That MS decided to totally blow it up in .NET 4.0. (weblogs.asp.net link, S/O link).  Yes, that’s right, they are totally re-writing WF 4.0  from the ground-up.  As the first link states, this could be for any number of reasons including lack of adoption and the perception that WF is just too complex – which I happen to agree with.  3.0/3.5 workflows will still work, but only on the 3.0 runtime. 

On the one hand, I have to give some credit to MS for basically saying “Hey guys, we effed up and we’re gonna scrap this…”, and yet, on the other I have to assume it’s a little embarrassing to have to do something like this. 

WebTV

 

 

 

 

 

 

 

 

BTW, Is this old news?  How did I totally miss the memo on this?

 

Share this post :

 

Technorati Tags: ,

Surprising jQuery Performance Tip

Was doing some research this morning, as usual, and came across a post from Giulio Bai on jQuery performance tips.  A lot of his tips are things I’ve heard elsewhere (no offense!), but one that I haven’t seen anywhere and for some reason surprised me is that using a the JavaScript provided for() loop is considerably faster than using jQuery’s each() function.  In fact, it can be several orders of magnitude faster depending on what you’re doing.  Interesting. 

Link to his post

Technorati Tags: ,

If you value your privacy, do this now…

I’ll keep it short and sweet.  Was browsing this new twitter thing that all the kids are playin’ with and I saw an link to this story: You Deleted Your Cookies?  Think Again.  Short version: You can create cookie-like objects with flash, that:

  1. Don’t get deleted from your machine when you clear cookies
  2. Can be used to re-spawn browser-based cookies if you delete them
  3. Can do a whole bunch of annoying stuff that you probably don’t want done to your machine
  4. To disable this on your browser, go to the following URL: http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager03.html
    and uncheck “Allow third-party Flash content to store data on your computer”
    Keep in mind, you’ll need to do this on each of your browsers
    Technorati Tags: ,

XmlSerializer & XmlSerializerFactory: I’m sort of positive you aren’t insane.

A few weeks back I was doing some pokin’ around the ol’ web regarding reading XML from somewhere (database, file-system, the trunk of your car) and into an .NET object.  In case you weren’t aware…it turns out .NET makes doing this type of work nothing short of trivial. 

<slightly off-topic background info>

That is, if you had XML that you [stole from MSDN] that looked like this…

<?xml version="1.0"?>
   <book>
      <author>Gambardella, Matthew</author>
      <title>XML Developer's Guide</title>
      <genre>Computer</genre>
      <price>44.95</price>
      <publish_date>2000-10-01</publish_date>
      <description>An in-depth look at creating applications 
      with XML.</description>
   </book>
...

…and you had an object that looked like..

public class Book{
    string author{get; set;}
    string title{get; set;}
    string genre{get; set;}
    decimal price{get; set;}
    date publish_date{get; set;}
    string description{get; set;}
}

You could do this…

XmlSerializerFactory xmlSerializerfactory = new XmlSerializerFactory();
XmlSerializer serializer = xmlSerializerfactory.CreateSerializer(typeof(book));
book myDeserializedBook = (book)serializer.Deserialize(responseStream);

And you magically have a populated instance of the book class with the values from the XML file above.

</slightly off-topic background info>

The first time you deserialize an object of a particular type, the framework creates an assembly of that type on-the-fly which incurs some overhead.  This is the same way the older, .NET Framework provided XmlSerializer works.  (This is also how I go the title for this post)  The difference is that XmlSerializerFactory is supposed to cache these assemblies the first time they are created.  Well, bad news kids, if you use any of the following constructors besides the first, the .NET Framework won’t cache the assembly. 

CreateSerializer(System.Type)
CreateSerializer(System.Type, string)
CreateSerializer(System.Type, System.Type[])
CreateSerializer(System.Type, System.Xml.Serialization.XmlAttributeOverrides)
CreateSerializer(System.Type, System.Xml.Serialization.XmlAttributeOverrides, System.Type[], System.Xml.Serialization.XmlRootAttribute, string)
CreateSerializer(System.Type, System.Xml.Serialization.XmlAttributeOverrides, System.Type[], System.Xml.Serialization.XmlRootAttribute, string, string, System.Security.Policy.Evidence)
CreateSerializer(System.Type, System.Xml.Serialization.XmlRootAttribute)
CreateSerializer(System.Xml.Serialization.XmlTypeMapping)

Daniel Cazzulino pointed this out, and I’m thankful to have come across his post in my XmlSerializerFactory investigation. 

I ended up going with code that resembles this with the exception of opting not to use the XmlSerializerFactory since it doesn’t seem like it buys me anything over the standard XmlSerializer if I’m not using the (System.Type) constructor.

Share this post :

 

Technorati Tags: ,,

Adding “Open with reflector” to your right-clicks….

I feel like these days I’m constantly using reflector to dissect assemblies and [can’t believe I’m going to say this but] opening reflector every time is too much work.  It just means like it’d be a lot easier if I could right click a DLL and select “Open with reflector” – just like I do with 7-Zip and the Tortoise SVN client.  Well…this is how you do that.

Adding the “Open with reflector” to your right-click menu

Open up windows explorer (Windows Key + E)

Go to “Tools” > “Folder Options” & select the “File Types” tab

FolderOptions

Look for the DLL extension.  If you don’t have it, and I didn’t, go ahead and add it using the steps below.  If you do have it, then skip the “Adding the DLL extension to your registered file types” section…

Adding the DLL extension to your registered file types

1. Click “New” under the “Registered file types” list

2. Enter the DLL file extension, and select “Application Extension” in “Associated File Type” drop-down.

3. Click “OK” – you’re done.

Step 2:

Back on the “Folder Options” window, highlight the DLL  extension and select “Advanced”.  That should bring you to the “Edit File Type” window below.

EditFileTypes2

Go ahead and click “New” to add a new action.  This will open up the window below.  We will want to add the action text “Open in reflector” and the path to Reflector.  Don’t forget the quotes!

CreateExt2

Click “OK”.  Go ahead and navigate to a directory where you’ve got some DLLs.  The finished product should look like this…

FinishedProduct

Bask in glory.


kick it on DotNetKicks.com

 

Share this post :

 

Technorati Tags:

ASP.NET Charting: Rendering Options

With the release of .NET 3.5 SP1, MS has released a sub-set of the Dundas charting component. They also put together a neat little solution that’ll let you run a number of examples/samples locally so you can get your hands dirty. If you’re looking to do any work with the charting components, or just play around getting these samples should definitely be your first step as the basics will be self-explanatory. The link for that is here.

Now that we got the boring introductory stuff out of the way; the .NET charting component gives you a few different choices when it comes to rendering your chart/image.

Temp directory/ImageTag/ImageUrl Method

This is what I’d consider the simple/out-of-the-box method. Basically, when you create your chart either in the designer or in a code-behind you can specify where the chart should live. This means that ASP.NET will create a chart based on some data that you provide, dump it in a temporary directory, and then you’ll refer to it just as you would any other image.

In other words, your designer markup may look like this:

<asp:chart id="Chart1" 
  runat="server" 
  Height="296px" 
  Width="412px" 
  ImageLocation="~/TempImages/ChartPic_#SEQ(300,3)" 
  Palette="BrightPastel" 
  BorderDashStyle="Solid" 
  BackGradientStyle="TopBottom" 
  BorderWidth="2" 
  backcolor="#D3DFF0" 
  BorderColor="26, 59, 105"
>

And, at runtime, the server will spit out something like the following:

<img id="Chart1" 
  BorderDashStyle="Solid" 
  src="/WebSamples/ChartImg.axd?i=chart_00090164d2f6498095a78f42f0b28216_1.png&amp;g=772eca8a160b4cb291bfe41a00e762a7" 
  alt="" 
  style="height:296px;width:412px;border-width:0px;" 
/>

Look familiar? That’s roughly what an ASP:Image control would render to had you dropped one of those onto the page. The only difference is that your SRC tag points to a HttpHandler that you specified in your web.config.

In any case, using this method is very straight forward and your client’s browsers will cache your charts just as they would any other image. Of course, the image file that gets cached will look like this:

ChartImg.axd?i=chart_00090164d2f6498095a78f42f0b28216_0.png&g=ec1fd46ebf42485894656b42606e5b27

…The MSDN documentation states that for static data, this caching improves performance. However, in my experimenting even with static data a refresh of the page causes the querystring parameters to change…which means you will need to pull it back down from the server, which also means the browser cached it for nothing. (Although this is what my experimenting indicated, I’m wondering if I missed something. Information to the contrary is welcome…anyone…?...crickets?)

Binary Streaming Method

Now, if you looked at the MS Chart Samples solution, you’ll notice that I’m skipping a couple of “rendering methods” here. That’s largely because I’m thinking if you’re still reading this, you already know you can render a chart in an iFrame, and because their guidance on rendering charts within legacy websites is essentially “use Binary Streaming”.

Binary Streaming is implemented by doing either one of the following

Keep in mind an asp:Image control is getting translated to an IMG tag anyway. In both cases, SomeChart.aspx contains the designer construct for a chart. Something like the following [which is snipped]:

<img src="SomeChart.aspx" width="412" height="296" alt=""/>

Or…

<asp:Image id="Image1" runat="server" ImageLocation="SomeChart.aspx" 
/>

Keep in mind an asp:Image control is getting translated to an IMG tag anyway. In both cases, SomeChart.aspx contains the designer construct for a chart. Something like the following [which is snipped]:

<%@ Page Language="c#" Inherits="Samples.SomeChart" CodeFile="SomeChart.aspx.cs" %>
<asp:chart id="Chart1" runat="server" height="296px" width="412px" 
    imagetype="Png" palette="BrightPastel" backcolor="#F3DFC1" rendertype="BinaryStreaming"
    borderdashstyle="Solid" backgradientstyle="TopBottom" borderwidth="2" bordercolor="181, 64, 1">
    <series>
        <asp:Series ChartTypeName="SplineArea" Name="Series1" BorderColor="64, 64, 64" ShadowOffset="2">
            <points>
                <asp:DataPoint YValues="6" />

With this method, you’re basically telling the chart that you’d like it to return a Binary Stream (surprise). In essence, the content of the server’s response will be the string representation of the binary object which your browser will render as an image. In a sense, it’s similar to making a request directly to ChartImg.axd directly. The difference here is you’re creating the binary representation of the chart from memory rather than a physical location on disk.

Both of these methods are very easy to set-up and require little to no-thought. I have to admit using a temporary directory feels a little icky but that may just be my OCD kicking in.

There’s another way, though.

If for some reason these two methods don’t jive with you, though, there is another way. It’s sort of hacky – but it works. Basically, you can convert a binary stream to Base64 and return the string directly to the image tag.

<img src='data:image/png;base64, iVBORw0KGgoAAAA[snip]; />
That means that you can generate your chart entirely in a codebehind and then just return the string via an AJAX request.
//Generate your chart
System.Web.UI.DataVisualization.Charting.Chart Chart1 = new System.Web.UI.DataVisualization.Charting.Chart();
//Save it to a stream and return it
System.IO.MemoryStream imageStream = new System.IO.MemoryStream();
Chart1.SaveImage(imageStream, ChartImageFormat.Png);
return Convert.ToBase64String(imageStream.ToArray());

All in all the, binary streaming or the Temp Directory method for chart rendering will probably satisfy your requirements 80% of the time.  It would be interesting to see how each of these scale/perform in a heavily loaded environment.  Hopefully, this provided you with a sufficient high-level overview of your chart rendering options. 

Share this post :

Remotely Enabling Remote Desktop from the Command Line

Okay, this is a very easy find if you search for it…but also very handy (Thank you My Digital Life).  Save as a CMD file and use as directed…

@echo off
@echo Remote RDP Enable Script by My Digital Life
@echo -------------------------------------------
@echo.
setlocal
if {%1}=={} goto syntax
:loop
if {%1}=={} goto finish
set remote="\\%1\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server"
shift
reg.exe ADD %remote% /v fDenyTSConnections /t REG_DWORD /d 0 /f>;nul 2>&1
if NOT %ERRORLEVEL% EQU 0 @echo %remote% NOT found.
goto loop
:syntax
@echo No computer name or host name specified.
@echo.
@echo Syntax: RemoteDesktop Computer1 [Computer2 .... Computern]
goto loop
:finish
endlocal

Share this post :

 

Technorati Tags:

Very Impatient & Moderately Lazy: Shortcuts

Very impatient, moderately lazy;  I use the keyboard to do whatever I can whether I’m in Visual Studio, navigating the web, or just moving around the O/S.  For example, if I need to  launch word I’m just going to hit the Windows Key + R and then type WinWord.  I use that technique for basically anything I know the application name for…notepad, calc, whatever.  If the application name is “too much” for me to type I’ll create a real old-skool bat file and throw it into my C:/Windows/System32/ folder.  A few of the handy ones that I use lately are the following…

REM Clear cache in IE
start "" "RunDll32.exe" InetCpl.cpl,ClearMyTracksByProcess 8
exit
REM Google something on a new FF tab
REM usage example: g "C# Generics"
echo off
start "" "C:\Program Files\Mozilla Firefox\firefox.exe" http://www.google.com/search?q=%1
exit
REM Launch VS2008
echo off
start "" "C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\devenv.exe" /nosplash"
exit

It’s not exactly rocket-science but it works pretty well.

Share this post :

 

Technorati Tags:

Learning doesn’t work if you don’t do it right…

So...there isn't really any denying that there is a lot to learn.  New releases from MS, new tools from third-party provides, new libraries..whatever it may be.  It's pretty unrealistic, at least with my current brain, to be able to learn all of that stuff while still having any kind of a life.  Sure, I squeeze in a book on the subway, and my idea of goofing-off at work is going to DotNetKicks.com and checking out what's late and great in .NET today.  That all said, I suspect it may be at least as important to learn how to learn as it is to do your reading and experimenting ("Do the learning" so to speak).  That sounds sort of silly and obvious to some extent, I'm sure, but it may be worth thinking about for a few minutes.  Also, this is a topic that there is considerable about of information on…an easy search* of “how to learn” gets you 365,000 results.  This is only the 4th result and it already has some fantastic insightful ideas…

The Rev. Charles Lutwidge Dodgson (1832-98) wrote under the pseudoym Lewis Carroll, and is primarily known for Alice in Wonderland and Through the Looking Glass. Carroll was a mathematician, photographer, inventor of puzzles and games, and wrote light verse. When he wrote on mathematics and logic it was not without whimsy, as evidenced by the following introduction to his book on Symbolic Logic. In any case, this is excellent advice on how to read any textbook.]

[snip]

  1. Begin at the beginning, and do not allow yourself to gratify mere idle curiosity by dipping into the book, here and there. This would very likely lead to your throwing it aside, with the remark `This is much too hard for me!', and thus losing the chance of adding a very large item to your stock of mental delights . . .
  2. Don't begin any fresh Chapter, or Section, until you are certain that you thoroughly understand the whole book up to that point and that you have worked, correctly, most if not all of the examples which have been set . . . Otherwise, you will find your state of puzzlement get worse and worse as you proceed till you give up the whole thing in utter disgust.
  3. When you come to a passage you don't understand, read it again: if you still don't understand it, read it again: if you fail, even after three readings, very likely your brain is getting a little tired In that case, put the book away, and take to other occupations, and next day, when you come to it fresh, you will very likely find that it is quite easy.
  4. If possible, find some genial friend, who will read the book along with you, and will talk over the difficulties with you. Talking is a wonderful smoother-over of difficulties. When I come upon anything—in Logic or in any other hard subject—that entirely puzzles me, I find it a capital plan to talk it over, aloud, even when I am all alone. One can explain things so clearly to one's self! And then you know, one is so patient with one's self: one never gets irritated at one's own stupidity!

As the excerpt mentions these are suggestions for text-books…so you could easily draw a parallel to reading a technical book (as opposed to a blog, or article).  In that context and in my opinion – these suggestions are spot-on. 

My bottom line: if you’re going to put forth the effort learning, you should learn how to do it right.

*I have no qualms with google but I’m trying to get out of the habit of using the term “google” as if it is a synonym for “search”

Share this post :

Technorati Tags: ,

FireFox Plugins/Addons for Development

Over on InstantShift.com Dkumar M has put together a great list of FireFox add-ons.  The add-on range from web-page eyedroppers [link] to tools that will let you get screenshots of your page in IE from FF [link].  Naturally since I have zero artisitic capability, I gravitated towards the the add-ons that were code-centric.  The most notable add-ons are listed below.  Check out the article [link] and other useful articles by Dkumar M [link].

Name Description
ColorZilla Bottom line: This allows you to grab a hex color-code from any element on a web-page.  It also has functionality built-in for measuring distances within a web-page and some other stuff.
Palette Grabber Creates palettes from web-sites (perhaps from CSS) and outputs a file readable by Photoshop, Gimp, and others.
JSView Allows you to view source on JavaScript files that are referenced on a page without having to type in the URL.
JavaScript Debugger The name of this should be pretty self-explanatory.  Some say this conflicts with FireBug, so watch out for that.

 

Enjoy.

Share this post :
Twitter