ASP.NET 4.5 Loves HTML5, CSS3, & JavaScript


ImAtBuildToday I had the pleasure of giving a presentation at the //BUILD conference in Anaheim, CA. Given that this conference is all about Windows 8 I was one of the few non windows session at the conference. Bellow is the abstract from my talk entitled. For those of you that weren’t lucky enough to get to come to //BUILD there is good news! All the session will be recorded and posted online and that includes mine. You can find a my session session on Channel 9 (although it may take a day or so to get posted). If you want to download the demos and slides head of to my Talks page on my website and if you have questions please don’t hesitate to email me!

 

 

ASP.NET 4.5 Loves HTML5, CSS3, & JavaScript.

Whether you’re building a new Website using ASP.NET or maintaining an existing one, you’ll leave this talk ready use HTML5 & CSS3 on ASP.NET with Visual Studio. We’ll look at what HTML5 & CSS3 have to offer modern app developers and how you can use them with ASP.NET for rich Web apps both today and tomorrow.

author: Matthew M. Osborn | posted @ Wednesday, September 14, 2011 5:22 PM | Feedback (1)

ASP.NET 404 Custom Errors & IIS


Recently I have been spending a fair amount of time working on the NuGet Documentation site (read more about it here). One of the improvements I wanted to make to it was to add useful error pages. You know more than the YSOD (yellow screen of death). One of the major issues for me was creating a useful and informative 404 page. I wanted the page to tell the user why they got there, offer suggestions about what page they may be looking for, and allow them to search the site. So I did the development work committed the changes and had the CI machine push to the server (in the case app harbor).

  1. <system.web>
  2.     <compilation debug="true" targetFramework="4.0" />
  3.     <customErrors mode="On" defaultRedirect="~/error">
  4.         <error statusCode="404" redirect="~/404" />
  5.     </customErrors>
  6. </system.web>


But I was still seeing the generic IIS sever errors! I did some searching on the internet and Twitter and found a helpful property of the response object.

  1. Response.TrySkipIisCustomErrors = true;


By default IIS will see an response with an error status code (400-500) and will automatically change the content of the response to its default error page. What this property does it tell IIS not to do that if there is already content in the body of the page. Well that was easy, right? So I made the change and pushed it to the server, and navigated to a page that didn’t exist. Well the server still returned me the default 404 page, but on a 500 it would give me my custom error page. So what gives? Well here is the deal, the way routing works is that if ASP.NET cannot find a file that matches the requested URL the request is given back to IIS to handle. So in the case of a 404 ASP.NET can’t find the file so its given back to IIS who uses the default static file handler to serve the request. This would be slightly different if the route had matched but then say somewhere in our code we set the status to 404. In this case it would already be in the ASP.NET pipeline and ASP.NET would server the custom 404 page.

There are two ways to solve this problem. First is the easiest which is to open up IIS Manger and go to the “Error Pages” settings under IIS and change the 404 page there to use your custom 404 page.

IIS

This is fine if you can remote into the server or you’re not running in the cloud where multiple instances can be started. So how then do you make that work? Well lucky for us starting with IIS7 and later these settings can be added to your web.config file under the System.WebServer node.

  1. <system.webServer>
  2.     <httpErrors errorMode="Custom" >
  3.         <remove statusCode="404" subStatusCode="-1"/>
  4.         <error statusCode="404" path="/404" responseMode="ExecuteURL" />
  5.     </httpErrors>
  6. </system.webServer>


So lets dig into what some of this code means and tell you about the tricky parts that you need to know. Before you can add a custom page you need to remove the entry for the status code as there can only be one entry per status code. The tricky bit here is knowing to set SubStatusCode to –1. This basically means all the possible sub statuses. If you like you could remove only the specific one you needed and set only the specific one. Also if you are playing around with the config you might find that there is a defaultPath attribute on the httpErrors node. This defines a “default” error page should an entry not be found in the list. The problem is that by default this is “locked” and cannot be set in an applications web.config and instead needs to be set at the machine level.  Once you add these settings to your config you should be able to see your custom error page when you navigate to a page that does not exist. As a side note this just drives home the importance of IIS Express and why you should use it for development. This would have been discovered prior to pushing changes to the live server that way.

author: Matthew M. Osborn | posted @ Friday, May 27, 2011 11:12 AM | Feedback (1)

Introducing NuGet Docs: Community Driven Documentation


NuGetDocsLogohttp://docs.nuget.org

Introducing NuGet Docs: http://docs.nuget.org! NuGet Docs is a community driven documentation site that provides guides, walkthroughs, and information about anything and everything NuGet related. NuGet Docs is your new resource for learning and understanding how to use NuGet to the fullest. There is information about how to use NuGet to consume packages, information about how to create your own packages, and even information about how to contribute to NuGet along with much more. This is the first iteration of the site and the documentation that is contained on it. So we hope you understand it might be rough around the edges, but here is the good news its community driven so you can contribute your knowledge and understand to help make it better. More about how to do that later.

Let’s talk about the reason, goal, and focus behind NuGet Docs for a minute. Historically speaking open source software lacks good documentation. NuGet Docs is the NuGet team’s effort to make documentation a first class citizen. We want our documentation to be just as awesome as our product, because no matter how awesome NuGet is if no one can understand it, it’s nothing more than “the suck.” The focus of the site is really about providing the user with the information they need. We don’t want so much flashy chrome that it blinds the user from the information they are looking for. First and foremost the number one priority of the NuGet Docs site is the content! Another key aspect of NuGet Docs is that we designed it to be easy to create, update, and maintain the documentation. So let’s talk more about how we achieved that.

NuGet Docs is an ASP.NET WebPages application extended to support the use of markdown files (.markdown). What this means is that the core of the site is coded in ASP.NET WebPages while the documentation itself is written in markdown. For those of you unfamiliar with markdown it is basically a more human readable way to annotate a document so that HTML can be created from it. More information about Markdown can be found here. By using markdown we allow the authors of the documentation to have a better experience while still allowing rich visual content to be created. We also wanted it to be easy to create new content on the site. With that in mind all that is required to create a new page is add a markdown file and it will be added to the site and show up in the menus. There are some conventions that need to be followed but you can read more about that in the "Contributing to NuGet Documentation" page on NuGet Docs (I know, so meta).

So what are you waiting for? Head over to the NuGet Docs site and read up about anything and everything NuGet. When you’re done why not take the time to contribute your knowledge to collective (Star Trek reference) and write some documentation yourself? For those of you that do contribute to NuGet Docs we have a preview site (http://preview.docs.nuget.org) that all changes will be pushed to and then when a new version of NuGet is released we will port the preview site to the live site. This means that you can even help write documentation for features that are not in the current released version but are in CI builds. We know you love being on the bleeding edge. Also we appreciate hearing your feedback and hearing about bugs you encountered (hey, why aren't you submitting patched for them?). You can provide those opinions and issue on the NuGet Docs CodePlex site.

author: Matthew M. Osborn | posted @ Wednesday, May 11, 2011 4:18 PM | Feedback (6)

Joining the Dark Side | SDET to SDE


dark-sideToday I am excited to announce that I have joined the Dark Side and by Dark Side I mean the developer team here at Microsoft. Many of you know that for the past two and half years I have worked on the ASP.NET team as a Software Development Engineer in Test or SDET. It has been an awesome experience and I enjoyed every minute of it, however my true passion is writing production code and that is why I have decided to make the switch to a Software Development Engineer or SDE.

So what did I do while I was a SDET? I worked on several products that have been shipped. I started out on the team working on the ASP.NET WebForms mainly the ClientID feature in 4.0. Then I moved to the MVC 2 team where I was able to experience the entire lifecycle. Most recently I worked on both ASP.NET WebPages and NuGet. One of my favorite products I worked on while on the QA team was LTAF! For those of you that don’t know that is a in process test framework that the ASP.NET QA team created and uses. In my time on the QA team I also created a podcast called Coding QA. The focus of the show was to explain how we test software on the ASP.NET team and also to let me vent about my frustrations. Okay so what will I be working on now? In the near future I will be working on the vNext of the ASP.NET MVC framework as well as vNext of ASP.NET WebPages. I will also continue to contribute to NuGet with what little free time I will have left.

Overall, it really doesn’t seem like much has changed given that I am on the same team, working on the same products, setting in the same office, but I am looking forward to all the new and exciting opportunities that I will have as a SDE! Also, that means that there is even more openings on the QA team so if your interested check them out here. Trust me the ASP.NET QA team isn’t just a bunch of button clickers its a lot of fun, check out Coding QA if you don’t believe me.

author: Matthew M. Osborn | posted @ Wednesday, February 23, 2011 12:00 PM | Feedback (2)

New and Improved Templates in WebMatrix


New Templates With the latest release of WebMatrix and ASP.NET WebPages I am proud to announce that we have been working to clean up the HTML, CSS, JavaScript, and general file and folder structures of the templates that we ship with the product. One of the major objectives was to provide general guidance on how a developer might actually set up a production website. This means we wanted to get ride of the “this is just a sample” mentality and really write some good code. That being said we also wanted to be able to slowly move users into more complex concepts. For instance one common optimization is to use CSS Sprites on websites. The problem is that this can be confusing when you are just starting to learn HTML and CSS. So we tried to come up with a good balance of production code and easy to understand code. When we were working on the templates we came up with the concept of a level system where Starter Site was entry level and you worked your way up through Fourth Coffee and Link Directory (in this release we didn't have time to get to Link Directory) to Photo Gallery and Wish List (Also didn’t have time to get to this one in this release).

So what are some of the improvements we made? Well the biggest and most prevalent is something called progressive enhancements. That means that if you view the website in a browser that supports HTML5 and CSS3 you get an even better experience but down level browsers still work and look great. We also took a look at some common practices used by the types of sites and tried to incorporate them. For instance ecommerce sites like Fourth Coffee often have featured products and photo galleries normal reduce the amount of text and focus on the images themselves. One on the improvements that I am most proud of is that now all of the templates that we worked on this release pass HTML5 validation and CSS3 validation (CSS3 validation shows errors due to the namespaced selectors used by most browsers, but this is common practice). In addition to all of this we spent a lot of time cleaning up code and making sure that it was readable and easy to understand.

When we started doing all of these improvements we decided that we were going to create a guideline document that we could use to define how templates should be developed. This document wasn’t a be all end all guide but it was a starting point. Some of the rules might need to be broke from time to time (sometimes to make things more understandable). Overall it was a good starting point and I would like to share an example of the rules we came up with. If you have your own I’d love to hear them!

  • Accessibility
    • Templates need to pass the accessibility tests at: http://wave.webaim.org/
    • Templates will satisfy all requirements of WCAG 2.0 level AA.
  • Validation
  • Images
    • Photos are .JPEG
    • Graphics are .PNG
    • Consider using sprites when possible
  • Formatting
    • Four spaces should be used instead of tabs
    • Colors defined in a comment in the top in CSS
    • Nest child selectors in CSS
    • Shorthand used when possible in CSS
      • Color codes ("#fe8" instead of "#ffee88")
      • Collapsed properties ("border: solid 1px red" instead of "border-width: 1px; border-color: red; ...")
    • Use lowercase for color codes in CSS
  • File Names
    • All files names should use CamelCase
      • _MyLayout.cshtml
      • AddContact.vbhtml
      • APageWithAReallyLongName.cshtml
  • Code
    • DO: Keep the application logic at the top of the page before the markup
    • DO: Follow the 1TBS Style variant of K&R
    • DO: Use one space after statement keywords
    • DO NOT: Use one space after open parenthesis or before close parenthesis.

Below are some images of what the visual improvements we made to the templates. Please take a look at them and also download WebMatrix and try the templates out and give us your feedback. A friendly reminder that this is just a beta so we may have missed a few things in the templates but its defiantly heading in the right direction.

Starter Site

Starter Site - Index Starter Site - Register

Fourth Coffee

Fourth Coffee - Index Fourth Coffee - Order Fourth Coffee - About Us

Photo Gallery

Photo Gallery - Galleries Photo Gallery - Gallery Photo Gallery - Tags Photo Gallery - View Photo

Links

author: Matthew M. Osborn | posted @ Wednesday, October 06, 2010 2:00 PM | Feedback (3)

Magic Page Names in ASP.NET WebPages


Capture

UPDATE: In ASP.NET WebPages Beta 2 moving forward we have changed the name of the of _Init to _PageStart and _Start to _AppStart.

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.

[Updated] Download Sample Source: http://samples.osbornm.com/securitydemoupdate.zip

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

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 (19)

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 (3)