Friday, May 15, 2009

Centering Box Elements in HTML with CSS

Most of my carreer I have been a "backend" guy, working on the database, and building services for consumption by other systems. Over the last couple of years I have had the pleasure of becoming a "frontend" guy, working on various web sites.

So far the site I have been working on only targets IE, As such there hasn't been a strong motiviation to add support for Firefox; however, with IE8 being much more standards compliant, I have a personal desire to get the site to a point where I can turn off IE7 Compatability Mode.

Today I was a little stumped when I was working on markup simillar to the following:


    <div style="text-align: center">

        <table>

            <tr>

                <td>

                    I am Centered

                </td>

            </tr>

        </table>

    </div>



In IE8 with Compatability mode this renders as I expect. The table is centered within the div; however, in Firefox and IE8 standard mode the table is left aligned.

I've always questioned why am I using text-align to align elements, but it always worked so I just shrugged and moved on. Turns out IE wasn't honoring that text-align should only align text. It was using to align all elements. The proper way to do this is:


    <div>  

        <table style="margin-left:auto;margin-right:auto">

            <tr>

                <td>

                    I am Centered

                </td>

            </tr>

        </table>

    </div>




This is so much better. I hated having to use text-align center, and then go through and set all the text up so it would align back left. I have tested this in Firefox 3.0.7 and IE8 (IE7 and Standards Mode). It feels to good finally learn the right way to do something.

Tuesday, May 5, 2009

Dynamic Expression

Scott Gu has a good article about a great sample component called Dynamic Linq. This is a very powerful addition to your linq toolkit which lets you create expressions based on strings. So imagine that you want to add sorting to a grid which is bound to a List. One way would be to have a switch statement for each options (Yes you can throw up I'll wait).

Another way would be to use the dynamic query library. I've always wondered how difficult it would be to create an Expression dynamically. This would be a nice addition to my Audit Logger allowing for the configuration of an audit category to exist outside of the code.

Much of this code came from this stackoverflow.com article. I simply went and added the glue:


        public static IEnumerable<T> Sort<T>(this IEnumerable<T> source,

            string sortExpression, bool desc)

        {

            var param = Expression.Parameter(typeof(T), string.Empty);

 

            var fields = sortExpression.Split('.');

            Expression property = null;

            Expression parentParam = param;

            foreach (var field in fields)

            {

                property = Expression.Property(parentParam, field);

                parentParam = property;

 

            }

 

            var sortLambda = Expression.Lambda<Func<T, object>>(

                Expression.Convert(property, typeof(object)),

                param);

 

            if (desc)

            {

                return source.AsQueryable<T>().OrderByDescending<T, object>(sortLambda);

            }

 

            return source.AsQueryable<T>().OrderBy<T, object>(sortLambda);

        }



Basically this will give you an expression which returns the value of a property. It will support property / field invocation so myObject.MyField.MyProperty. It works by creating an expression which represents the type of parameter being pased in to the lambda.

Then it builds an expression tree by chaining new expressions together for each token myObject, myField etc. Finally it creates a lambda which can be executed.

Wednesday, April 29, 2009

MVC For IDE's

Recently I had the pleasure of helping out a former employer of mine resolve a couple minor issues that have come up since my departure. During this time I had a revelation about how we treat our source code today, and how we should treat it tomorrow.

When I worked for this company I became the sole developer, and was able to define my own coding standards. Overtime all of the source files were updated, as I made changes to them, and was able to use Reformat Document tool in Visual Studio.

Since I have left, a new developer has taken ownership of all the projects I was working on. Said developer prefers a different style to their code. For example. I prefer all braces to start on a new line where as he prefers all opening braces to exist on the parent line.

What does this have to do with how we treat source code? Well imagine this scenario. I open up a large class file, and remove a single using statement from the top of the file. Upon saving the file, visual studio applies my formatting rules which I defined. This results in my one line change to cascade into hundreds of changes.

The question I pose then is why do our tools treat non-significant characters such as extra white space as significant when comparing two versions of the code? Shouldn't our development tools store the source code in as compact a format as possible and allow us to define our own personal views of the source code? Two developers on the same team should be able to read the same source code formatted how they like to see it.

Perhaps Visual Studio should be written as a MVC, and allow us to define our own views seperate from the source code.

Writting this reminded me of when I worked on VB6 applications and one developer would check out a file and the casing of all the variables would change. What a nightmare. Again the source code should be treated as data rendered into a view by the IDE.

Tuesday, April 28, 2009

Rendering to Xml with ASP.Net MVC

 

Warning: This is my first post using Windows Live Writer so if things don’t come out right I apologize.

I have been working lately on using the ASP.Net MVC platform as a rest based endpoint. My current consumer is looking for xml documents of our model; however, in the future I’d love to move our web site over as well. I have been playing around with a couple of different ways to render xml content from a view.

I have seen some approaches on the web which use an automatic serialization mechanism to convert your model into xml or json. I feel that this should not be done automatically but you should be able to customize the rendering however way you need. This has led me to try out three different options to date.

Option 1 Serializing a DTO

The first approach I tried was to take my DTO and get into Xml the quickest easiest way possible. The XmlSerializer. This broke down a little bit when I discovered I actually needed two DTO’s. This method I used a helper method in a code behind file. So my view looks like:

<%@ Page Language="C#" Inherits="MyViewToXml" CodeBehind="MyViewToXml.aspx.cs"  %> 
<%this.RenderToXml(); %>




Now if we look at RenderToXml we can see the magic here:




Response.ContentType = "text/xml";
Response.Write("<MyRoot>");

var dcs = new DataContractSerializer(typeof(List<DTO1>));
dcs.WriteObject(Response.OutputStream, this.Model);

var dcs2 = new DataContractSerializer(typeof(IList<DTO2>));
IList<DTO2> bfs = (IList<DTO2r>)this.ViewData["DTO2"];

dcs2.WriteObject(Response.OutputStream, bfs);

Response.Write("</MyRoot>");



I like this approach in that it was quick easy, and gave me full control, but it doesn’t sit well with me. It feels like I am grinding against the purpose of having a view. So let’s look at option 2.



Option 2 Embracing MVC View



My next shot was to serialize a much more complex object. In my actual case I don’t have a DTO defined, and I need to have even more control over the Xml being generated. Serialization by the framework won’t cut it, and I wasn’t go back 10 years to the days of having build xml via strings or even via a DOM. So what does that leave me with?




<Order Id="<%=this.Model.Id%>"  Number="<%=this.Model.Number%>">

<Customer Company="<%=this.Model.CompanyName %>">
<Address Line1="<%=this.Model.Address.Line%>"
City="<%=this.Model.Address.City %>"
State="<%=this.Model.Address.State %>"/>
</Customer>

<ShipTo Name="<%=this.Model.Location.Name %>">
<%if (!this.Model.ShipTo.Equals(this.Model.Contact.Address))
{ %>
<Address City="<%=this.Model.ShipTo.City %>"
State="<%=this.Model.ShipTo.State %>" />
<%} %>
</ShipTo>

<Items GrandTotal="<%=this.Model.CalculateGrandTotal()%>"
IsOverride
="<%=this.Model.IsGrandTotalOverridden %>">
<%foreach(var item in this.Model.Items) {%>
<Item Name="<%=item.Name%>" Total="<%=item.Total%>" />
<%} %>
</Items>
<Order>



Here we are embracing the view and generating our xml just as if we were rendering an Xhtml view of the domain. This is neat; however, it is a little verbose so I started to question what else is out there.



Option 3 Finding Alternate View Engines



Asp.Net MVC is very extensible. If you don’t like the view engine go find a new one or write your own. I ran across a port of HAML called NHAML. This can simplify the syntax to look at; however, NHAML’s tooling is not there. If you want intellisense or color highlighting, its just not there.



Further more it treats white space as significant characters. For example to nest elements you would need to do:




%Order
  %Customer
    %Address


Child elements are indented by two spaces. While this frees you from worrying about closing all your tags, its a little counterintuitive. There are other view engines out there, which I am looking forward to running through their paces.

Thursday, April 2, 2009

Setting up SSRS on server with multiple sites

I had to set up SSRS on a server today, which has about six or seven different sites. I went through and configured SSRS, bound the virtual directories to a free IP address, fired up the browser and kaboom!



Firing up google was very frustrating as all the solutions I was finding told me to check permissions. The issue here is most likely due to SSRS defaulting to using http://localhost to access the web services. (If anyone from Microsoft or knows whose responsible for this piece of code it'd be great to give a little bit more detail). How do you tell SSRS to use a different server?

There is a config file in %SQL Install Folder%\MSSQL.*\Reporting Services\ReportManager\RSWebApplication.config.. In side this file you will see some xml which looks like

<ui>
   <reportserverurl></reportserverurl>
   <reportservervirtualdirectory>ReportServer</reportservervirtualdirectory>
   <reportbuildertrustlevel>FullTrust</reportbuildertrustlevel>
</ui>

Perfect right so I enter in the URL for my site, fire up the report manager and....kaboom! This time the site doesn't even load and we get the following error from our log files:

w3wp!diagnostic!6!4/2/2009-12:03:16:: Error loading configuration file: The configuration file contains an element that is not valid. The ReportServerUrl element is not a configuration file

This is a horrible error message and doesn't really indicate what the issue. Turns out that you can have either ReportServerUrl or ReportServerVirtualDirectory. Enter the fully qualified URL for ReportServerUrl and remove the ReportServerVirtualDirectory node. Now we fire up the ReportManager in your favorite web browser...and...it works!

I could have saved many many hours and advil, had the developers done proper error handling. Ahh well hopefully you find this article before you've wasted to many hours.