Monday, 2 November 2009

Vici MVC – simple .NET implementation

I have been found the ViciMVC project and it caught my interest. What I can observe – it is really simple implementation of the MVC pattern for .NET (ASP.NET).

The key points I should mention about it are:

  • It is very lightweight.
  • It is very similar to Castle MonoRail and ASP.NET MVC.
  • It has its own, HTML based view engine which is based on their own Vici parser. The parser looks really great and allows to run C# code in it. Good work.
  • Unit testing is not bound to the HttpContext (as we all would expect) AND (this is huge for me) allow to render the resulting html so unit tests can just access raw output produced by the action.

The guys just did what they want and how they want. Great work overall.

I just must mention the ViciProject. The tools are great. Simple, lightweight and looks like easy to use.

Saturday, 24 October 2009

Content Management/Publishing System Problems

Reading the Treating user Myopia I remembered one thing I has been thinking about lately: the problems of all Content Management Systems.
Please note that I will be talking about Web Content Publishing which produces (as an end result) a web page represented with HTML.

Since first CMS the bunch of issues started to arise and most of them are related to basic things:

  1. How user should edit the content?
  2. How the content provided by user should be represented as HTML?

Editing user content

The most popular options to edit the content are:
  1. Poor HTML - user can provide HTML as it is.
  2. Plain text - the text is rendered as-as. Similar to 1, but is HTML encoded, so this is really 1-to-1 match of the text.
  3. Plain text with formatting - user edits the plain text according to specific rules, then the text is parsed and renders as HTML.
  4. Rich Editing (WYSIWYG) - is basically user friendly poor HTML. The main difference is that user should not know the HTML itself (with all its pros and cons).
  5. Preprocessed HTML - this is mix of Poor HTML/Rich Editing and Plain text with formatting. The edited content is in format of HTML but reserves special markup to be parsed dynamically. (Think of ASP.NET, JSP or any other dynamic page generated on server, but provided by user)
To give you an idea where each of them is used and its benefits or issues:
  1. Poor HTML - usually used in primitive/simple management systems. But is always (>99%) used as a back-door when options 4 is available. Characteristics:
    1. Very customisable (anything that can be represented with HTML can be done in this mode).
    2. Requires knowledge from the users.
    3. The actual output is 100% corresponds to the edited content.
    4. Easily overused (users can apply fonts/colors/text size etc with no actual need).
    5. Previous point leads to non-maintainable CMS itself as it is technically very hard change common layout with this approach.
    6. No way to enforce web-standards.
    7. No way to enforce common site layout rules.
  2. Plain text. Is actually part of any system (not only CMS). We can see that everywhere where users' input is shown on a page. It anything from Contact Us and Registration form a real CMS. Its characteristics:
    1. Easy to edit.
    2. No customisation points at all. The output will always be plain text.
    3. The actual output will often be different (newlines and space in plain text are in most cases displayed as such, but just ignored by browsers).
    4. Web-standards are automatically enforced.
    5. Common site layout rules are N/A.
  3. Plain text with formatting. Is used in most of Wiki sites. Often called Markdown. The aim is to allow user to edit content in plain text, but reformat it to rich (HTML) content according to the rules of Markdown. Characteristics:
    1. Requires users' knowledge of the markdown.
    2. There are a lot differen mark-ups/downs which increases learning curve for end-users overall.
    3. Really describes the content and NOT how to represent the content.
    4. Has limited customisation. Only set of particular HTML tags can be rendered as a result.
    5. Easy to enforce web-standards.
    6. Easy to enforce common site layout rules.
  4. Rich Editing (WYSIWYG). The aim is to provide users ability to edit content and see how it looks just in place. What You See Is What you get. Used in most of CMS systems, blogs, forums etc where there is a requirement to publish something better than just a plain text. Considered to be the must-have option and is a de-facto standard for content publishing these days. Characteristics (some inherited from Poor HTML):
    1. Very customisable.
    2. Does not requires knowledge from the users (easy to use).
    3. The actual output in most cases is > 90% similar to the edited content (which is pretty good).
    4. Easily overused (users can apply fonts/colors/text size etc with no actual need).
    5. Previous point leads to non-maintainable CMS itself as it is technically very hard change common layout with this approach.
    6. Issues with the editors.
    7. No way to enforce web-standards.
    8. No way to enforce common site layout rules.
    9. Copy-paste from other documents is very buggy.
  5. Preprocessed HTML/MarkDown - this can used in systems that dynamically build online forms or are in some way application builders. The idea is to allow user to provide a content but still make it dynamic. Usually used in pretty complex applications. Typical example I can take from top of my head is DekiWiki. Characteristics:
    1. Requires knowledge of the markup.
    2. Customisation points are limited.
    3. Content is always mixed with dynamic behavior which leads to painful maintainability.
    4. The actual output is often totally different comparing to the original content.
    5. No way to enforce web-standards.
    6. No way to enforce common site layout rules.
Probably, the Rich Editor is the golden middle here. But the things go wrong when people try to copy-paste content (very rich-formatted), let's say, from MS Word. Hardly any WYSIWYG editor can handle that. And the result output will be awful. Forget about web standards....

The point I want to make here is that there is no unique option for all possible solutions. If you create a system for geeks - use mardown, for normal users - use Rich Editor and be prepared to review its content.

But generally, I feel there is a lack of science behind this. We need to analyse this area to provide a good solution for both users and developers, so they can live happy lives and not bother writing posts like the Treating user Myopia.

For any ideas on how to solve this publishing issue I promise beer.

Friday, 16 October 2009

Testing expected exception, revisited

I have been using NUnit for a long time and really got used to it. Nowadays it is very sweet, especially with NUnitEx.

It does have a simple syntax for testing exception. Pretty much what I did long time ago.

It looks like this:

[Test]
public void ThrowsAndGivesMessage() {
    Assert.Throws<FormModelProviderException>(() => new XmlFormModelProvider().CreateModel());
}

BUT, it does not allow me to verify the actual message of the exception. I want to write the code like this to do that:

[Test]
public void ThrowsAndGivesMessage() {
    Action act = () => new XmlFormModelProvider().CreateModel();
    act.Throws<FormModelProviderException>()
        .Message
        .Should().Contain("Form/Form element is not found");
}

The point here is that I verify the exception type thrown AND get the TYPED exception as the result of the verification so I can do whatever I want with it. One more thing I like is that we explicitly see the acting code.

Ohh, yes. The code to support this:

public static TExpected Throws<TExpected>(this Action a) where TExpected : Exception {
    try {
        a.Invoke();
    } catch (TExpected expected) {
        return expected;     
    } catch (Exception other) {
        Assert.Fail(string.Format("Expected exception of type {0} but {1} was raised.", typeof(TExpected).Name, other.GetType().Name));
    }
    Assert.Fail(string.Format("The expected exception {0} has not been raised", typeof(TExpected).Name));
    return null; // This NULL smells - should be refactored :)
}

Enjoy.

Thursday, 8 October 2009

Dividing integers in C# are evil

If you have ever worked with arithmetical operations in C# you probably know this. But it is the thing that can easily be slept from you and not even mentioned.

What do you think the code will print? True or False?

Console.WriteLine(5/2 > 2); // True or False?

The result is, of course, FALSE. You should never forget the TYPE. Integer 5 divided by integer 2 returns INTEGER. And it is truncated integer, so the value will be 2 and not 2.5.

This fact that division operator returns INTEGER in my opinion is just wrong. There is no ANY guarantee at all that result will ever be integer. In other languages (including Pascal/Delphi) the division returns floating-point result. Which IS correct.

So in real live: INT/INT=REAL, in C# INT/INT=INT. Just wrong. No math behind such kind of division.

I have just faced this issue (just totally forgot about INT/INT=INT) trying to calculate an angle between 2 points on the Bitmap. It is simple:

Point p1 = GetIt();
Point p2 = GetIt();
var radians = Math.Atan( (p1.X-p2.X) / (p2.Y-p1.Y) ); // Atan( INT/INT)!!

As we can see the error is unavoidable. We will end up with wrong result.

So you should remember once and forever: Be explicit about type when using division.

And the code snippets should look like this to work correctly:

Console.WriteLine(5.0/2.0 > 2.0); // This  correctly becomes "True"

// casting of one division argument is enough, but better be explicit
Math.Atan( (double)(p1.X-p2.X) / (double)( p2.Y-p1.Y) ); 

// or if casting bothers you:
Math.Atan( (0.0 + p1.X-p2.X) / (0.0 + p2.Y-p1.Y) );

 

Additional note is that ReSharper greatly warns you saying “Possible loss of fraction”. I love it more and more every day.

Friday, 2 October 2009

IT holidays (Official and not)

It turns out there are a lot IT holidays out there. So we can make celebration pretty often :)

Here is the list:

  • International Day without Internet (last Sunday of January). It is intended to have one day with no computer, internet. Just be offline and go and visit your relatives, friends; go to park etc.
  • Day of secure Internet (1st Tuesday of February). The aim is to inform users about security issues in world wide web.
  • Computer geek day (February 14). The day of people in love with computers… If seriously, it is the day when (14 February, 1946) the first electronic digital computer (ENIAC) was launched which actually worked, and even performed calculations (ballistic tables of the U.S. Army). And BTW this is my birthday… What a coincident :)
  • Overclocker day (28 February or 29th on the overclocked year). This seems to be born in Russia in 2004.  Not much to add to this. Every gamer knows what overclkocking is.
  • IT-Professional day (28 February). Invention of network cable. Just another reason to have couple of drinks with colleagues.
  • Day of freedom of speech in Internet (12 March). Initiated by UNESCO as part of “Reporters without Borders” program on 12 March 2008. The aim is to support Internet descendants who might be in prison. Organisers ask to to give your NO to the censure in the Internet.
  • Shutdown Day (24 March). For the first time this holiday was celebrated March 24, 2007. That day a call came to shut down as many computers as possible arround the world. The purpose of is to find out how many people can survive a day without a computer. The authors of this idea are programmers who live in Montreal (Canada), Denis Bystrov (born in Belarus) and Ashutosh Rajekar (born in India).
  • RuNet Birthday (7 April). On the 7th of April 1994  The Internet Corporation for Assigned Names and Numbers (ICANN) had registered the domain .ru for Russia.
  • Cryptographic service day (5 May). The service was organised in Russia in 1921 to empower security of communications within Russia and outside of it.
  • International Day of Information Society (IT-Day, 17 May). UN recognises it as a day of all IT geeks (software devs, admins, Internet providers, web-designers etc) since 2006. The same day, 17 May, but 1865 International Telegraph Union was established in France.
  • Sys Admin day (last Friday of July). This idea came to mind of sys-admin from Chicago (Ted Kekatos). First celebrated on 28 July 2000. BTW, Pope of Rome, the same year, officially called St. Issidor (clarification?) the governor of all computer and internet users.
  • Tester’s day (9 September). This day 1945 in Harvard university a butterfly was found in Mark II Aiken Relay Calculator during the testing. It got the start for this day.
  • Developer’s day (256th days of a year). Professional day of a developer celebrated on the symbolic, 256th day of the year. The idea came from Russian developer Valentin Balt. This day became official in Russia only since 2009, but was celebrated since 2002.
  • Smiley birthday (19 September). On 19 September 1982 professor from Scott E. Fahlman from Carnegie Mellon University first time suggested to use three symbols :-) to be interpreted as a smiling face. Nowadays these symbols are used everywhere.
  • International Day Of Internet (30 September). This holiday was offered to become official several times at different times. However, none of the suggested dates did not become a tradition. As for Russia, at the informal level, the Day of the Internet is September 30. Such an initiative came from the Moscow company, "IT Infoart Stars".
  • International Day of Information (26 November). Initiated my International Academy of Infromatisation. Any person dealing with information in any kind can celebrate this day.
  • International day of information protection (30 November). This holiday is celebrated from November 30, 1988 at the initiative of the American Association of computer equipment. The purpose is to remind everyone of the need to protect computer information, drawing attention of producers and users of hardware and software security problems. It was a in 1988, was recorded first mass epidemic of computer virus. It was a worm, named in honor of its author Morris.
  • Birthday of computer science in Russia (4 December). In August 1948, reporter, member of AN USSR Isaac Brook together with engineer Bashir Rameevym presented the project of automatic computing machines. A Dec. 4, 1948 State Committee of the Council of Ministers introduced the advanced technology and registered this invention under the number 10475, entitled "Digital electronic calculating machine”.

Translated and shortened from here.

Thursday, 1 October 2009

Image.GetBounds always returns value in Pixels

Ok. Looking at the method Image.GetBounds I see:

Return value:

The RectangleF that represents the bounds of the image, in the specified unit.

So far so good. But please notice the signature of the method:

public RectangleF GetBounds(ref GraphicsUnit pageUnit)

We need to pass the unit of measurement BY REFERENCE. I had no idea why.

It turns out this method ALWAYS RETURNS THE VALUE IN PIXELS. Additionally the unit parameter is always set to Pixel instead.

And there is no ANY information about it on the documentation at all. Great. I wasted 2 hours for this.

Again have to patch, fix, extend.

Tuesday, 29 September 2009

ASP.NET MVC Most annoying issues

  • No support for SSL in routing  (no URL generation configured in a single place). One big hack is here.
  • No support for (non)SSL redirect using RedirectToRoute (so it is not possible to redirect to (non)SSL page from controller action, except generating absolute link manually).
  • HttpExeption is handled as any other one except if its Code is 404. Inconsistent. But is “as designed” in ASP.NET generally (FTW again).
  • It reuses interface of the HttpContext class just acting as a proxy (HttpContextBase). Thus it inherits all the issues it has. It had to be different interface that abstracts from HttpContext (in particular the ApplicationPath’s trailing slash issue).
  • No support for Fragment part of URL in routing.
  • Weird ValueProvider – sometimes its value is array, sometimes string. The behaviour is consistent, but not naturally understandable. Have to wrap all that stuff with my own utility to unwrap that.
  • NullReferenceException occurs accessing routes if not properly used.
  • Annoying RenderPartial with model. Has to create a new ViewDataDictionary.
  • Empty values are used instead of NULLs. By default if user leaves a field blank (non-mandatory) empty string is bound to the property. It will be fixed in MVC2.
  • In reality, rarely you can use the typed C# 3.5 syntax for routing MvcContrib fixes that and I did it.
  • The default data binding is NOT secure and it is often encouraged. This also applies to Castle MonoRail. To protect it we need to specify white-list (which leads to another problem) or use ViewModel/DTO (which I do) and thus write more code.
  • The white-list of databinding properties is array of STRINGS. No type sefety. I write my wrapper to convert Expression<Func> to string. Fixing and patching again.

And this is the list I only remember now…

Generally the idea behind ASP.NET MVC is great. Even one of my ideas had been implemented in it.

But the delivered implementation has to be patched and wrapped with your own utils. Only after that it can be used consistently.

I am using ASP.NET MVC for about half a year or so and I still do prefer it instead of WebForms. Probably I just had to choose Castle MonoRail. I have never used it, only looked around, read blogs and looked into code samples, but it seems to be a bit more mature. It probably has less “features” (one is worth noting - routing), but I believe it at least performs consistently everywhere.

I am just so tired of patching, wrapping, extending, fixing all the Microsoft things…

I probably just need to go to holidays for a while to cool down a bit.

I should also mention the most positive tools I used with ASP.NET MVC:

I do encourage you to contribute to NHAMl in any possible way. That is a real thing.


Ohh. And I have a great idea. Let’s rewrite all the tools we find design issues in? Huh?

Are you brave enough to tell that?

…hmm… I am probably not.
Though I want to.