Hugoware

The product of a web developer with a little too much caffeine

Archive for May 2009

Anonymous Types – Dynamic Programming With C#

with 15 comments

In a previous post I discussed trying to work with Anonymous types in .NET. I had included some code for working with those types to try and make it easier to pass your information around inside your projects.

Essentially, it was a wrapper for Reflection that allowed you to access properties by providing the correct type and property name. It would keep the instance of the Anonymous type in memory so it could work directly with the object.

You may have noticed that there was .Get() functions, but no .Set() function. Why is that?

You may have never noticed this before, but all of the properties in an Anonymous type are read-only. Most of the time you aren’t going to make changes to those values anyways, but if you can’t assign the value of a property in one pass, then it’s a bummer.

For fun, I took a little time to write another version of AnonymousType. This one is a lot more flexible than the one before, but you aren’t really using C# the way it was intended to be. Instead of using reflection you’re using a Dictionary, specifically with strings (for the property names) and objects (for the values).

You create objects the same way as before, but now you have access to a few more features and functions.

//Creating Instances of AnonymousType
//==============================
//Create a using an Anonymous type
AnonymousType type = AnonymousType.Create(new {
  name = "Jim",
  age = 40
  //method = ()=> { Console.WriteLine(); } // still doesn't work here
});

//or an empty AnonymousType
AnonymousType empty = new AnonymousType();

//or even an existing object
var something = new {
  name = "Mark",
  age = 50
};
AnonymousType another = new AnonymousType(something);


//Creating And Using Methods
//==============================
//append methods and call them
another.SetMethod("print", (string name, int age, bool admin) => {
  Console.WriteLine("{0} :: {1} :: {2}", name, age, admin);
});
another.Call("print", "Mark", 40, false);

//append a method with a return value
another.SetMethod("add", (int a, int b) => {
  return a + b;
});
int result = empty.Call<int>("add", 5, 10);


//Working With Multiple Properties
//==============================
//add properties and work with them (NOTE: a better way is shown below)
another.Set("list", new List<string>());
another.Get<List<string>>("list").Add("String 1");
another.Get<List<string>>("list").Add("String 2");
another.Get<List<string>>("list").Add("String 3");

//or use it an easier way
another.With((List<string> list) => {
  list.Add("String 4");
  list.Add("String 5");
  list.Add("String 6");
});

//you can work with more than one type
another.With((string name, int age) => {
  Console.Write("{0} :: {1}", name, age);
});

Again, this is breaking away from the way C# was intended to be used, so be careful how much you make use of it. For the most part you’re going to want to create your own classes to hold this information, but while working with Anonymous types, this is a quick and easy way to pass your information around.

Stay tuned for version three (something really cool!)

Source Code

Download AnonymousType.Remix.cs

.

Advertisements

Written by hugoware

May 29, 2009 at 2:44 am

Is ASP.NET And MVC Really A Good Fit?

with 8 comments

ASP.NET MVC is a new framework for building web applications. It’s geared to favor TDD and gives programmers more control over the the content that is sent down to the client. I’ve even defended ASP.NET MVC in other places for all of its great new features. I really do like ASP.NET MVC.

But the more I use it, the more I wonder if the pattern really works – or at least as well as WebForms did. Maybe I’m missing something, and I’d gladly take advice, but here are a few of my road blocks.

The Disconnect With RenderPartial

One of the cool things about WebControls was that you still had an awareness of other parts of the page. If you needed some client script to be attached to a page to make your control work, then…

this.Header.Controls.Add(
  new LiteralControl("<script type='text/javascript' >alert('hello world');</script>"
  ));

No problem. Stylesheets can be added, scripts imported – great. But what about MVC, more specifically, inside of a “UserControl/PartialView”.

<% this.Header.Controls.Add(
  new LiteralControl("<script type='text/javascript' >alert('hello world');</script>"
  ));%>

What does this little code snippet create? Object reference not set to an instance of an object. exception. Uh oh. Nobody is home.

But even if you could pass some sort of reference to the header into your control – How do you plan to add anything anyways? Code between <% and %> is executed after your header has been rendered, or at the very least, is no longer checking for changes to itself (I’m not exactly certain if it is fully rendered but it doesn’t reflect any changes made to it).

Of course, you can always add script and link tags inline, but isn’t that a step backwards?

Knowing Everything Going Into A View

Once the controller finished handling a request it passes the information into the view. The view, as I understand it, isn’t supposed to do anything more than display the result. But is it really that simple? Do your views have a standard way of turning out every time? Do you really always know exactly everything you’re planning on displaying? Or the order your plan to show it?

I’m working on a project right now that allows people to type in a search term and then get results from all sorts of categories. Not only that, the results are order by most relevant to least relevant on the view as well as changes up the text and wording of your results depending on your query (like searching for locations near zipcode returns distances or searching for open stores returns hours, etc…).

So here’s the problem – I’ve got defined classes for each of the types of results so I can include a score for each of them (since I can’t use the generated LINQ object), I’ve got a container class for each of them to calculate the scores (since a generic list won’t do), I’ve got another class to represent the view (as the ‘generic type’). I just want to do a LINQ query and drop my results into a Databound control!!

Instead, I’ve got all these extra classes, which feels like clutter to me. Not only that, ordering the content on the page is a trick in itself. With WebForms you could reorder controls and that was the end of it. As of now, I haven’t found an easy way to do this with MVC.

Maybe I’m a little spoiled from using Javascript so much lately working on jLinq. I enjoy the flexibility you have. Want to add a score property? something.prop = "Assigned just like that!"; Need to add a function! something.generate = function() { ... }; If you read my previous post about passing Anonymous Types, you’ll understand where the inspiration came from.

Inline Code Just Doesn’t Replace WebControls

<% and %> just doesn’t work as well as a WebControl. Not only is it a little difficult to read, it’s also deceptive in how it works. For example, what is shown on the page when this view is run?

<%--In the <body> tag--%>
<asp:Content ContentPlaceHolderID="body" runat="server">
    <% this.ViewData&#91;"MyParam"&#93; = 5; %>
</asp:Content>

<%--In the <head> tag--%>
<asp:Content ContentPlaceHolderID="head" runat="server">
    <% =this.ViewData&#91;"MyParam"&#93; %>
</asp:Content>

It’s not 5, but I’m sure you knew that. But does everyone on your team know that? Were you able to say with certainly before you answered?

Now, that’s not to suggest that you can’t make the same mistake inside of a WebForm, but inline server side code is already hard enough to read to begin with; what happens when you start placing your code in the wrong order as well? Moving code between <script> tags doesn’t help that much either.

Exactly, What Are We Testing Again?

I won’t claim to know much of anything about TDD – I’m admittedly as beginner. I’ve noticed the claim that MVC makes great strides in improving TDD by using Controllers. This way you can generate tests using the Controller Actions – something was much more difficult with WebForms.

This might not really be directed at MVC as a fault, but do we really need to test Controller Actions? Or are we actually testing the functionality behind the scenes? For example, I keep seeing a lot of tests like this.

[Test]
public void RouteDefaultsWork() {
    var app = new GlobalApplication();
    RouteCollection routes = new RouteCollection();
    GlobalApplication.RegisterRoutes(routes);
    var context = MvcMockHelpers.FakeHttpContext();
    context.Request.SetupRequestUrl("~/home");

    var data = routes.GetRouteData(context);
    Assert.AreEqual("home",data.Values["controller"]);
    Assert.AreEqual("Index",data.Values["action"]);
}

Is that really a test? That proves something that we’re going to notice the second we run the app (which I’m hoping is done before you release your app 🙂 ) Aren’t we more concerned if our functions that pull, format and update information are accurate. A unit test makes sense for .CalculateRate() or .GetClosestLocationToZipcode(), but I haven’t quite figured out the purpose of testing a controller action.

With that said, are the Controllers really handling this kind of logic? Or haven’t we created separate, reuseable classes elsewhere that are handling this programming? If so, is making Controllers available for writing tests really all that helpful? I don’t really know.

I’m clearly not an authority on TDD with MVC, so any clarifications on what I’m doing wrong then I’m welcome to advice.

Summary

Don’t get me wrong – I love MVC. It’s bugged me for a long time being stuck using annoying parts of ASP.NET like using only a single form for a page or stupidly long control IDs for things that never needed an ID. It just seems that a lot is lost when you move away from WebForms.

I know that development is in full swing for MVC and I expect for things to only improve at this point. I look forward to the future of MVC since it will no doubt continue to improve.

Written by hugoware

May 25, 2009 at 1:02 am

jLinq And Accepting Parameters

leave a comment »

One of the more complicated parts of jLinq is that any commands, especially query style commands, can accept different number of parameters at any given time. When using the features like command memorizing and field memorizing the function has to assume the values to use.

Another feature that is in development is to make it so that jLinq will accept different types of parameters for commands and then determine the best way to handle them.

For example, the other day I was writing some unit tests for jLinq and entered in the following query…

jLinq.from(data.users)
  .less("first", 5)
  .select();

Okay, all names less than 5 characters, right? Ah… oops…

So that doesn’t work… why is that? Well looking into the code for the ‘less()’ command we find the following.

{name:"greater", count:1, type:"query",
method:function(query, value) {
	return query.when({
		number:function() {
			return (query.value > value);
		},
		string:function() {
			return (query.value.length > value.toString().length);
		},
		array:function() {								
			return (query.value.length > value.length);
		},
		other:function() {
			return (query.value > value);
		}
	});					
}},

So if you notice that command – toString() – you’ll see our problem. Matching against a string field assumes the parameter should be treated as a string. The query is technically evaluating the 5 as a string. Or more specifically, the length of the string…

//the correct way that doesn't work in 2.1.1
record.first.length < 5.toString().length // or 1 (one)
&#91;/sourcecode&#93;

The majority if the time this is going to be correct, but occasionally we run into a query that it doesn't work with.

As of now most of the queries are having a second look to make sure the correct comparison is done. This is being done using a new query helper method named <strong>as()</strong>. This way, if a command expect a number, then it will search for all numeric versions for the value that was passed in.


//checks for the type of value - if it is already a number, then return it
//otherwise, check for a length value
value = query.helper.as(value, {
  number:function(v) { return v; },
  other:function(v) { return v.length; }
});

This way you can focus more on expressing your queries and less concern about what gets passed into it.

Written by hugoware

May 18, 2009 at 5:11 am

jLinq 2.1.1 Released

with 2 comments

A newer version of jLinq is now available – jLinq 2.2.0

jLinq 2.1.1 has been released.

This version makes a fix to a very annoying IE bug that would cause arrays to be sorted reversed from all other browsers.

You most likely will want to update to this version to avoid any problems using jLinq.

Written by hugoware

May 14, 2009 at 3:02 am

Simplify Using Anonymous Types

with 7 comments

New Version Available:Check out this post about the AnonymousType class Remixed!.

When you’re using ASP.NET MVC you pass information from the Controller to the View. Your information is found in the ViewDataDictionary where you can cast the info back into whatever form it originally was. Additionally, you can even specify a model type for the page so that no casting is required to access your information.

It may be a little inconvenient, but it’s not bad. This just means you need to either define the class in advance or limit yourself to simple values.

If you’re writing LINQ queries and creating anonymous types then you’re in a tougher situation. I’ve seen people try and come up with solutions for accessing an anonymous type after its been created, but nothing seemed all that intuitive.

In the next version of C# we’re going to see the new dynamic declaration which will most likely solve this problem. For now, Reflection is about the only way you solve this issue.

On a recent project I got a little tired of trying to manually do this each time. I ended up writing a wrapper class (included at the end of the post). The example below shows how you can use this class AnonymousType.

//Controller
//==================
this.ViewData["details"] = new {
  name = "Jim",
  age = 30
};


//View
//==================
AnonymousType details = new AnonymousType(this.ViewData["details"]);

//access properties
string name = details.Get<string>("name");
int age = details.Get<int>("age");

//supply a default type in case the property doesn't exist
bool fake = details.Get<bool>("someFakeProperty", false);

//Use the properties by name - maps to the argument name
details.Use((string name, int age) => { 
  Console.WriteLine("{0} is {1} years old", name, age);
});

//An wrong property name (wrong type or incorrect case) will cause an error
details.Use((int NAME) => { /* Error! */ });

It’s really just Reflection, but it streamlines using unknown types inside of a View.

Now, if you are thinking “What about methods? or Fields?” then you’re like me. Now, if your second thought was “Well wait, if it has methods then it’s a defined class, we should just cast it instead.”, then you’re much smarter than me. Unfortunately, I spent an hour or so writing ComplexAnonymousType that would call methods (even match correct signatures), access fields, the works… then to realize how much of a wasted effort it was. 🙂

Anyways, try it out if interested. Let me know what you think!

Don’t forget! Reflection is slower than the normal means of accessing properties. While the time spent is negligible in small amounts, if you’re going to be using this code below with a lot of items, it may be wiser to define a class instead.

Source Code

Download AnonymousType.cs

New Version Available:Check out this post about the AnonymousType class Remixed!.

.

Written by hugoware

May 13, 2009 at 11:41 am

Free Bandwidth For All ASP.NET Users

with 6 comments

That’s right, you read it correctly – free bandwidth. With a very short function we’re going to minify our output.

Makes me think of a song, but I don’t want to ruin the rest of the post.

When people render their WebForms and MVC Views, they send their finished HTML back down to the page. The HTML contains all the markup required to run in the browser. Every developer knows all this though (and if not… well…).

Part of the whole grand ASP.NET pipeline is the Response.Filter. A seemingly innocent property with a lot of potential. Enough boasting about this guy, let’s get onto the code and see what it can do.

First, you’re going to need to create a custom stream. I’m hiding all the inherited members because they aren’t going to mean much in this example, but don’t forget that you need them.

With our custom stream, add a hidden property called the UnderlyingStream (honestly call it whatever you want). Lastly, accept a stream in the constructor and assign it to the underlying stream when you instantiate the new stream you’re building.

Lastly, we’re going to override .Write() routine to actually minify our output. A couple simple Regular Expressions and we can chop out most of the whitespace.

public class MinifyFilter : Stream {

//inherited members from Stream class – Don’t forget
//See download for more information
//…

//The real output stream
private Stream _UnderlyingStream;

//Make sure to pass in the current Response.Filter
public MinifyFilter(Stream stream) {
this._UnderlyingStream = stream;
}

//Override our write event
public override void Write(byte[] buffer, int offset, int count) {

//clean out the whitespace characters
string html = Encoding.UTF8.GetString(buffer);
html = Regex.Replace(html, @”\n|\t”, ” “);
html = Regex.Replace(html, @”>\s+<", "><").Trim(); html = Regex.Replace(html, @"\s{2,}", " "); //write the new html byte[] output = Encoding.UTF8.GetBytes(html); this._UnderlyingStream.Write(output, 0, output.Length); } } [/sourcecode] This is a very streamlined version of the code that doesn't take everything into account. You might want to put some special attention into preventing formatting of text in the <pre> tags or <code> tags, but it's a great start. Now using it is as simple as... [sourcecode language='csharp'] //MVC Example: At the start of a controller action public ActionResult Index() { this.Response.Filter = new MinifyFilter(this.Response.Filter); //...rest of the action return this.View();  } //WebForms Example: At the Page_Init protected void Page_Init(object sender, EventArgs e) { this.Response.Filter = new MinifyFilter(this.Response.Filter); //rest of the Page_Init code } [/sourcecode] You could also assign this to a more global event that runs for all requests, but at that point you will need to write code to make sure you don't accidentally minify something like an image or a file (things that can't be compressed by just removing white-spaces). You might wonder how much a little script like this would save. The answer is simple - It depends. Clearly, pages with a lot of white spaces will find a lot more gain. Sometimes it’s 1 or 2 KBs (which will add up over the course of a month). Sometimes though, especially on larger pages, you can see some real savings.

Here are a few popular sites and their savings

GameSpy 94K – (84K minified)

StackOverflow 119K – (102K minified)

Forums.ASP.net 222K – (154K minified)

Keep in mind that this code isn’t bullet-proof, but instead it’s here to get you started. You can continue to tweak the .Write() method to make sure that your code behaves the way you would like.

With all the savings you get from the extra bandwidth make sure you remember to send me a Coke Zero!

Source Code

Download MinifyFilter.cs

.

Written by hugoware

May 9, 2009 at 4:50 am

iTextSharp – Simplify Your HTML to PDF Creation

with 183 comments

Update: A second version that works in .NET 2.0 has been included at the end of this post.

If you’ve ever had to generate PDFs on the fly then you may have run into iTextSharp, which is a port of iText for C#. It isn’t as straight forward as some people might like, but it is certainly a powerful tool once you figure it out.

Normally, if you wanted to take some HTML and turn it into a PDF you would write a lot of extra code to recreate the document in PDF format, but lucky for all of us, iTextSharp also supports HTML. Again, it isn’t exactly straight forward, but to help I wrote a quick wrapper today to help with the process.

HtmlToPdfBuilder allows you to build a PDF using HTML and hides the complexities of working with iTextSharp. You still need iTextSharp to get this project to run, so make sure to include it.

To start, create a new HtmlToPdfBuilder object. As part of the constructor you’ll need to set the document size. It’s actually a Rectangle, but iTextSharp has predefined sizes already available in the PageSize class (constants)

//Page sizes are found in iTextSharp.text.PageSize
HtmlToPdfBuilder builder = new HtmlToPdfBuilder(PageSize.LETTER);

After you have the builder you can add as many pages as you would like using the .AddPage() method. You can also access each of the pages by their index on the builder you create.

HtmlPdfPage first = builder.AddPage();
//also found at builder[0]

HtmlPdfPage second = builder.AddPage();

Once you’ve added your pages you can start adding your HTML with .AppendHtml().

first.AppendHtml("<h1>Hello World</h1>");

//you can also use params for formatting
second.AppendHtml("<h1>{0}</h1><span>{0}</span>", "Hello Second Page", "Another Param");

Next, you’re going to want to apply some styles to your PDF document, you can use a couple methods. First, the .AddStyle() let’s you add a single style to your page. The first parameter is the selector, such as "H1" or ".totals", the second parameter is a single line of CSS such as "color:#F00;font-weight:bold;".

There is also a method called .ImportStylesheet() that accepts an absolute path (not relative) to a stylesheet and adds all of the styles it finds. I was pretty pleased with the method because I was able to do the entire thing with a single Regular Expression.

//add individual styles
builder.AddStyle("H1", "color:#F00");
builder.AddStyle("p", "font-weight:bold;text-decoration:underline;");

//import an entire sheet
builder.ImportStylesheet("c:\\stylesheets\\pdf.css");

It’s worth mentioning that all of my efforts to set heights, widths, paddings and margins didn’t go so well. I’m not sure what the rules are when it comes to that part so be warned.

Finally, you’re ready to save your document. Use the .RenderPdf() method to get the bytes of your PDF.

byte[] file = builder.RenderPdf();
File.WriteAllBytes("c:\\output\\final.pdf", file);

If you’ve worked with iTextSharp before, or you want a little more control over the rendering process, the builder has two events named BeforeRender and AfterRender that give you access to the iTextSharp classes PdfWriter and Document.

Hopefully, this helps simplify working with HTML and PDFs with iTextSharp. Share your thoughts or suggestions!

Source Code

Download HtmlToPdfBuilder.cs

.

Below is a test version for .NET 2.0 – Please let me know if you discover any bugs. Since I am using Visual Studio 2008 I’m not always aware when there is code that won’t work in previous versions.

Download HtmlToPdfBuilder.cs (for .NET 2.0)

Don’t forget, you still need to download iTextSharp and add it as a reference in your project.

Written by hugoware

May 8, 2009 at 3:04 am