Parsing The Payload
Thursday, August 14, 2008 8:14:47 PM (Mountain Standard Time, UTC-07:00)
So this week we got to start working a brand spanking new MVC project. So far we're leveraging Castle Windsor, NHibernate, Fluent Nhibernate, and kind of running Linq to NHibernate. It's amazing how quickly you can get a project up and running in such a short amount of time. (BTW, Fluent NHibernate rocks!) When you're building off the trunk of these projects, it's almost like the contributors to all these great projects are extended members of the team. Thank you all!
Moving on... One of the things that are cool, but also slightly annoying, is how the MVC framework parses out items from the http payload to populate any input arguments on controller actions.
It's great how it just works, but it's a little annoying if it's under test and you have to add more fields, or remove fields from a form, then you have to go update the signature of the action then go update the test.... yada yada The changes just ripple down...
So one thing we tried out this week was to create a payload parser. What this guy does is take a DTO parse out the values for each of the properties on the DTO from the current requests payload and fill it. This makes it easy to package up the form parameters in a nicely packaged DTO and fire it off down to a service layer to do some work.
So instead of declaring an action method on a controller that looks like this, where the signature would have to change based on what fields are submitted on a form:
ViewResult register_new_account(string user_name, string first_name, string last_name)
We can write this...
public ViewResult register_new_account() {
var accountSubmissionDTO = parser.MapFromPayloadTo<AccountSubmissionDTO>();
var validationResult = task.Validate(accountSubmissionDTO);
if (validationResult.IsValid) {
task.Submit(accountSubmissionDTO);
return View("Success", accountSubmissionDTO);
}
return View("Index", validationResult.BrokenRules);
}
This better allows us to adhere to the OCP. If we need to include additional fields on the form, we can add them to the form as long as the control name is the same as the name of the property on the DTO that it will be bound to. The implementation of the payload parser is quite primitive for now, but at the moment it's all that we needed.
First up the specs... simple enough, for now!
public class when_parsing_the_values_from_the_current_request_to_populate_a_dto : context_spec<IPayloadParser>
{
[Test]
public void should_return_a_fully_populated_dto()
{
result.Name.should_be_equal_to("adam");
result.Age.should_be_equal_to(15);
result.Birthdate.should_be_equal_to(new DateTime(1982, 11, 25));
result.Id.should_be_equal_to(1);
}
protected override IPayloadParser UnderTheseConditions()
{
var current_request = Dependency<IWebRequest>();
var payload = new NameValueCollection();
payload["Name"] = "adam";
payload["Age"] = "15";
payload["Birthdate"] = new DateTime(1982, 11, 25).ToString();
payload["Id"] = "1";
current_request.setup_result_for(r => r.Payload).Return(payload);
return new PayloadParser(current_request);
}
protected override void BecauseOf()
{
result = sut.MapFromPayloadTo<SomeDTO>();
}
private SomeDTO result;
}
public class when_parsing_values_from_the_request_that_is_missing_values_for_properties_on_the_dto :
context_spec<IPayloadParser>
{
private AccountSubmissionDTO result;
[Test]
public void it_should_apply_the_default_values_for_the_missing_properties()
{
result.LastName.should_be_null();
result.EmailAddress.should_be_null();
}
protected override IPayloadParser UnderTheseConditions()
{
var current_request = Dependency<IWebRequest>();
var payload = new NameValueCollection();
payload["FirstName"] = "Joel";
current_request.setup_result_for(x => x.Payload).Return(payload);
return new PayloadParser(current_request);
}
protected override void BecauseOf()
{
result = sut.MapFromPayloadTo<AccountSubmissionDTO>();
}
}
public class SomeDTO
{
public long Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public DateTime Birthdate { get; set; }
}
The current implementation:
public interface IPayloadParser {
TypeToProduce MapFromPayloadTo<TypeToProduce>() where TypeToProduce : new();
}
public class PayloadParser : IPayloadParser {
private readonly IWebRequest current_request;
public PayloadParser(IWebRequest current_request) {
this.current_request = current_request;
}
public TypeToProduce MapFromPayloadTo<TypeToProduce>() where TypeToProduce : new() {
var dto = new TypeToProduce();
foreach (var propertyInfo in typeof (TypeToProduce).GetProperties()) {
var value = Convert.ChangeType(current_request.Payload[propertyInfo.Name], propertyInfo.PropertyType);
propertyInfo.SetValue(dto, value, null);
}
return dto;
}
}
Spikin' MVC
Saturday, May 17, 2008 2:35:30 PM (Mountain Standard Time, UTC-07:00)
So last week the guys and I at work started to spike ASP.NET MVC. We're starting up a new project, and decided to take advantage of the Preview 2 version of the so far released libraries. Our experiences so far have been.... hmmm... not as expected.
Here's a few things we've learned, hopefully they help someone else out. We're nant junkies, so the first thing we did to get going was automate the compiling, testing, running, deploying, and creation of the database with nant. We found that when running our project against the aspnet_compiler.exe that it didn't recognize some of the new C# 3.0 syntax.
<select name="protocolName">
<% foreach( var dto in ViewData ) {%>
<option><%= dto.ProtocolName %></option>
<% } %>
</select>
The above code would raise an error with the aspnet_compiler.exe. Now this is valid C# 3.0, but the pre compiler didn't know what to do with the "var" keyword. Next, the precompiler didn't know where to find the "Form()" method on the Html helper class because, it's an extension method.
<% using( Html.Form( Controllers.Order.Name, "submit", FormMethod.Post ) ) {%>
It's kind of an interesting idea that so many methods on the "HtmlHelper" class are extension methods. The solution to getting the aspnet_precompiler to recognize the C#3.0 syntax was to dump this block of xml in the web.config.
<system.codedom>
<compilers>
<compiler language="c#;cs;csharp" extension=".cs" warningLevel="4"
type="Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<providerOption name="CompilerVersion" value="v3.5"/>
<providerOption name="WarnAsError" value="false"/>
</compiler>
</compilers>
</system.codedom>
Next up... testing controllers. I think the guys and I were a little surprised at just how awkward it was to test a controller. I thought, a lot of time was spent making the controllers more testable. Our first pain point was the fact that "RenderView()" is a protected method on the Controller base class. Here's what I'm talking about...
public class HomeController : Controller
{
public void Index( )
{
RenderView( "Index" );
}
public void About( )
{
RenderView( "About" );
}
}
So let's think... how can we test that when the Index action is invoked it calls "RenderView" with an argument value "Index"... So some people have suggested creating a Test Double. I say... booo... I use mock object frameworks so that I don't need to groom a garden of hand rolled test stubs. Here's what we came up with... first cut remember!
public class OrderController : BaseController, IOrderController
{
private readonly IOrderIndexCommand indexCommand;
private readonly ISubmitOrderCommand submitCommand;
public OrderController( IOrderIndexCommand indexCommand, ISubmitOrderCommand submitCommand )
{
this.indexCommand = indexCommand;
this.submitCommand = submitCommand;
}
public void Index( )
{
indexCommand.InitializeWith( this );
indexCommand.Execute( );
}
public void Submit( )
{
submitCommand.InitializeWith( this );
submitCommand.Execute( );
}
}
Ok... so it's slightly more testable. Each action on the controller executes a command, after first being initialized with ... The other thing to notice is that the OrderController inherits from BaseController. BaseController is actually an adapter that implements an IViewRenderer interface.
public abstract class BaseController : Controller, IViewRenderer
{
public void Render< TypeToBindToView >( IView view, TypeToBindToView viewData )
{
RenderView( view.Name( ), viewData );
}
}
The OrderIndexCommand is initialized with an IViewRenderer.
public class OrderIndexCommand : IOrderIndexCommand
{
private IViewRenderer viewEngine;
private readonly IOrderTasks task;
public OrderIndexCommand( IOrderTasks task )
{
this.task = task;
}
public void InitializeWith( IViewRenderer engineToRenderViews )
{
viewEngine = engineToRenderViews;
}
public void Execute( )
{
viewEngine.Render( ControllerViews.Order.Index, task.RetrieveAllProtocols( ) );
}
}
What's Wrong With Inline ASPX
Tuesday, December 18, 2007 1:42:36 PM (Mountain Standard Time, UTC-07:00)
This month I've been going pretty hard core about learning ASP.NET and I was having a lot of difficulty with playing with the ASPX view engine. I'm already fairly familiar with HTML and CSS, but now I have to learn these new ASP.NET controls? Why can't I just stick to the HTML and CSS I know and enjoy working with?
Well it turns out I can... I don't need to learn about the complex data binding of a GridView or how an ASP:TextBox converts to a plain ol' input tag wrapped in span tags. I've been heavily studying the work from the project we worked on during the Nothin' But .NET boot camp and reading up on the MSDN documentation on inlining aspx.
I like it... C'mon doesn't this....
<h1>Available Slips</h1>
<table>
<thead>
<tr>
<td>Location Name</td>
<td>Dock Name</td>
<td>Slip Width</td>
<td>Slip Length</td>
</tr>
</thead>
<% foreach ( SlipDisplayDTO item in ViewLuggage.ClaimFor(ViewLuggageTickets.AvailableSlips) ) {%>
<tr>
<td><%= item.LocationName %></td>
<td>
<a href='<%= WebViews.DockView.Name( ) %>?<%= PayloadKeys.DockId %>=<%= item.DockId %>'>
<%= item.DockName %>
</a>
</td>
<td><%= item.Width %></td>
<td><%= item.Length %></td>
</tr>
<% } %>
</table>
Seem a lot more readable then this...
<asp:Repeater ID="uxSlipsRepeater" runat="server">
<HeaderTemplate>
<table>
<thead>
<tr>
<td>Dock Name</td>
<td>Slip Width</td>
<td>Slip Length</td>
</tr>
</thead>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<a href='DockView.aspx?<%= PayLoadKeys.DockId %>=<%# ((SlipDisplayDTO)Container.DataItem).DockId %>'>
<%# Transform.From(Container.DataItem).AndConvertItToAn<SlipDisplayDTO>().DockName %>
</a>
</td>
<td><%# Transform.From(Container.DataItem).AndConvertItToAn<SlipDisplayDTO>().Width %></td>
<td><%# Transform.From(Container.DataItem).AndConvertItToAn<SlipDisplayDTO>().Length %></td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
The extra asp namespaces appended to all the controls just seem like noise. The explicit casting from Container.DataItem to the type actually contained seems like extra work. I suppose you could write all this out in an item data bound event handler. But it just looks like noise, noise noise... Then when you actually look at the HTML that's spit out it loaded with more noise...
For example:
<input
name="ctl00$ContentPlaceHolder2$uxUserNameTextBox"
type="text"
id="ctl00_ContentPlaceHolder2_uxUserNameTextBox" />
Versus:
<input name="uxUserNameTextBox" type="text" />
Well all of this can be avoided. But you're going to have to get just a little bit deeper, and here's how. Everything you need to know is in HttpContext. Yup!
Instead of dropping an ASP:TextBox on the page try an input element and parse out the value in the input element from the HttpContext.Current.Request.Params. This is a NameValueCollection that has all the Http Headers that were sent along the trip to the server AKA The Payload.
For my current school assignment I'm currently flushing out the concept of an HttpGateway, where all traffic comes in and all traffic goes out. Currently this is just wrapping and HttpContext but with an interface that works better for me as a client of it. I don't need to see everything available in the HttpContext (which is a lot!).
Next up, take advantage of the HttpContext.Items collection. This is a collection of objects which you can load up with extra information to pass on down the pipeline. Consider the concept of view luggage, where luggage is issued a ticket when you drop it off. You can then claim that luggage using the same luggage ticket.
What does this mean, you can have your presenters, controllers, commands (whatever) drop off luggage to be carried to the view. You can then have your views claim that luggage with the luggage ticket. (Take a look back at the first bit of HTML markup in this post.)
The HttpContext.Items collection is a dictionary for objects. Using strongly typed luggage tickets you can make that the key, and the actual luggage the value to store in the items collection. The HttpContext then becomes the airplane, carrier or transporter that hauls your luggage from your presenter, controller, command (whatever) to the view.
For the quick and dirty here's the code that describes what I'm talking about:
public class ViewLuggageTransporter< Luggage > : IViewLuggageTransporter< Luggage > {
public ViewLuggageTransporter( IViewLuggageTicket< Luggage > key ) : this( key, HttpContext.Current.Items ) {}
private ViewLuggageTransporter( IViewLuggageTicket< Luggage > key, IDictionary items ) {
_ticket = key;
_items = items;
}
public Luggage Value() {
foreach ( DictionaryEntry entry in _items ) {
if ( entry.Key.Equals( _ticket ) ) {
return ( Luggage )entry.Value;
}
}
return default( Luggage );
}
public void Add( Luggage value ) {
_items.Add( _ticket, value );
}
private readonly IViewLuggageTicket< Luggage > _ticket;
private readonly IDictionary _items;
}
public class ViewLuggage {
public static IViewLuggageTransporter< T > TransporterFor< T >( IViewLuggageTicket< T > ticket ) {
return new ViewLuggageTransporter< T >( ticket );
}
public static T ClaimFor< T >( IViewLuggageTicket< T > ticket ) {
return new ViewLuggageTransporter< T >( ticket ).Value( );
}
}
To parse out the value submitted in a request you can create mappers to parse out the values for each control. In the code below each of the string literals prefixed with a "ux" represents the name of the html control that was on the page.
public class UpdateRegistrationPresentationMapper : IUpdateRegistrationPresentationMapper {
public UpdateCustomerRegistrationDTO MapFrom( IHttpRequest input ) {
return new UpdateCustomerRegistrationDTO(
input.ParsePayloadFor( PayloadKeys.CustomerId ),
input.ParsePayloadFor( PayloadKeys.For( "uxUserNameTextBox" ) ),
input.ParsePayloadFor( PayloadKeys.For( "uxPasswordTextBox" ) ),
input.ParsePayloadFor( PayloadKeys.For( "uxFirstNameTextBox" ) ),
input.ParsePayloadFor( PayloadKeys.For( "uxLastNameTextBox" ) ),
input.ParsePayloadFor( PayloadKeys.For( "uxPhoneNumberTextBox" ) ),
input.ParsePayloadFor( PayloadKeys.For( "uxCityTextBox" ) )
);
}
}
For an even sweeter example check out the source code for the NothinButDotNetStore.
Next up, figuring out a cleaner way to implement authorization and authentication without having to rely on the FormsAuthentication class. So far my spiking of Forms Auth looks something like the code below... *Please do not use the code below. I was just trying to understand how forms auth works and this is not a great example of how you should use it.
public void AuthenticateHttpRequest( ) {
HttpCookie cookie = GetCookieFrom( HttpContext.Current );
if ( null != cookie ) {
BindPrincipalToThreadUsing( _mapper.MapFrom( FormsAuthentication.Decrypt( cookie.Value ) ) );
}
}
private HttpCookie GetCookieFrom( HttpContext context ) {
return context.Request.Cookies[ FormsAuthentication.FormsCookieName ];
}
private void BindPrincipalToThreadUsing( CustomerCookieCredentials credentials ) {
IIdentity identity = new CustomerIdentity( credentials.Username, credentials.Username );
HttpContext.Current.User = new GenericPrincipal( identity, new string[] {"customer"} );
}
private void AddAuthenticationTicket( ) {
FormsAuthenticationTicket ticket =
new FormsAuthenticationTicket( 1, "mo", DateTime.Now, DateTime.Now.AddMinutes( 20 ), false, "2" );
string cookieValue = FormsAuthentication.Encrypt( ticket );
HttpContext current = HttpContext.Current;
current.Response.Cookies.Add( new HttpCookie( FormsAuthentication.FormsCookieName, cookieValue ) );
IIdentity identity = new CustomerIdentity( "mo", "2" );
current.User = new GenericPrincipal( identity, new string[] {"customer"} );
}
Understanding HTTP
Monday, July 02, 2007 4:27:51 PM (Mountain Standard Time, UTC-07:00)
HTTP is used for so many different reasons. While working in the wold of point of sale terminals, I spent some time sending raw HTTP packets and parsing them in C. Lot's of fun!
Here's a quick little exercise on playing with HTTP, that i found in "Microsoft .NET Framework 2.0 Web-Based Client Development"
1. Open up a command prompt: Start->Run->cmd
2. type "telnet", and press enter
3. type "o mokhan.ca 80"
4. type
"GET / HTTP/1.1
Host: mokhan.ca"
Then press enter twice
But do it quickly, before my server closes the connection due to a timeout!
 | MCTS Self-Paced Training Kit (Exam 70-528): Microsoft .NET Framework 2.0 Web-Based Client Development (Pro Certification) by Glenn Johnson, Tony Northrup
Read more about this title... |
HTTP Verbs and SMTP Over Simplified
Wednesday, June 27, 2007 7:21:47 AM (Mountain Standard Time, UTC-07:00)
I gave this explanation to my wife last night on SMTP, so hopefully it will help...
SMTP stands for Simple Mail Transfer Protocol... you can think of it as a mailbox. When you need to send mail to someone you put the mail in the mailbox, and a mail person comes and picks up the mail and sends it to where ever it needs to go.
Now pretend that we didn't have Canada Post to send our mail and in order to have your mail sent you had to subscribe to a mail service, so that you had access to their mail box, so that their mail person would come pick up the mail and deliver it for you.
I subscribe to Shaw cable, so they offer me their "mailbox" or SMTP server for me to send all my outgoing mail through... If I want to send mail through GMail's SMTP server I would need to have access to it.
HTML Forms...
There are many types of HTTP commands that are sent to a server the 2 most popular are GET, POST.
The GET verb requests a resource from the server, like a web page.
The POST verb sends data to the server like in a contact form.
Stop Pretending ASP.NET
Tuesday, June 05, 2007 10:56:37 AM (Mountain Standard Time, UTC-07:00)
I just read an excellent article on feelings on ASP.NET. Although, I don't have as much experience with ASP.NET as the author, I feel the same way about it.
Although, it gives us a lot of power, it is so much more bulkier then it could be. The false sense of "state" that it provides us, and the way we have to program around it, is odd. I much prefer the world of desktop application development for it's true stateful environment, however I like the power of the web when it comes to communicating messages to the world.
"Now the first problem with Webforms is not that its an abstraction, or even that its a leaky one (they all are). The problem is that what Webforms attempts to abstract away is actually simpler than the abstraction!" - Jeff Perrin
It's odd how many so called ASP.NET developers couldn't write the simplest HTML. It seems the concept of standards compliance, and html validation is not of importance. Why?
(Do me a favor and stop writing so much of your heavy business logic write into the code behind of your web forms and custom controls. Do you have any idea how difficult it is to make a simple change?)
Obscuring HTTP
AJAX Call Processor with ASP.NET
Friday, June 30, 2006 9:17:35 PM (Mountain Standard Time, UTC-07:00)
AJAX, shorthand for
Asynchronous JavaScript and XML, is a
Web development technique for creating interactive
web applications. The intent is to make web pages feel more responsive by exchanging small amounts of data with the server behind the scenes, so that the entire web page does not have to be reloaded each time the user makes a change. This is meant to increase the web page's interactivity, speed, and
usability." -
wikipedia There are 3 main components in my AJAX implementation. The client side JavaScript and HTML, and the server side AJAX call processor. For this articles I am going to discuss how I implemented the blog page on this site using AJAX.
Client Side
If you check the source code behind my blog page you may notice 2 script files were included. These are "ajax_obj.js" and "getEntry.js". The "ajax_obj.js" file creates an instance of the "XMLHttpRequest" object for non Microsoft browsers and an "ActiveXObject" for Microsoft web browsers. This object is pretty cool, it's the basis for almost all AJAX technology. Learn it, understand it and AJAX will become a breeze.
The 2nd js file, "getEntry.js" performs the interaction between my web server and the client machine (You're the client by the way!). What it does is sends a request to my server for my latest blog entry, my server takes the request and returns just the blog entry. Duh!
But how does it do this? Using the "XMLHttpRequest" or "ActiveXObject" object instantiated in the "ajax_obj.js" file we use 4 methods/properties. To make this easy let's call this guy "goAJAXReq", short for global AJAX request object.
- open: This specifies what type of request I would like to make the server, and what URL to call.
- onreadystatechange: This specifies a "callback" function to handle the servers response to my request. The callback is basically a function created in order to receive the call back. It's like leaving a voicemail message on your buddy's phone and telling him to call you back at this number when he gets the message.
- send: This tells the "goAJAXReq" to send the request to the server. Kind of like picking up the phone to call your buddy. Except like me your buddy never answers the phone so you'll have to leave a message.
- status: This tells you the status of your request so far. It's actually and HTTP status, and would be similar to an operator message. "This number cannot be reached. Please try again!" If you don't get this message most people here a "Hello!?" on the other end. The "Hello" is a 404 status. The operator message is like the HTTP 200 or 404 status.
"getEntry()" function. This guy dials the phone number, leaves a message with a "callback" number and pressed # to send the message.
"updatePage()" is the number buddy can call me back at. So when buddy calls me I answer at this number and he gives me the info that I need. When I receive my blog entry back from my server I search for an HTML element on the page called "blog". This is defined as a <div> tag, and I write the data returned back to me in this element. Voila, that's the AJAX on the client side. Now you can go into a lot more detail with how you would like your data sent to you, and how you would like it packaged and unpackaged. But for this example, my call returned straight forward HTML for my blog entry.
Server Side
The server side implementation can be done in so many different ways. Most of the AJAX articles I found on the net used PHP, for this example I am using ASP.NET. The key component in my implementation is the use of "reflection". My AJAX object "goAJAXReq" sends the method name it wishes to run at the server to return the data it wants. In this example the method was "getEntry". Using reflection I parse out the value for the method variable and call that function. This function grabs my latest blog entry, makes sure its valid HTML and returns the data to the client.
In my AJAX call class I parse out the value for the "method" variable from the request stream. I am using the "method" variable to contain the name of the method I want to invoke. In this example the request stream is sending "method=getEntry". This means the request stream wishes to process the "getEntry" method on the server. After parsing our the "getEntry" name I use reflection to call that method. My "getEntry" method grabs my latest blog entry and writes it directly to the "response" stream. This is what carries the data being transferred back to the client.
Voila! My AJAX call processor is complete. If you have any questions at all please contact me!