Magic Page Names in ASP.NET WebPages


Capture One of the features in ASP.NET WebPages that is super powerful yet super simple is the “magic names” you can give to a page that make that page behave differently. Unfortunately the feature isn’t really called “magic names” (That would be way too cool!). Instead they are broken down into the two variations, Start pages and Init Pages. You may have seen these pages used before in other posts (I used one in my SimpleMembership post) or maybe even covered in one of the tutorials. I just figured that I would give them their own post as they are pretty powerful and could use some further explanation than what is normally given.

So let’s start with Start Pages (see what I did there?). What is the idea behind a Start Page? Well, as the name implies this is a page that will be executed every time your application starts. For those of you familiar with the Application_Start event in ASP.NET this is basically the same thing. This page will execute only once when your application is first started or if you’re running in IIS, when the Application Pool is recycled. So what is the magic file name you have to give a page to make it a Start Page? It’s simple, just name the file “_start.cshtml” or “_start.vbhtml”.

Now would be a good time to stop and talk about what the underscore character at the beginning of the file name does. ASP.NET WebPages use a concept for routing that will automatically wire up pages to nice routes for you. This was originally prototyped as “Smarty Routes” and I will be making a post about how they work later. For now what you should know is that the underscore tells routing not to serve that page up directly, effetely making it unrequestable from a browser. This trick works for any page not just these magically named pages. For instance if you have a “partial page” that contains some common UI and you don’t want the end user to be able to navigate to that page just start the name with an underscore.

Okay so back to Start Pages. Start Pages do not have any output, they are basically just a code block (the @{ } at the top of the file). If for whatever reason there is markup in the file it is just ignored. So what is a Start Page good for? Well it is used to perform programmatic setup of your site. Some of the built in features that need to be configured in a Start Page are SimpleMembership and the Email Helper. The last thing about Start Pages is that there can only be one Start page per website. Below is a sample of what a possible Start page might look like.

  1. @{
  2.    //Set up Simple Membership
  3.    WebSecurity.InitializeDatabaseFile("Demo.sdf", "Users", "UserID", "Username", true);
  4.    
  5.    //Set Up Email Server
  6.    Mail.SmtpServer = "smtp.Server";
  7.    Mail.SmtpPort = 25;
  8.    Mail.EnableSsl = true;
  9.    Mail.UserName = "UserName";
  10.    Mail.Password = "Password";
  11.    Mail.From = "Demo App";
  12. }

 

Okay so the second “magical name” is “_init.cshtml” or “_init.vbhtml”. For the same reason (not being requestable) Init Pages also begin with an underscore. So what is an Init Page? Init Pages run at the beginning of each request prior to the requested page. I bolded the words “each request” in the last sentence because I want you to understand that for each request that comes to the sever this page with execute. So that means it would not be beneficial to put long running setup code in this page, anything you put in an Init Page should run fast. Unlike Start Pages there can be multiple Init Pages in each website. This means that you can have the root contain an Init Page and then a subfolder contain one as well. Earlier I said that they would run for each request that came to the server that is not really 100% true. They will only run if they are in the parent folder chain of the requested page. If you have two subfolder both with Init Pages in them and then request a file from one of the subfolders only the Init Page in that subfolder will run. So you might be asking yourself “what is the order in which they execute?” The easiest way to sum that up would be that the execution starts furthest away from the requested file and works its way down the chain closer to the requested file. There is one last difference between Start Pages and Init Pages that I would like to call out. An Init Page does have an output. This means that if you put mark up in the file it will show up in the output of the request. The output follows the order of execution so an Init Page’s output would appear before the requested files output. A key point to make here is that due to the life cycle of a page if you are using a Layout Page that will appear after the output of the Init Page.

So what is a good use for Init Pages? Well there are a couple examples I’d like to give. First, is to define a Layout Page for the site. This way you do not need to include the setting of the Layout Page in each page in the site but it can still be overridden. You could override the page by placing an additional Init Page “closer” to the page or by simply just setting it to something new in the page you want to look different. The other use that Init Pages are ideal for is securing your website. I talked about this a little in my SimpleMembership post, but you can use an Init Page to require authentication to view the pages in a folder. Also because you can have multiple Init Pages you could add additional security requirements (e.g. require a cretin role) as you go deeper in a folder structure. Below is an example of an Init Page that sets the Layout Page and then requires authentication and the user to be in the “admin” role.

  1. @{
  2.    LayoutPage = "~/Account/adminLayout.cshtml";
  3.    WebSecurity.RequireAuthenticatedUser();
  4.     if(!WebSecurity.IsCurrentUserInRole("Admin")){
  5.         Response.Redirect("~/Account/unauthorized");
  6.     }
  7. }

 

Hopefully this post clears up some of the mystery around these special magical file names that you may have heard about before. If not don’t hesitate to ask your question, the only stupid questions are the ones not asked! I’d like to see the creative ways that you can come up with to use both Start Pages and Init Pages so please feel free to email me your ideas!

author: Matthew M. Osborn | posted @ Tuesday, July 27, 2010 4:59 PM | Feedback (0)

Using SimpleMembership With ASP.NET WebPages


With the introduction of ASP.NET WebPages and the WebMatrix stack our team has really be focusing on making things simpler for the developer. Based on a lot of customer feedback one of the areas that we wanted to improve was the built in security in ASP.NET. So with this release we took that time to create a new built in (and default for ASP.NET WebPages) security provider. I say provider because the new stuff is still built on the existing ASP.NET framework. So what do we call this new hotness that we have created? Well, none other than SimpleMembership. SimpleMembership is an umbrella term for both SimpleMembership and SimpleRoles.

diagram

To the left is a diagram (you can click on it to see a bigger version) I often use when explaining how SimpleMembership works to other team members. I will admit I spent time making sure my boxes looked like boxes and had four points just for you guys. The middle section dotted in blue is the existing Membership APIs in the ASP.NET Framework. The SimpleMembership APIs are implemented as providers that are plugged into the core ASP.NET APIs. SimpleRoleProvider simply implements the RoleProvider abstract base class and does not add anything more. SimpleMembershipProvider is a bit trickier. To be able to support features I will discuss later in the post we needed to add additional functionality so we created a new ExtendedMembershipProvider abstract class. The ExtendedMembershipProvider abstract class inherits from the core ASP.NET MembershipProvider abstract base class. When you are using ASP.NET WebPages both of these new providers are registered as the default Membership and Role Providers. We also added a new WebSecurity class which provides a nice façade to SimpleMembershipProvider. This class is a helper class designed to make some of the more common tasks easy when you are trying to secure your website. WebSecuirty also holds APIs for some of the new functionality that we have added. For instance confirming an account and initializing the database (I’ll talk about that in just a minute). That is the basic overview of the internals to the new SimpleMembership feature.

Okay now that you have a basic understanding of how and why we created SimpleMembership I would like to spend some time walking you through how you can use it to secure your brand new ASP.NET WebPages site. There’s too much to cover in a single blog post so I’ll skim over some areas and ignore others, but will provide you enough information so that you can get started using SimpleMembership on your own. Also I do assume that you have a basic working knowledge of ASP.NET WebPages and the patterns that are used with this type of framework. Okay so what am I going to show? I will walk you through how to set up the database, create a registration page, create the login and logout pages, create a profile page, and finally create a simple admin section to control it all.

Before we start the first step of setting up your database I would like to give you some background information. One of the biggest complaints from customers has been the lack of control over the users table. The default provider in ASP.NET gave you some generic information and then the ability to store other information in a “blob”. This worked out well if you were not trying to do anything complicated but, if you wanted to something complicated it wasn’t that easy. With SimpleMembership we decided that it was easier to allow you, the developer, to have control of the users table and let SimpleMembership handle storing the authentication credentials. For example, you might already have a users table and want to integrate it with SimpleMembership. All SimpleMembership requires is that there are two columns on your users table so that we can hook up to it – an “ID” column and a “username” column. The important part here is that they can be named whatever you want. For instance username doesn't have to be an alias it could be an email column you just have to tell SimpleMembership to treat that as the “username” used to log in.

UsersTable Okay so let’s get started creating our users table. In this example I will be using the new SQL CE 4 Database Engine so in WebMatrix add a new database file (this can be done on the database manager tab), name it whatever you like in this example I chose “SecurityDemo.sdf”.  Add a new table called “Users” (once again you can call the tables and columns whatever you want I’m just guiding you through my example). The only two columns you most have are some ID column and some username column in this case I chose the very clever names “UserID” and “Username”. Also add any other columns for data you would like to store, when you’re done you’ll have something like the table in the image to the left. Although if you want to follow along add all the columns I have that way it will be easier to copy and paste code.

Now that we have created our users table we need to wire it up to SimpleMembership so that SimpleMembership knows what columns to use. Now I’m going to introduce a new feature of ASP.NET WebPages that you may or may not know about which is the start page. This is a specially named page that will get run the first time an application starts. So create a page with the name “_start.cshtml” in your site, remove all the markup leaving only the code block at the top, and put the following code in that code block.

  1.  //Set up Simple Membership
  2. WebSecurity.InitializeDatabaseFile("SecurityDemo.sdf", "Users", "UserID", "Username", true);

 

MembershipTablesCreated The parameters are rather self-explanatory but they are, in the following order,  name of the database file, name of the table you are using for the users table, name of the column being used for the ID, and name of the column you are using for the username. If you notice I left the last one off because it isn’t really self-explanatory, it is a bool value telling SimpleMembership to create the tables it needs if they are not present. These are tables that are used under the covers to make everything work, for instance the roles table. Every table created by SimpleMembership will start with “webpages_” in the name. As a general rule of thumb for later on if you have to manually query one of the tables with “webpages_” in the name there is probably a better API to be calling. Now it’s time to run your site once, these will cause SimpleMembership to go and create the tables we need. When you’re done you will have the tables in the image to the left in your database. 

Okay so now you’re all set up and SimpleMembership is wired up to your table. The next logical step is to create a page where users can register for your site. Due to the fact that his post is already getting long I’m not going to show you the whole page, just the key pieces of code and if you’d like to see the whole page you can download the sample and use it to follow along. At this point create a register page with input fields for each of the columns in your user table. When the page is posted to you want to do some sort of validation on the values, you can download the sample and see the pattern I use. If all the posted values are valid call the following code, where the anonymous object represents the columns in your users table.

  1. WebSecurity.CreateUserAndAccount(username, password
  2.    new{FirstName = fname, LastName = lname, Email = email, StartDate = DateTime.Now, Bio = bio});

 

Now is the perfect time to talk about the words User and Account. Basically the word user maps to the user table you create while the word account maps to the table SimpleMembership uses to store things like password salts and confirmation tokens. You can choose to use your own SQL insert statement to insert into your users table and then just wire that entry up to SimpleMembership but as this is a rather common task we created a helper for it.

The next logical set would be to create a way to login and logout of your site. Let’s start with the login page. Once again I’m skipping all the simple HTML markup and post data validation since we have a lot to cover.

  1. if(WebSecurity.Login(username, password)){
  2.    var returnUrl = Request.QueryString["ReturnUrl"];
  3.    if(returnUrl.IsEmpty()){
  4.        Response.Redirect("~/Account/Profile");
  5.    } else {
  6.        Response.Redirect(returnUrl);
  7.    }
  8. }

 

There is a helper method that hangs off of the WebSecurity class that you use to login a user and it will return true of false based on if the username and password combination is valid. There is one thing that I wanted to make sure that I pointed out here. If you remember that SimpleMembership is built on the core ASP.NET Membership APIs when a user visits a part of the site that requires authentication (I’ll cover how to set that up in just a minute) they will be redirected to the the login page (default is “~\account\login”). When they are redirect the framework tacks on a query string parameter of “ReturnUrl” that can be used to return the user to the URL that they were trying to navigate to after they are logged in. You’ll notice that in the code I check for that and if it’s not empty I redirect them to that URL otherwise they get redirect to their profile page.

Now that you can login to the site you need someone to be able to logout right? Logging out is much simpler, in fact the logout page does not have any markup it is simply a page that the website posts to and then the request is redirected after the user is logged out.

  1.  WebSecurity.Logout();
  2. var returnUrl = Request.QueryString["ReturnUrl"];
  3. if(returnUrl.IsEmpty()){
  4.     Response.Redirect("~/");
  5. } else {
  6.     Response.Redirect(returnUrl);
  7. }

 

I choose to keep the concept of a return URL because I wanted a user to be returned to the page where they clicked on the link to logout. This makes for a nice touch and can really help user experience but it’s not necessary, you could simple redirect them to the root of the site.

What good is having a login and logout page if there is no part of your site that requires a user to be authenticated? In this example I choose to kill two birds with one stone and say that if a user is logged in and they visit their profile page they will be able to change their password. This way I get to show you guys two APIs instead of just one. For a cleaner look I have a conditional statement in the HTML markup that will leave out the Change Password markup if “isCurrentUser” is false.

  1.  //Get the username from the URL e.g. account/profile/osbornm
  2. var UserName = UrlData[0] != string.Empty ? UrlData[0] : WebSecurity.CurrentUserName;
  3. var isCurrentUser = UserName == WebSecurity.CurrentUserName;
  4. if(IsPost && isCurrentUser){
  5.     //If everything checks out try to change the password
  6.      if(val.Count == 0){
  7.          if(!WebSecurity.ChangePassword(WebSecurity.CurrentUserName, oldPassword, newPassword)){
  8.              val.Add("Unable to change password.");
  9.          }
  10.      }
  11.  }

There are a couple of APIs that I would like to point out in the code above. First off is that CurrentUserName property hanging off of WebSecurity. If a user is logged in this will be there username and if they are not logged in it will be an empty string. Also there are plenty of these helpers methods that you can use including one that requires an authenticated user that you can put at the top of your page to require a user to be logged in to see that page. The second API I want to call out is ChangePassword, also hanging off of WebSecurity. This will return true is the change was successful or false if there was a problem.

Now that we have the basic functionality the only thing left is to spice it up by adding some roles and a special section for administrators to do administrator stuff. The way I’m going to tackle this problem is to create parts of the admin section and then use them to add the role and add users to the role, once that's done we will change it so only people in the admin role can access that page. Just like before I will leave off the simple HTML markup and you can download the sample if you would like to see it.

  1.  //Code to add a role
  2. var roleName = Request["roleName"];
  3. if(roleName != null){
  4.     if(roleName == string.Empty){
  5.         //Validation Message
  6.     } else {
  7.         Roles.CreateRole(roleName);
  8.     }
  9. }

 

The first thing I would like to point out is that pattern that I am using for this page. I wanted to have all the functionality on one page so that means there will be many forms all posting to this page. So how to I tell the difference from a post to add a role from a post to add a user to a role? I use the values that come in with the request. If the post has a value named “roleName” I know that it must have come from that form, that is what line three is testing. While this isn’t fool proof, it is simple and works most of the time and its fine for this sample. You’ll notice that in the code sample we have reached a point where we aren't using the WebSecurity class anymore, that's because the core ASP.NET APIs work just fine. So we call the static “CreateRole” method on the Roles object, which under the covers ends up calling the SimpleRoleProvider to create the role. 

Now that we can create a role we need a way to add a user to that role otherwise there is no reason to have roles. I choose a simple UI for this task that probably isn’t the most efficient for adding lots of users to lots of roles but it works fine for this example. So you’ll notice in the code below that I grab all the users and all the roles so that a dropdownlist can be populated with the values.

  1.  //Code to get all users
  2. dynamic users;
  3. using(var db =  Database.Open("SecurityDemo")){
  4.      users = db.Query("SELECT * FROM [Users]");
  5.  }
  6. //Get the current roles in the system
  7. var roles = Roles.GetAllRoles();
  8. //Code to add a user to a role
  9. var userToAddTo = Request["userToAddTo"];
  10. var roleToAdd = Request["roleToAdd"];
  11. if(!userToAddTo.IsEmpty() && !roleToAdd.IsEmpty()){
  12.     Roles.AddUserToRole(userToAddTo, roleToAdd);
  13. }

 

The reason I choose to query for all the users myself is I wanted to show you that the developer really does own the users table so you can issue normal SQL queries to get info like this without having to go through all the Membership APIs. Again, I followed the pattern of detecting values that came in from the request to determine what action needed to be performed. Once again the core ASP.NET APIs are good enough for adding a user to a role so you can simply call the static method on the Roles object.

Now that we have can go create the admin role and add our user to it, navigate to the page and do so, it’s okay I’ll wait for you. Done? Good. So now that you’re an admin on your own site let’s go lock down this admin section of the site so only users that are in the admin role can access it. This is easiest done by moving that page to an admin folder and then using an init page. This is another one of those specially named pages that you may or may not already know about. Basically you create a page with the name “_init.cshtml” in a folder and that page will run first before any other page in that folder for every request. This is useful for doing operations such as requiring an authenticated user or requiring a specific role because the code is in one location and not spread across every page.

  1. WebSecurity.RequireAuthenticatedUser();
  2. if(!WebSecurity.IsCurrentUserInRole("Admin")){
  3.     Response.Redirect("~/Account/unauthorized");
  4. }

 

Just like the “_start.cshtml” file there is no markup just a code block at the top. This code does two things; the first is to require an authenticated user this means if you visit part of the admin section and you aren’t logged in you will get a nice prompt for your password. The second is that if a user is authenticated but they aren’t in the “admin” role they will be redirect to an unauthorized page I created that displays a nice error message explaining why they can see that part of the site. You don’t have to do it that way you could redirect anywhere you wanted for even set the status code to 404 so it looked like there wasn’t anything there, it’s all up to you.

Well now you’re done, you have a very simple implementation that secures your site and can store user information. The sky really is the limit here, there is so much more you can do, there was just too much to cover in one blog post. If you have requests for how to do something I’d be glad to add an example or even create a new post about if you just have to let me know. Also in the downloadable source there is quite a bit more than what I covered here! I have examples of requiring a confirmation email to be sent, deleting user and roles, using a layout page to display a login/logout status widget, and how to implement some simple validation based on the way ASP.NET MVC does its validation. So please download and play around with the sample source.

Download Sample Source: http://samples.osbornm.com/securitydemo.zip

author: Matthew M. Osborn | posted @ Wednesday, July 21, 2010 12:42 PM | Feedback (11)

Coding QA Teams Up With TekPub


TekPubCodingQAToday is an exciting day for the Coding QA Podcast! I am proud to announce that Coding QA has teamed up with TekPub to give-a-way some licenses for TekPub to our listeners. This has been in the works for some time now and we wanted to find some creative a way to give these licenses away. To us the standard send us an email and we will draw a name out of a hat just did not seem to cut it. I know you’re sitting on the edge of your seat and asking “How then do I get these?” Well given that we are a podcast all about testing we figured what better way than to make you test something. Given that both Federico and I have been working on the newly released WebMatrix we figured that this would be the perfect thing to give our listeners to test. I’d like to take a second and make sure that I make this very clear so listen up. This is NOT in any way, shape, or form connected with Microsoft Corp.

Goal: Find the most Interesting bugs possible in WebMatrix

What: TekPub is going to give 1st and 2nd place a yearlong subscription and 3rd thru 10th place a 30 day subscription

How: Open a bug on Microsoft Connect and email us (giveaway@codingqa.com) with a link to the bug

When: We will gather up all the entries on Sept 17th, 2010 and then pick the top 10

Okay so your probably asking yourself what in the world makes up an interesting bug? Well this is a bit subjective so we have come up with some criteria to give you some kind of idea. These are just a few of the criteria and its doesn’t mean that if your bug doesn’t fit all of these then its not an interesting bug with a chance of getting a license. This list is just meant to give you some kind of guide on how we will be picking the top 10.

  • A majority of users will run into the bug. This means that it is not an extreme edge case.
  • Some form of data loss occurs because of the bug. This can be end user data loss or developer data loss.
  • The issue is a bug in functionality not the design of the functionality.
  • The bug must be a result of the framework code not the implementation of the framework code by the developer.
  • Must not be a duplicate. First bug submitted wins. Bugs and issues already called out in the readme would be considered duplicates.
  • We must be able to reproduce the bug. This means it’s in your best interest to provide good repro steps or even a repro site.

Examples of Interesting bugs that could win you a TekPub license

  • When I use the following code the CSHTML parser goes into an infinite loop.
  • Using the following steps I can get elevation of privileges.
  • Using the following steps my face melted off. See Indiana Jones and the Last Crusade

Examples of bugs that won’t win you a TekPub license but are still bugs.

  • The following error message has a misspelled word.
  • When all 6 of the planets and 2 planetoids align and only on this one really old non-supported machine this code doesn’t work.

Okay so what are you waiting for? Why haven’t you download WebMatrix and started finding bugs? You can enter as many bugs as you like but you can only win one license. We know all of you testers out there are going to try to work the system (that's what testers do) but please don’t. This is a reward we wanted to give to our listeners for your support and we would hate to have to call you out. Happy hunting!

Download WebMatrix | Visit TekPub | Visit Coding QA

author: Matthew M. Osborn | posted @ Thursday, July 08, 2010 9:40 AM | Feedback (2)

Introduction to WebImage


Just a random image ;) One common operation that pretty much every website in the world does is either accepting, creating, editing, or displaying images. This could be something as simple as a user’s profile picture or as complex a full blown image gallery. Either way if you have every had implement these functionalities in a website you know that they are not the easiest thing to create. Well, here is where the WebPages team comes in to save the day! We have wrapped what we think are some of the most common image manipulation operations into a brand new fancy WebImage helper.

Okay so what can the WebImage helper do for you, well a few things: 

  • Get an image from the request
  • Resize
  • Crop
  • Add a watermark (text and image)
  • Flip vertical and horizontal
  • Rotate right and left
  • Save and convert formats
  • Some other more boring stuff like get the array of bytes, blah blah blah.

Okay so now that I got you all excited about the WebImage helper (it’s okay if you’re not I will forgive you) let jump into some code.

So one of the more common things to do is to allow a user to upload an image and then save it off somewhere, either to a database or the file system. So I am going to stop here and say that for the rest of the article I will assume you have a basic understand of HTML and that I don’t need to show you how to create a file upload input on your page.

  1. var photoToDatabase = WebImage.GetImageFromRequest("FileUploadNameHere");
  2. repo.SaveToDatabase(photoToDatabase.GetBytes());
  3.  
  4. /* OR */
  5.  
  6. var photoToFileSystem = WebImage.GetImageFromRequest("FileUploadNameHere");
  7. string newFileName = Guid.NewGuid().ToString() + "_" + photoToFileSystem.FileName;
  8. photoToFileSystem.Save("~\\images\\" + newFileName);

 

In the code sample above you can see two different ways to grab the uploaded file from the request (the input has a name of ‘FileUploadNameHere’) and save it off, either to a database or to the file system. The first example shows how to save it up to a database. Most of the time the API for saving to a database just take a Byte[] of the image, for instance see the Simple Data demo. The second one that save the image off to the file system is the much more interesting sample. For right now ignore the man behind the current (line number seven) in the sample that just ensures a unique file name. The team to trying to see what we can do to make this a better story but no promises. So if you’ll notice there is a native API that we are called, called Save. This method takes in a path, which can be a relative path like it is in the sample or a a full path (you would PhysicalApplicationPath to create such a path), and saves a copy of the image to the file system.

Okay so let’s do something a little more interesting, let’s talk about what you how you would take that image that you just saved off and then create a thumbnail version of it.

  1. var photoToDatabase = WebImage.GetImageFromRequest("FileUploadNameHere");
  2. photoToDatabase.Clone().Resize(128, 128, preserveAspectRatio: true);

 

In this example there are two APIs that I would like to take the time to point out. The first is the call to the Clone method, this effectively create a copy of the image in memory. The reason for this is that we want to still have the original image preserved, assuming we are also going to save it of. The second is the call to the Resize method, it takes a height and a width and has a two optional parameters. In this example I am using the preserveAspectRatio parameter, which will choose a height and a width that matches as closely to the values you passed in while still keeping the aspect ratio.

This would be a good time to stop and point out that all the WebImage APIs are designed to return a WebImage so you get a fluent design when using them. In the example above you can see how I was able to chain multiple API calls together into one line, which in my humble opinion looks much cleaner. Now that you have a basic understanding of how the WebImage API works, and can explore the remaining APIs, I’d like to leave you with a sample how you can write a page that takes an users uploaded photo adds whatever text they provided as a watermark and then allows them to download the image.

  1. @{
  2.         WebImage photo = null;
  3.         var newFileName = "";
  4.         var imagePath = "";
  5.         var imageThumbPath  = "";
  6.         if(IsPost){
  7.             photo = WebImage.GetImageFromRequest("Image");
  8.             if(photo != null){
  9.                 /*Setup Correct Image Paths*/
  10.                 newFileName = Guid.NewGuid().ToString() + "_" + Path.GetFileName(photo.FileName);
  11.                 imagePath = "~\\images\\" + newFileName;
  12.                 imageThumbPath = "~\\images\\thumbs\\" + newFileName;
  13.                 /*Add Text Watermark*/
  14.                 var text = Request["Text"];
  15.                 var opacity = Request["Opacity"].AsInt();
  16.                 var fontSize = Request["FontSize"].AsInt();
  17.                 photo.AddTextWatermark(text, fontSize: fontSize, opacity: opacity);
  18.                 /*Add Image Watermark*/
  19.                 var WMImage = WebImage.GetImageFromRequest("WMImage");
  20.                 if(WMImage != null){
  21.                     photo.AddImageWatermark(WMImage, verticalAlign: "Top", opacity: opacity);
  22.                 }
  23.                 /*Save and Create Thumbnail*/
  24.                 photo.Save(imagePath);
  25.                 photo.Resize(350, 350, preserveAspectRatio: true).Save(imageThumbPath);
  26.             }
  27.         }
  28. }
  29.  
  30. <!DOCTYPE html>
  31.  
  32. <html xmlns="http://www.w3.org/1999/xhtml">
  33. <head>
  34.     <title>ASP.NET WebPages | WebImage Demo</title>
  35.     <link type="text/css" rel="Stylesheet" href="default.css" />
  36. </head>
  37. <body>
  38.     <form action=""  method="post" enctype="multipart/form-data">
  39.         <fieldset>
  40.             <legend>WebImage Demo</legend>
  41.                 <label for="Image">Image</label>
  42.                 <input type="file" name="Image" />
  43.                 <label for="Text">Watermark Image</label>
  44.                 <input type="file" name="WMImage" />
  45.                 <label for="Text">Watermark Text</label>
  46.                 <input type="text" name="Text" value="WebImage Demo" />
  47.                 <label for="Opacity">Opacity (0-100)</label>
  48.                 <input type="text" name="Opacity" value="80" />
  49.                 <label for="FontSize">Font Size</label>
  50.                 <input type="text" name="FontSize" value="60" />
  51.                 <input type="submit" value="Try It Out" />
  52.         </fieldset>
  53.     </form>
  54.     @if(imagePath != ""){
  55.     <div class="result">        
  56.         <img src="@Href(imageThumbPath)" alt="Your image with a watermarl" />
  57.         <a href="@Href(imagePath)" target="_blank" class="download">Download Full Size</a>
  58.     </div>
  59.     }
  60. </body>
  61. </html>

 

WebImage Demo

Okay so now that you have a basic understanding of how WebImages work I’d like to encourage you to explore the remaining APIs and see what awesome ideas you can come up with. As always please let us know if you have any feedback.

 

Demo Source: WebImageDemo.Zip

Q&A:

Question: Where can I find the dll that has WebImage?
Answer: WebImage is part of the WebMatrix stack, specifically ASP.NET WebPages. WebImage is in the Microsoft.WebPages.Helpers assembly that is GAC'd and also drop in program files when you install the stack.

author: Matthew M. Osborn | posted @ Tuesday, July 06, 2010 2:57 PM | Feedback (17)

Introducing WebMatrix Beta


Over the last year or so I have had the opportunity to help develop and shape a brand new framework that is, as of today, in its first ever public beta. I’d like to introduce you all to WebMatrix! WebMatrix is actually a group of products and frameworks all with the common goal of making web development simple and easy. A few of the pieces of WebMatrix have already been announced and some are never before seen until now. What are they all you ask, well let’s jump right in and review the pieces.

The best part about all of this is that it all comes in a 15MB download (50MB if .NET 4 is not already installed on the machine) and that’s everything that you need to get developing awesome websites! We have really worked hard to reduce the amount of work you have to do before you can start doing real work. You can run WebMatrix side-by-side with any of the Visual Studio 2010 SKUs including Express.

WebMatrixOver the next few blog posts my focus is going to be primarily on ASP.NET WebPages and the Razor syntax as this is the area of the stack that I spent most of the time working on. Below is a list of posts that I plan on making in the next few weeks but if you would like to hear about something not on the list please let me know I’d be more than happy to add it.

If you would like to know more about the other products and features that make up WebMatrix, here are some great links to get you started. Please, I encourage you to play around and see what you think. Also I have some exciting news coming in the next day or so regarding what happens if you find an interesting/good WebMatrix bug.

The most important of them all: Download WebMatrix

author: Matthew M. Osborn | posted @ Tuesday, July 06, 2010 2:56 PM | Feedback (1)

A Year of Coding QA


AlbumCodingQA This is one of those posts where I don’t talk about coding, sorry, but it’s still about technology so hopefully I don't scare you guys off. So what is this I want to talk about, well my podcast of course, Coding QA.

Somewhere February last year (2009) I got the idea that I wanted to host my own podcast. I had been listening to various podcasts for awhile and thought it would be fun to host my own. I spent a few weeks bounce ideas around in head about what I wanted my podcast to be about. After awhile I settled on testing. Next, I went looking for a co-host as I figure there was just no way I could be that entertaining by myself. I found that co-host in the office right across the hall, Federico Silva Armas. To make a long story short on March 11th of 2009 Federico and myself published the first episode of our podcast, Coding QA. Okay to be fair it was actually our second episode but we were so embarrassed about the first one we didn’t release it (maybe one day). As a side note the name is a play on words. Both Federico and I believe that testers should be coders too, so we are Coding QA, get it? Yea bad but give me a break you come up with a podcast and find a funny name and then you can criticize.

After a few episodes I was starting to get concerned about the technology we were using to record and host the podcast. I figured if I was going to be in this for the long haul I should upgrade. For the first few episodes we were using simple gaming headsets and recording individual tracks on separate machines. There was a couple of problems with this. One, the audio quality was just not up to par, I mean what can you expect from a $10 microphone? Two, the different machines would record at slightly different speeds so after about 15 minutes the audio would be one to two seconds out of sync. So I did a little research and and upgraded to a couple of nice microphones and a proper hardware mixer. Here is what I ended up getting

Here are some “glamour” shots of the equipment and “studio” I know you guys just ready my blog for the pictures:

DSCF1150DSCF1152DSCF1148DSCF1163DSCF1160DSCF1862

The Next problem was bandwidth, previously I was hosting the files on my Windows Sky Drive and simply linking to them from an embedded player in a blog post. The podcast had no official site or way to subscribe to it other that the podcast tag RSS feed on the blog. So I started doing more research and found a company called Liberated Syndication. They specialize in hosting startup podcasts. We got a decent amount of bandwidth and storage along with a blog engine geared towards podcasts. Before you ask yes it is a PHP site, I do see the irony, but I am always one to choose the best service and not blindly choose something because “X” company produces it. However, I do have to say that since Coding QA has gotten a lot more popular we are considering moving to Amazon S3 as it is far more cost effective for the amount of bandwidth we are going through each month (30MB an episode and an average of 3000 downloads each month is a lot of bandwidth).

So now that I have claimed that Coding QA is popular I guess I have to back it up with some numbers. Currently we have 39 episodes and have been “on air” for over a year now. We have had over 33,000 total downloads, now let me tell you I have no idea how Federico and I have fooled people into downloading us that many times. I mean okay I give you that maybe half of those are from my mom but still, WOW. Below is a graph of our monthly download totals from day one to today. (The dip in December is because we only had one new episode due to the holidays, Microsoft shuts down in December :) )

MonthlyDownloadTotals

Okay, so what have I learned over the last year? First rule of podcasting is if you can get it in one take your life is far better off! Trust me, I spent countless hours inside of audacity trying to splice episodes together and its a pain! I have found that Coding QA functions as a release for both Federico and I. Almost every episode is based on something we want to bitch about from our week and it feels good to rant sometimes. Another lesson is that audio quality is important if people are bothered by pops or breath noises they just simply wont listen why would they? Lastly is that the episodes that have been most popular are the episodes that Federico and I have fun on, so have fun with it. It’s my podcast and I’ll laugh if I want to.

So if you haven't listened to an episode yet I invite you to give it a try. I promise Coding QA isn’t a gateway podcast :) Also, and this is a pure plug, if you do listen to the podcast and like it please go to our site and give the ad on the side a click. They help to cover some of the cost of running the podcast, which is out of our pockets not Microsoft.

author: Matthew M. Osborn | posted @ Sunday, May 16, 2010 9:15 PM | Feedback (1)

Update: How and When to Encode for the Web


One of the more tricky things to learn when you are developing for the web is to know when and how to encode the content you’re delivering. There are a couple high level reasons as to why you need to encode your content. First is that some characters just are not valid in URLs and attributes which could cause your links and html to not work properly. Secondly, and by far the most important is that if you are outputting user generated content to the page you want to protect against HTML injection. Forgive me but I am going to glean over the importance and theories behind this because that is a whole other blog post. If you’d like to learn more about that here is a good starting point. I would like to focus more on when you know you should be encoding your output but you just don’t know what kind of encoding to use. That being said I’m going to talk about the three types of encoding for the web and give you some samples of when and how to use them. There are three main types of encoding for the web that you should be concerned with, HTML, URL, and Attribute encoding.

HTML Encoding

The first type of encoding I’d like to talk about is HTML encoding. This is one of the more common types of encoding and the one that is used to prevent the HTML injection attacks mentioned above. For those of you familiar with ASP.NET 4 and MVC 2 you know that the team added a new feature to support automatic HTML encoding, the <%: syntax. The short explanation of why you need to use HTML encoding is simple that a cretin set of characters mean something special in HTML. For instance ‘<’ is used to open and HTML tag and ‘&’ is used to and the beginning of a sequence of characters to define special symbols like the copy write symbol.

 

  1. HttpUtility.HtmlEncode("<script>alert('&');</script>")

 

Would return the following string

  1. &lt;script&gt;alert(&#39;&amp;&#39;);&lt;/script&gt;

Attribute Encoding

The second type of encoding I’d like to talk about is attribute encoding. Attribute encoding replaces three characters that are not valid to use inside attribute values in HTML. Those characters are ampersand ‘&’, less-than ‘<’, and quotation marks ‘”’. The first two for the same reason you HTML encode to prevent HTML injection attacks and the last one because quotation marks are used to define the value of the attribute.

  1. HttpUtility.HtmlAttributeEncode("<script>alert(\"&\");</script>")

 

Would return the following string

  1. &lt;script>alert(&quot;&amp;&quot;);&lt;/script>

URL Encoding

The Last type of encoding I’d like to talk about is URL Encoding. URL encoding is most commonly used when you have some data that you would like to pass in the URL and that data contains some reserved or invalid characters. An Example of an invalid character is a space while a reserved character would be something like a forward slash which normally means directory. Invalid and reserved characters are encoded using a ‘%’ and then two alphanumeric characters. A list of the characters and there encodings can be found here.

  1. HttpUtility.UrlEncode("Some Special Information / That needs to be in the URL")

 

Would return the following string

  1. Some+Special+Information+%2f+That+needs+to+be+in+the+URL

 

If you’re quick on your feet you might already be asking yourself what in the world happened to spaces getting encoded with the ‘%’ syntax and what are all these ‘+’ doing? Well here is the catch in .NET and in most modern frameworks/browsers spaces get encoded and decoded from ‘+’ because it is more user readable. Now if you want to ensure full compatibility you should use ‘%20’ to encode spaces and there is a separate API (UrlPathEncode) you can use in .NET to do so. To be honest you will mainly call UrlPathEncode when you are constructing paths and UrlEncode when you are constructing a query string. You can read more about that here.

 

The Tricky Part

Some of you may find yourself in the case where you are writing frameworks or controls that generate HTML mark up. For me, given that I work on the ASP.NET team, this is almost always the case. One thing that I see people get tripped up on is using the appropriate type of encoding. A lot of developers will simply just call HtmlEncode and think they are doing the right thing. This is not always the right case! Lets take the example of where we have a control that generates the HTML mark up to include a Xbox Gamercard in a page. The control takes in user (in this case another developer) input for the Gamertag and constructs an IFrame referencing a URL with that uses the given Gamertag. The first, thing that needs to be done is to URL encode the Gamertag as it will become part of a URL. At this point most developers would call it safe and stick it in the SRC attribute of the IFrame but that is not the case. We also need to Attribute encode it because quotation marks are valid URL characters but not valid attribute characters.

  1. string.Format("<iframe src=\"http://gamercard.xbox.com/{0}.card\" scrolling=\"no\" frameBorder=\"0\" height=\"140\" width=\"204\">{1}</iframe>",
  2.         HttpUtility.HtmlAttributeEncode(HttpUtility.UrlPathEncode(gamerTag)),
  3.         HttpUtility.HtmlEncode(gamerTag));

 

For me this is one of the most tricky parts about developing for the web. So hopefully after reading this you have a little bit better idea of how and when you should be encoding. Please let me know if you have any questions.

Update: JavaScript Encoding

One issue that I did not cover in my original post was how to handle encoding when you were in JavaScript. JavaScript contains its own methods for Encoding URLs and HTML etc. and you can google on Bing and find all types of posts on the subject. So I wont spend time discussing those methods. What I would like to discuss is when as a developer of a control or framework you need to output some JavaScript on a page and it needs to use some user input in that Script. For the most part the rules for encoding described above are the same when inside of JavaScript. Even the tricky parts are the same, source attributes need to be URL encoded and then attribute encoded. So for the most part this is all just the same stuff over and over.

There is however one difference, what happens when you need to use user input as a string. For instance you want to store some user string in a variable in JavaScript. There is no rule above that applies to this, but you do need to encode, because that string may include something like a single or double quote. Which means that the string would be ended and everything else would be executed as JavaScript code. There is a new method in ASP.NET 4 that you can use to help you with this, JavaScriptStringEncode. There is even an overload that will add double quotes around the whole thing so you can just drop it right into the JavaScript. Here is some sample code:

  1. string script = "<script type=\"text/javascript\"> var msg = {0}; alert(msg); </script>";
  2. string.Format(script, HttpUtility.JavaScriptStringEncode("some'input", true /*add double quotes*/));

 

Would return the following string

  1. <script type="text/javascript"> var msg = "Some\'Input"; alert(msg); </script>

author: Matthew M. Osborn | posted @ Wednesday, May 05, 2010 4:17 PM | Feedback (5)

What’s in my laptop bag?


UPDATE: I figured it was time do the obligatory “what’s in my laptop bag” post. If you have been following my twitter stream you might have seen that I just purchased a new MacBook Pro and I figured it was time to get a new laptop bag as well. Previously I had the a Microsoft Ogio bag, basically the same as the Ogio Hip Hop. After some strong recommendations from my friends I decided on a Tom Bihn bag for the new one. For those not familiar with Tom Bihn they are awesome bags with awesome attention to detail. I ended up choosing the black Super Ego bag with the appropriate gray Brain Cell insert. So to make a short story long, having to switch everything over to the new bag I figured it would be the perfect time to do this post.

What's in my bag
  • MacBook Pro 15 inch. i7, 8GB of RAM, and 160 Intel SSD
    • Extra power brick
    • Display port to VGA adapter
  • Kindle 2 32GB iPAD
  • Zune 120GB
  • Flip HD
  • My digital camera (used to take the picture)
  • 80GB portable Hard drive
  • A couple of thumb drives (one of which is bootable)
  • Extra SD card and MicroSD adapter
  • USB (micro & mini verities), iPhone, and Zune cables
  • Chargers (USB wall adapters and my camera charger)
  • iPhone headphones
  • Moleskin notebook
  • Checkbook and pens
  • Microsoft free support cards (giveaways when I need to get out of a “my computers broke” talk)
  • Some of my business cards
  • Some screen cleaning wipes (yes I’m OCD)
  • An umbrella (it rains a lot in Seattle and I ride the bus)

author: Matthew M. Osborn | posted @ Sunday, April 25, 2010 9:18 PM | Feedback (2)

Introducing Browsers Providers in ASP.NET 4


In ASP.NET there is a concept of Browser Capabilities, they define what the device that issued the request to the site is capable of doing. For instance things like “Supports JavaScript” and “Supports Frames”, they also provide other meta information about the device such as the Name and version number. I’ll be the first to say that most of the values that are in there are no longer really useful. For example that is a property called “Is AOL”, yes I’m not kidding but at some point in time you wanted to know these things. I’m not going to spend any more time talking about what Browser Capabilities But if you don’t know you might consider watching this before continuing. Also, you might want to check out the Mobile Device Browser File on codeplex. 

imageOkay so what is the big deal with the Browser Providers? In previous versions you had two options if you wanted to modify or extend how ASP.NET determined the devices capabilities. The first is to modify the Machine level browser file in the framework directory. The second is to add a .browser file to the App_Browsers folder in the website, which gave you website level control. If you look at the File Scheme for the .browser files you will quickly see how this could be a problem if you wanted to do any dynamicish stuff because it was just a flat file.

Okay so now you understand the problem you can understand how Browser Providers fix the problem. They are a special type that is registered in application wide that has methods that are executed on each request and allow you to add, remove, or modify capabilities in the browser capabilities collection. The easiest way to do this is to inherit from our default provider and override the methods.

 


  1. public class CustomProvider: HttpCapabilitiesDefaultProvider
  2. {
  3.     public override HttpBrowserCapabilities GetBrowserCapabilities(HttpRequest request)
  4.     {
  5.         HttpBrowserCapabilities caps = base.GetBrowserCapabilities(request);
  6.         caps.Capabilities["Used www"] = request.RawUrl.Contains("www.");
  7.         return caps;
  8.     }
  9. }

 

In this example I am just looking at the url that was used to make the request and seeing if the device/user put “www.” in front of the request. Not really useful but it is a demo. Also, remember that this is executed for each request so the code that goes in here should be Very speedy. You do not want to hold up the request while the provider goes and talked to a database. Now that you have your provider you need to register it with the application. You can do this is the browserCaps in the web.config or you can register in the Global.asax, like so.

  1. void Application_Start(object sender, EventArgs e)
  2. {
  3.     HttpCapabilitiesBase.BrowserCapabilitiesProvider = new CustomProvider();
  4. }

 

Now your provider will run on each request, it’s pretty simple I know. The main thing to remember is that because it run on each request it should be lightweight code that executes and honestly this should be one of those time where creating a browser provider is the last resort, in my opinion at least.

author: Matthew M. Osborn | posted @ Friday, March 19, 2010 2:10 PM | Feedback (0)

MVC 2 RTM Is Out!


RoughLife My involvement in MVC 2 started almost a year ago, and it has been one crazy year! For me this is a rather important release because it was really the first major project I have ever worked on and my first Microsoft project to RTM. I have grown leaps and bounds over this last year and learned more than I ever thought I could. I had the privilege of working with some of the smartest people I know and to be quite frank it was rather humbling. My hat goes off to each and everyone of them for having to put up with me and not going postal. Okay so yes enough of that emotional stuff and on to the interesting stuff MVC 2.

Okay so I am sure there will be numerous other posts from the likes of The GU™ and Phil Haack about MVC 2 and what is new in it so I’m not going to go in depth but i would like to call out a few features that I think are the big ones.

Install MVC 2

Okay so I know you are all hyped up now and can’t wait to install it on all your server I must ask a question of you? Why are you still reading my post? Go download it, seriously stop reading and go install it. If you’re still reading I must say that looking back on everything it feels great to say that MVC 2 is RTM! Once again thanks to everyone on the team for a great time!

author: Matthew M. Osborn | posted @ Thursday, March 11, 2010 9:39 PM | Feedback (0)