Saturday, January 24, 2009

Cum sa faci un control serverside care sa faca postback!

Aveam nevoie la un moment dat de un control serverside care sa faca potback. Dupa cateva cautari pe net am gasit ceva care arata de genu:
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>

Nu sunt 100% sigur de implementarea asta, dar pentru o implementare rapida e bine sa tin minte.

Saturday, December 6, 2008

Validare client side pentru Date/Time in ASP.NET

De ce sa folosesti un algoritm de validare pentru un DateTime cand poti folosi ASP.NET Ajax care are acest algoritm, si probabil mai bun decat primul algoritm care il poti gasi pe 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;
}
}
Trebuie sa dai variabilei Sys.CultureInfo.CurrentCulture.dateTimeFormat.ShortDatePattern valoarea corecta inainte sa fie facuta validarea.

Ceva de genul:
if(Sys) {
Sys.CultureInfo.CurrentCulture.dateTimeFormat.ShortDatePattern =
'<%= System.Globalization.CultureInfo.CurrentCulture
.DateTimeFormat.ShortDatePattern %>'
;
}
Pentru a face acest lucru am fost nevoit sa folosesc ScriptManager care incarca librariile ASP.NET Ajax. In acest fel poti valida perfect chiar si data de 28 februarie.

Tuesday, November 11, 2008

Incercam sa ma invinovatesc...

Imi incercam noua componenta web (server side). Totul mergea exact cum planuisem pana cand am aruncat o privire in designer.
Deoarece ma interesa partea functionala mai mult nu ma ingrijoram asa tare de modul in care arata la design time, si surprinzator afisa o eroare de genul:

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


Primul gand care mi-a trecut prin cap a fost "Am gresit!". Dar unde?
Dupa ce am cautat putin pe google am gasit niste baieti care discutau pe aceeasi problema. Problema lor s-a oprit la EnsureChildControls(). A mea nu.

Cautand in continuare pentru mai multe informatii am descoperit ca nu eu gresisem defapt. Defapt gasisem un bug in Visual Studio. Bug-ul a fost semnalat aici la Microsoft.

Sunday, October 5, 2008

Programand ASP.NET cu Notepad.exe

Prima mea experienta cu aplicatiile web a fost cu pagini JSP, si prima mea aplicatie a fost, bineinteles, clasica ""Hello World" si arata asa:
<%@ page contentType="text/html;charset=WINDOWS-1252"%>
<HTML>
<BODY>
<%="Hello World"%>
</BODY>
</HTML>
Aceasta aplicatie o scrisesem in Notepad si am facut deploy la ea pe un server Apache Tomcat Server. Acest lucru, pentru mine, insemna ca nu ai nevoie de un compilator pentru a edezvolta o aplicatie simpla si dinamica. Ceea ce era ceva cool

Astazi faceam deploy la o aplicatie ASP.NET si am observat ca toate fisierele ASPX contineau doar textul:

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

si ma intrebam.... “Poti programa aplicatii ASP.NET fara Visual Studio, folosind orice editor de text si facandu-i deploy manual fara nici o compilare?”.

Deci am incercat.
Am creat un folder.
Am mapat folder-ul pe serverul IIS.
Am creat un fisier aspx nou ce continea:
<%@ Page %>
<HTML>
<BODY>
<%="Hello World!"%>
</BODY>
</HTML>
An descis browser-ul si am navidat la adresa http://localhost/MyFolder/Default.aspx . In browser am obtinut mesajul Hello World!.
Pentru a face totusi aceasta pagina putin mai complicata am modificat pagina Default.aspx pentru a face ceva dinamic, ceva ca un calcul. Cred ca 1 + 1 e destul:
<%@ Page %>
<HTML>
<BODY>
<%="1+1=" + (1+1).ToString()%>
</BODY>
</HTML>
si rezultatul fiind evident 1+1=3 :).

Deci daca cineva se incumeta sa dezvolte aplicatii ASP.NET poate folosi doar Notepad-ul si un server IIS.

... dar totusi te afli in .net, nu in Java unde limbajul de default (si singurul) este Java. Care limbaj este libajul implicit pentru acesta pagina simpla? Cea mai rapida metoda pentru a afla: scriu repde ceva in c# si vad ce afiseaza.

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

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

Uitandu-ma in Detailed Compiler Output, am vazut cine este compilatorul de default al aplicatiilor asp.net "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\vbc.exe" (visual basic compiler).
Adaugand atributul language la directiva page si indicand limbajul corect folosit in pagina totul va compila OK.

Decorarea return-ului!

Atunci cand am descoperit .net-ul am descoperit si atributele, si din cauza ca eu sunt inclinat spre paretea practica a lucrurilor (si mai putin cele teoretice) nu mi-a atras atentia niciodata ca poti folosi atributele si la decorarea unei valori intoarse de o metoda. Intr-o zi am dat peste enum-ul AttributeTargets si dupa ce am vazut valoarea ReturnValue mi-am dat seama ca nu stiu cum se poate decora asa ceva. Dupa ce am cautat putin pe Google un exemplu am gasit ceva de genul asta:
[MethodAtr(Params...)]
[return: ReturnAtr(Params...)]
public SomeType MyMethod(
[ParamAtr(Params...)]
SomeOtherType myParam)
{
return someValue;
}
Unde [return: ReturnAtr(Params...)] este modul in care decorezi o valoare de return.

ASP.NET Dynamic Data si alte ORM-uri

Cautand daca cu ASP.NET Dynamic Data se pot folosi si alte ORM-uri inafara de EF (Entity Framework) si LINQ to SQL, am dat peste metoda ValidDataContextType din clasa System.Web.DynamicData.ModelProviders.SchemaCreator. Corpul metodei arata asa si cred ca spune totul despre extensibilitatea spre alte ORM-uri:
public virtual bool ValidDataContextType(Type contextType){
if (!IsDataContext(contextType)){
return IsObjectContext(contextType);
}
return true;
}
Singurile DataContext-uri valide sunt System.Data.Linq.DataContext sau System.Data.Objects.ObjectContext. Deci daca vrei sa extinzi ASP.NET Dynameic Data poti face asta doar prin implementarea unui provider de LINQ2 sau EF. Aici, Frans Bouma ofera mai multe informatii referitoare la aceasta problema.