Friday, December 5, 2008

How to create a server side control with events in ASP.NET

I needed to write a custom control for a site that does post backs. After searching the internet i found something that looks like this:
namespace My.Namespace
{
public class CustomEventArgs: EventArgs
{
public string SomeValue { get; set; }
}

public class MyServerControl : Control
{
public event
EventHandler<CustomEventArgs> CustomClick;
private void DoCustomClick(CustomEventArgs arg)
{
if (CustomClick != null)
{
CustomClick(this, arg);
}
}

protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if (this.Page != null)
{
this.Page.ClientScript
.GetPostBackClientHyperlink(this, "");
if (this.Page.IsPostBack)
{
if (this.Page.Request.Form["__EVENTTARGET"]
== this.UniqueID)
{
CustomEventArgs args = new CustomEventArgs();
args.SomeValue =
this.Page.Request.Form["__EVENTARGUMENT"];
DoCustomClick(args);
}
}
}
}

protected override void Render(HtmlTextWriter writer)
{
writer.AddAttribute(HtmlTextWriterAttribute.Href,
"javascript:__doPostBack('"
+ this.UniqueID + "', 'SomeValue');");
writer.RenderBeginTag(HtmlTextWriterTag.A);
writer.Write("Click here to do a postbak event with args!!!");
writer.RenderEndTag();
}
}
}
<%@ Page Language="C#" AutoEventWireup="true" %>
<%@ Register Assembly="MyServerControl"
Namespace="My.Namespace" TagPrefix="MyTag" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Test Page</title>
<script runat="server">
protected void MyServerControl1_CustomClick(
object sender, CustomEventArgs e)
{
Response.Write(e.SomeValue);
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<MyTag:MyServerControl ID="MyServerControl1" runat="server"
OnCustomClick="MyServerControl1_CustomClick" />
</div>
</form>
</body>
</html>

I`m not 100% sure that this is the way but for a quick implementation I think is ok to remember this.

Date/Time Client side validation in ASP.NET

Why use a DateTime validation algorithm when you can use the ASP.NET Ajax that has that algorithm, and maybe better then the first one you find on the internet.

function DateTimeClientSideValidationHandler(source, argument) {
argument.IsValid = true;
if (Sys) {
argument.IsValid = false;
var shortDatePattern = Sys.CultureInfo
.CurrentCulture.dateTimeFormat.ShortDatePattern;
var d = Date.parseLocale(argument.Value, shortDatePattern);
argument.IsValid = d != null;
}
}
You have to give to the Sys.CultureInfo.CurrentCulture.dateTimeFormat.ShortDatePattern the right value befor the validation handler is called.

Something like this:

if(Sys) {
Sys.CultureInfo.CurrentCulture.dateTimeFormat.ShortDatePattern =
'<%= System.Globalization.CultureInfo.CurrentCulture
.DateTimeFormat.ShortDatePattern %>'
;
}
To do this I had to use ScriptManager that loads the ASP.NET Ajax libraries. In this way you can validate even the february 29th dates perfectly.

Tuesday, November 11, 2008

Trying to blame me...

I was trying out my new developed server side web control. Everything worked exactly as planned until i took a look at the designer.
Because i was interested by the functionality i wasn't too worried about it's displaying in design time, but surprisingly it was displaying an error like:

Error creating control - MyControl
'MyCssClass' could not be set on property 'CssClass'


The first thing that crossed my mind was "I made a mistake!". But where?
After googling on internet, i found some fellows that were talking about the same issue. Their problem stopped at EnsureChildControls(). My problem didn't.

Looking for more information about this, i found that it wasn't my mistake. I found a bug in visual studio. The bug was reported here to Microsoft.

Friday, October 3, 2008

Programming ASP.NET with Notepad.exe

My first experience with web applications was with JSP pages, and my first application was like this:
<%@ page contentType="text/html;charset=WINDOWS-1252"%>
<HTML>
<BODY>
<%="Hello World"%>
</BODY>
</HTML>
This application was written in Notepad and deployed on the Apache Tomcat Server. That meant, at least for me, you don't need a compiler do develop something simple and dynamic. That was something cool.

Today I was deploying an ASP.NET Application and noticed that all the ASPX files have only this text:

This is a marker file generated by the precompilation tool, and should not be deleted!

and I was wondering.... “Can you program an ASP.NET Application without Visual Studio, using any text editor and deploy it manually without any compilation?”.

So I tried.
I created a new folder.
I mapped the folder on the IIS server.
I created a new aspx file in that folder with the content:
<%@ Page %>
<HTML>
<BODY>
<%="Hello World!"%>
</BODY>
</HTML>
I opened the web browser and browsed the http://localhost/MyFolder/Default.aspx and I got the Hello World! message.
To make it a little more complicated a modified the Default.aspx page to do something dynamic, something like a calculation. I think 1 + 1 will do:
<%@ Page %>
<HTML>
<BODY>
<%="1+1=" + (1+1).ToString()%>
</BODY>
</HTML>
and the obvious result displayed was 1+1=3 :).

So you are able to write ASP.NET applications using only the Notepad and an IIS server.

... but you are in .net, not in Java where the default language (and the only one) is Java. Witch language is the default for this simple page? The fastest way I could find out is to write something in c# language and see the result.

The new Default.aspx
<%@ Page %>
<HTML>
<BODY>
<% for(int i=0 ; i<5 ; i++) { } %>
</BODY>
</HTML>
The result:

Compiler Error Message: BC30084: 'For' must end with a matching 'Next'.

Looking in the Detailed Compiler Output, I saw that the default compiler for the asp.net applications is C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\vbc.exe (visual basic compiler).
Adding the language attribute to the page directive and pointing correctly to the language you use it compiles OK.

Wednesday, October 1, 2008

Decorating the return!

When I discovered the .Net there ware some attributes, and because I have a little more practical tendencies (less theoretical ones) it never caught my attention that I can use an attribute on a return value of a method. Looking one day at the AttributeTargets enum and seeing the ReturnValue value I realize that I didn’t knew how you can decorate a return value. After I searched on Google an example of it, this is what o found:
[MethodAtr(Params...)]
[return: ReturnAtr(Params...)]
public SomeType MyMethod(
[ParamAtr(Params...)]
SomeOtherType myParam)
{
return someValue;
}
Where [return: ReturnAtr(Params...)] is the way of decorating a return value.

ASP.NET Dynamic Data and other ORMs

Searching to see if I could use with the ASP.NET Dynamic Data some other ORMs besides the EF and LINQ to SQL, I stepped on ValidDataContextType method from the System.Web.DynamicData.ModelProviders.SchemaCreator. The method body looks like this and I think it provides enough information about the extending to other ORMs:
public virtual bool ValidDataContextType(Type contextType){
if (!IsDataContext(contextType)){
return IsObjectContext(contextType);
}
return true;
}
The only valid DataContexts are System.Data.Linq.DataContext or System.Data.Objects.ObjectContext. So if you want to extend the ASP.NET Dynameic Data you can do this by implementing a LINQ2 or EF provider to some database. Here, Frans Bouma gives more references aboute this issue.