Blog of Developer Mikkel Ovesen
This blog is actually meant for me only... I will use it mainly to help me remeber code snippets, usefull add-ins and links and other information that I regards as important in my work as a developer

Dynamically Loading ASP.NET User Controls with jQuery

December 25, 2008 18:17 by mikkel@ovesens.com

 

This post is only relevant if you are using WebForms. If you have converted to the MVC approach, then go read about Dependency Injection or NHibernate :)

If however you are using WebForms or are maintaining an application that was build with WebForms. Here is a way to partially render a usercontrol via jQuery (ajax).

Introduction

User controls are a great way to group markup and functionality, but in these AJAX times, the problem and nature of User Controls, in relation to ajax, is their fixed position in the Page Control tree.

Sam Mueller describes the issues and gives his solution to dynamically loaded user controls using jQuery.

Read it here:

http://samuelmueller.com/post/2008/12/20/Dynamically-Loading-ASPNET-User-Controls-with-jQuery.aspx

Sam Muellers raises some very interesting points, however I have two things I would like to change (URL and security).

URL

I very much like that Sam Mueller has found a solution to "directly" call a user control (view) with an URL. What I do not like is the URL to be called:

/ajax.svc/renderuc?path=/usercontrols/myusercontrol.ascx

I would like to be able to call the user control directly by this kind of URL:

/usercontrols/myusercontrol.ascx

And by using a HttpHandler this is possible. I have written an example here:

   1: public class AjaxUserControlHandler : IHttpHandler
   2:     {
   3:         public void ProcessRequest(HttpContext context)
   4:         {
   5:             // Get the path to the user control
   6:             string path = context.Request.Url.LocalPath;
   7:  
   8:             // Intialize the pseudo page and user control
   9:             Page page = new Page();
  10:             UserControl viewControl = page.LoadControl(path) as UserControl;
  11:  
  12:             // Display error if the user control was not found
  13:             if (viewControl == null)
  14:             {
  15:                 context.Response.StatusCode = 404;
  16:                 context.Response.Output.WriteLine("The requested url was not found");
  17:                 return;
  18:             }
  19:  
  20:             // Check existense of the AjaxEnabled attribute. Only add the AjaxEnabled attribut to 
  21:             // user controls that is safe for direct calls
  22:             var type = viewControl.GetType();
  23:             var attributes = type.GetCustomAttributes(typeof (AjaxEnabledAttribute), true);
  24:             AjaxEnabledAttribute attribute = attributes.FirstOrDefault() as AjaxEnabledAttribute;
  25:  
  26:             // If the attribute was not found, display an error
  27:             if (attribute == null)
  28:             {
  29:                 context.Response.StatusCode = 403;
  30:                 context.Response.Output.WriteLine("Access to the resource is not allowed");
  31:                 return;
  32:             }
  33:  
  34:             
  35:             // Check if the request is valiud with regards to the requirements of the attribute.
  36:             // If not, display error
  37:             if ((attribute.Method == RequestMethodSupport.GET && context.Request.RequestType != "GET")
  38:                 || (attribute.Method == RequestMethodSupport.POST && context.Request.RequestType != "POST"))
  39:             {
  40:                 context.Response.StatusCode = 403;
  41:                 context.Response.Output.WriteLine(string.Format("The request method {0} is not allowed.", context.Request.RequestType));
  42:                 return;
  43:             }
  44:  
  45:             // Add user control to the pages control tree
  46:             page.Controls.Add(viewControl);
  47:  
  48:             // Disable caching, remove this if you will allow client caching
  49:             context.Response.CacheControl = "No-Cache";
  50:  
  51:             // Execute and return result to Output stream
  52:             context.Server.Execute(page, context.Response.Output, true);
  53:         }
  54:  
  55:         public bool IsReusable
  56:         {
  57:             get { return true; }
  58:         }
  59:     }

 

To make it work, you need to add the following to httpHandlers tag in the web.config.

<add verb="*" path="*.ascx" type="[NAMESPACE].AjaxUserControlHandler, [ASSEMBLY]"/>

 

Security

I have implemented an AjaxEnabled attribut, so that it is not possible to directly call any of the user controls (if you know the path to them) in the solution.

The attribute is simple and looks like this:

   1: public class AjaxEnabledAttribute : Attribute
   2: {
   3:     [DefaultValue(RequestMethodSupport.All)]
   4:     public RequestMethodSupport Method { get; set; }
   5: }
   6:  
   7: public enum RequestMethodSupport
   8: {
   9:     All,
  10:     GET,
  11:     POST
  12: }

 

By doing this, the handler will only allow calls to user controls that have the [AjaxEnabled[ attribute, like this:

   1: [AjaxEnabled]
   2: public partial class Test : System.Web.UI.UserControl
   3: {
   4:     ...

 

Conclusion

With the HttpHandler, and the attribute in place, my two concerns (url and security) are dealt with.

You are now able to call a user control directly:

/usercontrols/myusercontrol.ascx

And you are only able to call user controls that have the AjaxEnabled attribute.

Any comments and suggestions are welcome btw :)


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

How will you parallelize your existing codebase? Try R.A.S.P

December 24, 2008 14:08 by mikkel@ovesens.com

Original post:

http://www.atalasoft.com/cs/blogs/rickm/archive/2008/12/23/how-will-you-parallelize-your-existing-codebase-try-r-a-s-p.aspx

----------------------------------------------------------------------------------------------------------------------

How will you parallelize your existing codebase? Try R.A.S.P.

There has been much talk of how we will be writing all of our new code with parallelization in mind.  However, what of our existing code?  It’s unlikely that everyone will just suddenly dump decades of existing code and write everything from scratch.  In this article I’m going to provide a simple methodology for how we might deal with the ever building problem of parallelizing our existing mountains of code.  Comments and contributions are welcome.

 

Methodologies of the Past

From the STL to .NET, the frameworks we have constructed our applications around have been heavily dependent on the idea of an application having a single thread.  Given that the foundation of what we have all been using for a very long time was constructed around this preconception, it’s unreasonable to expect that much of our existing code will ever be fully parallel.  Even those that wrote code on top of a thread safe framework may find that years of patches and and poor design decisions make ground up parallelization impossible.

If we set our expectations reasonably, we see that we should instead focus on leveraging parallelism to improve the performance of the slowest parts of our software.  From this viewpoint, parallelization is an optimization problem.  Like all optimization, the difficulty of parallelizing code will have much to do with the methodologies which were used to write it.  

Of course, object-oriented code being written with modern S.O.L.I.D. principles and will be easier to parallelize than older procedural code.  At the same time, a poorly organized codebase or poorly written code will always make change difficult and so also hard to parallelize.  This is why well written code is worth the investment.  We will see the investment paying off in spades for the companies who have bothered to care about code quality.  Others who find they have spaghetti code under the hood will find they will need to deeply segregate and modularize before parallelization is possible.

 

A Methodology for Revisiting the Past

In most cases it would be a poor choice to implement your own threading API.  Efficient and easy to use parallelization APIs are coming to (or already part of) every commonly used language and framework.  Most of these APIs are not only built on top of years of research, they also have been written and debugged by a large number of people with specific expertise.  These APIs are a godsend because they will allow most developers to parallelize existing software with a minimum amount of pain.  The parallelization of existing code bases will be much the same as any other kind of performance tuning. 

The key will be using a profiler to identify places in the code that would be sped up by parallelization and leveraging these new APIs to take advantage of the available hardware.  The exciting part is that this can be done with any existing profiler and many existing APIs.  The unfortunate part is that because memory sharing is such a big issue, parallelization requires a degree of separation beyond other types of optimization and so is likely to require some amount of refactoring.

Not all types of performance problems are conducive to being solved by parallelization, careful evaluation of the problem at hand is required.  Also, as with anything that requires significant code change, building a solid test fixture is key to introducing as few bugs as possible.  By leveraging the ideas of avoiding premature optimization, pragmatic unit testing, using existing APIs, and mindful refactoring it will be possible to introduce parallelization into many already existing projects with a manageable amount of risk.

 

What is RASP?

While not included in the acronym, the first step in any kind of optimization is profiling.  Before you can begin to parallelize your code, you must determine where the bottlenecks might be.  A broadly defined list of parallelizable things to look for would be, to quote Rich Hickey, “independent data/work, moderate-to-course-grained work units and/or complex coordination logic that would be simplified with threads”.  A couple quick examples of low hanging fruit to be on the lookout for would be slow iterative loops and blocking I/O.  It is important to note that as a general guideline it would be wrong to parallelize anything if it would not significantly increase the speed of your software.

For each of the bottlenecks found while profiling, parallelization is best separated into four steps:

Review: Review code to determine if it is a good candidate for parallelization.
Anchor: Create a unit test fixture to ensure that the behavior of the to be parallelized code does not change.
Separate: Ensure that the to be parallelized code has no shared memory constraints, and if it does, factor them out if possible.
Parallelize: Minimally refactor for parallelization while leveraging an existing API to do the heavy lifting.

As the specifics of what each of these would entail depends greatly on exactly which platform and language is in use, I will not go into them deeply now.  Overall, it’s a simple methodology but I think both sufficient for the task at hand and broadly applicable. 

 

Conclusion

Review, Anchor, Separate, Parallelize.  It’s not intended to be a difficult concept but instead to provide a simple path to parallelization.  I would be very interested in hearing about any opinions on what RASP might be missing or how it may be better clarified.  While I didn’t have time to discuss them deeply in this post, parallelization patterns are also a key concept in using RASP as if you can’t easily identify what can be parallelized than it would be impossible to use any parallelization methodology.  In the future I hope flush out RASP further as well as discuss parallelization patterns in depth.


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:
Categories: Development
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

Dynamically Loading ASP.NET User Controls with jQuery

December 24, 2008 14:02 by mikkel@ovesens.com

If you have not moved entirely to the ASP.NET MVC framework and you don't think that ASP.NET Ajax is sufficient... well I have found this article about using usercontrols and jQuery.

http://samuelmueller.com/post/2008/12/20/Dynamically-Loading-ASPNET-User-Controls-with-jQuery.aspx

 


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Create Word Documents using .NET without Interop

December 24, 2008 13:43 by mikkel@ovesens.com

Original blog post:

http://www.invoke.co.nz/products/docx.aspx

--------------------------------------------------------------------------------------

We have decided to release another component we've been using (FREE of charge, click here to download). This library creates Word Documents (.docx) using .NET. It is written purely in C#, you don't need any Word viewing applications or Interop (COM) dlls installed/registered.

It works very similar to a Repeater control, instead of HTML markup you create a docx template using Word 2007 (Open XML format), specify parameters/placeholders to hold values then pass the document to the library, it will then merge those fields.

Here's an example:
To create a Word (.docx document)
- Open up Word 2007, create a new file and type in the following (without the " "):
"Hello %NAME%"
- Save & Exit (save as hello.docx)

- Create a new VS 2008 Console Application project, add a reference to the docx library, copy paste the code into Program.cs

static void Main(string[] args)
{
    File.Copy("hello.docx", "hello_ready.docx", true); // create a copy of template file for later use
    // DocumentDataSource holds name/value pair data
    DocumentDataSource source = new DocumentDataSource();
 
    source["NAME"] = "Joe Bloggs"; // assign a value to parameter %NAME%
    DocumentRenderer.ProcessDocument("hello_ready.docx", source); // process the document
 
    Process.Start("hello_ready.docx"); // run MS Word to see merged document
}

Result
Create a Word Document using C# without Interop (COM)

That's an over simplified example, the library is able to do a lot more, if you'd like to download it or find out more please click here,

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags: , , ,
Categories: Development
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

R.I.P. DateTime... well hello DateTimeOffset

December 23, 2008 15:53 by mikkel@ovesens.com

I have for a long time been thinking, looking and coding a solution that deals with the fact, that the DateTime represents a time, but not time zone.

I have long know, that to truly make a global application you must persist dates in the UTC format. However my experience with persisting in UTC and retrieving in UTC from the database is not good.

And then the DateTimeOffset shows up at the exact perfect time... As usual I do not want to use my time writing a blog post (I will rather be coding), when there are already good persons out there that has put many of my thoughts down on hard drives.

So continue reading here:

http://weblogs.asp.net/okloeten/archive/2008/12/18/6795009.aspx


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Retrieving the COM class factory for component with CLSID {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} failed due to the following error: 80070005

December 23, 2008 15:24 by mikkel@ovesens.com

If you encounter this error, you need to setup the security properties for the component in the "Component services" -> "DCOM Config".

This is the original blog post about it:

http://blog.crowe.co.nz/archive/2006/03/02/589.aspx

Or you can read it here:

The problem is that by default Microsoft Excel as a COM object can only activated by the following accounts:

  • Administrator
  • System
  • Interactive

When you are running your ASP.Net account on Windows XP your web application is running as the ASPNET account.

The way to resolve this issue is to edit the DCOM configuration settings for the Microsoft Excel Application object.

Configure DCOM

  • Go to the Start-Run menu item.
  • Type in "DCOMCNFG" and hit enter.
  • This should load the "Component Services" MMC (you can also load from Administrative Tools - Component Services"
  • Expand "Component Services"
  • Expand "Computers"
  • Expand "My Computer"
  • Select the "DCOM Config" item
  • Select the "Microsoft Excel Application" item.
  • Right click and select Properties
  • Select the Security Tab and you should see the following:



     
  • Under "Launch and Activation Permissions" select the "Customize" option.
  • Click the "Edit" button

    Windows XP

             

    Windows 2003 Server

     

      
     
  • Click the "Add" button to add a new account to the list.
  • On the dialog that is displayed click the Locations button

    (this is because by default your domain will be selected and we need a local account)

    In this dialog scroll the list to the top (sometimes the first item is not visible) but scroll to the top and select the first item which is your computer name. In the list below "CCROWE" is the name of my computer.



     
  • Click the OK button
  • On the dialog that is displayed enter "ASPNET" as the account name (make sure location is set to the name of the computer that IIS is on) on Windows XP or if you are running on Windows 2003 Server you must enter the account that the Application Pool is running as, by default "Network Service"

    Windows XP

                  

    Windows 2003 Server

    Note: A quicker way on Windows XP is to just enter the computer name and the account
    so in my case that would be:

              ccrowe\ASPNET 

     


  • Click the OK button
  • Now make sure you select the following options for the "ASP.NET Machine Account" or the account that is the application pool identity ( by default Network Service)
     
    • Local Launch         : Allow
    • Remote Launch        : [blank]
    • Local Activation     : Allow
    • Remote Activation    : [blank]

    These settings can be seen below:

  •  

    Windows XP

             

    Windows 2003 Server

     
  • Click the OK button and test your web application again and it should work fine.

Note: Remember if you are running on Windows 2003 Server you must use the application pool identity as the account and not the ASPNET account.


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags: , , ,
Categories: Development
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

Debugging memory leaks and Parallel LINQ

December 18, 2008 02:47 by mikkel@ovesens.com

Link to good articles

Debugging OutOfMemoryExceptions in managed code using Windbg

http://blogs.msdn.com/amolravande/archive/2008/12/16/debugging-outofmemoryexceptions-in-managed-code-using-windbg.aspx

 

Query Data with Parallel LINQ

http://blogs.msdn.com/charlie/archive/2008/12/15/query-data-with-parallel-linq.aspx

 


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tool for Mockup and Wireframes

December 11, 2008 14:58 by mikkel@ovesens.com

Take a look here

http://balsamiq.com/


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Prevent Cross-Site Request Forgery (CSRF) using ASP.NET MVC AntiForgeryToken helper

November 26, 2008 17:25 by mikkel@ovesens.com

Original post:

http://blog.codeville.net/2008/09/01/prevent-cross-site-request-forgery-csrf-using-aspnet-mvcs-antiforgerytoken-helper/

--------------------------------

Cross-site scripting (XSS) is widely regarded as the number one security issue on the web. But since XSS gets all the limelight, few developers pay much attention to another form of attack that’s equally destructive and potentially far easier to exploit. Your application can be vulnerable to cross-site request forgery (CSRF) attacks not because you the developer did something wrong (as in, failing to encode outputs leads to XSS), but simply because of how the whole Web is designed to work. Scary!

How CSRF works

So, what’s it all about? All web application platforms are potentially vulnerable to CSRF, but in this post I’ll focus on ASP.NET MVC. Imagine you have a controller class as follows:

   1:  public class UserProfileController : Controller
   2:  {
   3:      public ViewResult Edit() { return View(); }
   4:   
   5:      public ViewResult SubmitUpdate()
   6:      {
   7:          // Get the user's existing profile data (implementation omitted)
   8:          ProfileData profile = GetLoggedInUserProfile();
   9:   
  10:          // Update the user object
  11:          profile.EmailAddress = Request.Form["email"];
  12:          profile.FavoriteHobby = Request.Form["hobby"];
  13:          SaveUserProfile(profile);
  14:   
  15:          TempData["message"] = "Your profile was updated.";
  16:          return View();
  17:      }
  18:  }

This is all very normal. First, the visitor goes to Edit(), which renders some form to let them change their user profile details. Secondly, they post that form to SubmitUpdate(), which saves the changes to their profile record in the database. There’s no XSS vulnerability here. Everything’s fine, right? We implement this sort of thing all the time…

Unfortunately, this innocent controller is an easy target for CSRF. Imagine that an attacker sets up the following HTML page and hosts it on some server of their own:

   1:  <body onload="document.getElementById('fm1').submit()">
   2:      <form id="fm1" action="http://yoursite/UserProfile/SubmitUpdate" method="post">
   3:          <input name="email" value="hacker@somewhere.evil" />
   4:          <input name="hobby" value="Defacing websites" />
   5:      </form>
   6:  </body>

Next, they somehow persuade a victim to visit this page (basic social engineering, look it up). When this HTML page loads, it submits a valid form post to /UserProfile/SubmitUpdate on your server.

Assuming you’re using Windows authentication or some kind of cookie-based authentication system such as Forms Authentication, the automated form post will be processed within the victim’s established authentication context, and will successfully update the victim’s email address to something under the attacker’s control. All the attacker has to do now is use your “forgotten password” facility, and they’re taken control of the victim’s account.

Of course, instead of changing an victim’s email address, they can perform any action that the victim can perform with a single POST request. For example, they might be able to grant administrative permissions to another account, or post something defamatory to a CMS.

Ways to stop CSRF

There are two main ways to block CSRF:

  • Check that incoming requests have a Referer header referencing your domain. This will stop requests unwittingly submitted from a third-party domain. However, some people disable their browser’s Referer header for privacy reasons, and attackers can sometimes spoof that header if the victim has certain versions of Adobe Flash installed. This is a weak solution.
  • Put a user-specific token as a hidden field in legitimate forms, and check that the right value was submitted. If, for example, this token is the user’s password, then a third-party can’t forge a valid form post, because they don’t know each user’s password. However, don’t expose the user’s password this way: Instead, it’s better to use some random value (such as a GUID) which you’ve stored in the visitor’s Session collection or into a Cookie.
Using the AntiForgeryToken helpers

With Preview 5, Microsoft has added a set of helpers to the “futures” assembly, Microsoft.Web.Mvc.dll, that give you a means to detect and block CSRF using the “user-specific tokens” technique.

To use these helpers to protect a particular form, put an Html.AntiForgeryToken() into the form, e.g.,

   1:  <% using(Html.Form("UserProfile", "SubmitUpdate")) { %>
   2:      <%= Html.AntiForgeryToken() %>
   3:      <!-- rest of form goes here -->
   4:  <% } %>

This will output something like the following:

   1:  <form action="/UserProfile/SubmitUpdate" method="post">
   2:      <input name="__MVC_AntiForgeryToken" type="hidden" value="saTFWpkKN0BYazFtN6c4YbZAmsEwG0srqlUqqloi/fVgeV2ciIFVmelvzwRZpArs" />
   3:      <!-- rest of form goes here -->
   4:  </form>

At the same time, Html.AntiForgeryToken() will give the visitor a cookie called __MVC_AntiForgeryToken, with the same value as the random hidden value shown above.

Next, to validate an incoming form post, add the [ValidateAntiForgeryToken] filter to your target action method. For example,

   1:  [ValidateAntiForgeryToken]
   2:  public ViewResult SubmitUpdate()
   3:  {
   4:      // ... etc
   5:  }

This is an authorization filter that checks that:

  • The incoming request has a cookie called __MVC_AntiForgeryToken
  • The incoming request has a Request.Form entry called __MVC_AntiForgeryToken
  • These cookie and Request.Form values match

Assuming all is well, the request goes through as normal. But if not, boom!, there’s an authorization failure with message “A required anti-forgery token was not supplied or was invalid”.

This prevents CSRF because even if a potential victim has an __MVC_AntiForgeryToken cookie, an attacker can’t find out its value, so they can’t forge a valid form post with the same value in Request.Form. But legitimate users aren’t inconvenienced at all; the mechanism is totally silent.

Using salt

Salt? What? In case you want to protect multiple forms in your application independently of each other, you can use a “salt” value when you call Html.AntiForgeryToken(), e.g.,

   1:  <%= Html.AntiForgeryToken("someArbitraryString") %>

… and also in [ValidateAntiForgeryToken], e.g.,

   1:  [ValidateAntiForgeryToken(Salt="someArbitraryString")]
   2:  public ViewResult SubmitUpdate()
   3:  {
   4:      // ... etc
   5:  }

 

Salt is just an arbitrary string. A different salt value means a different anti-forgery token will be generated. This means that even if an attacker manages to get hold of a valid token somehow, they can’t reuse it in other parts of the application where a different salt value is required. (If anyone can suggest other use cases for salt, please let me know.)

Limitations of the Anti-Forgery helpers

ASP.NET MVC’s anti-CSRF helpers work very nicely, but you should be aware of a few limitations:

  • All legitimate visitors must accept cookies (otherwise, [ValidateAntiForgeryToken] will deny their form posts). Arguably this isn’t a limitation, because unless visitors allow cookies, you probably don’t have anything to protect anyway.
  • It only works with POST requests, not GET requests. Arguably this isn’t a limitation, because under the normal HTTP conventions, you shouldn’t be using GET requests for anything other than read-only operations.
  • It’s easily bypassed if you have any XSS holes on your domain. An XSS hole would allow an attacker to read a victim’s anti-forgery token value, then use it to forge valid posts. So, don’t have XSS holes!
  • It relies on the potential victim’s browser implementing cross-domain boundaries solidly. Browsers are supposed to stop foreign domains from reading your app’s response text and cookies, and are supposed to stop foreign domains from writing cookies to your domain. If an attacker manages to find a way around this, they can bypass [ValidateAntiForgeryToken]. Of course that’s not supposed to be possible. For the most part, modern browsers block this line of attack.

In conclusion, ASP.NET MVC’s anti-CSRF helpers are easy to use, and work very nicely thank you!


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories: Development
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

New ASP.NET Charting Control

November 26, 2008 11:48 by mikkel@ovesens.com

Microsoft released a free ASP.NET charting controls.

Read more about it here:

http://weblogs.asp.net/scottgu/archive/2008/11/24/new-asp-net-charting-control-lt-asp-chart-runat-quot-server-quot-gt.aspx

Or take a qucik look directly on these following link:

Microsoft recently released a cool new ASP.NET server control - <asp:chart /> - that can be used for free with ASP.NET 3.5 to enable rich browser-based charting scenarios:


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5