by DotNetNerd
25. March 2009 08:53
Jeg løb for nylig ind i at SQL Server 2008 management studio smed en exception da jeg prøvede at ændre et tabel design "Saving changes is not permitted. The changes require the following tables to be dropped and recreated..."
Først troede jeg det var NHibernate der havde låst tabellen, da den var genereret af NHibernate, men efter lidt søgning fandt jeg ud af at det var Microsoft der går hårdt efter titlen "dumbest feature of the year". Af en eller anden grund synes de som standard at det ikke skal være muligt at lave designændringer der kræver at tabellen droppes i 2008 udgaven af SQL manager.
Idag løb en kollega så ind i samme problem, og dermed slog det mig at det nok var værd lige kort at skrive om her på bloggen, hvordan man slår det fra. Det er så enkelt som at gå ind under tools -> options og slå et flueben fra under punktet designers som det kan ses her:
by DotNetNerd
22. March 2009 13:17
Et sted jeg ofte oplever friktion imellem practices og frameworks er imellem godt objektorienteret design og webudviklings frameworks. Veldesignede objekter er sjældent specielt velegnede til f.eks databinding og serialisering. Eksempelvis kaster serialiseringsprocessen i MVC frameworket en exception, hvis man forsøger at serialisere et objekt der er del af en mange til mange relation (hvor to klasser har collections indeholdende instancer af hinandens typer). Det giver fint mening at det forholder sig sådan i en serialiseringskontekst, men omvendt kan man ikke i sit design undvære mange-til-mange relationer. I forhold til databinding kan det være et issue at man gerne vil databinde et objekt hvor nogle properties er komplekse typer, hvorfra der skal noget logik til at afgøre hvilken værdi der skal representere objektet i brugerfladen.
Løsningen på den slags udfordringer er ofte at lave en ViewData klasse der som udgangspunkt er et subset af den oprindelige klasse. Properties som er mere komplekse kan så fjernes eller ændres, og udregnede eller relaterede data kan tilføjes viewet. Som bekendt er der ingen designbeslutninger uden konsekvenser, og her er den tydelige konsekvens at man nu skal skrive kode til at mappe imellem entiteter og viewdata. I mange tilfælde er det virkelig trivielt, da properties navngives ens, så for at undgå at skulle gøre dette manuelt skrev jeg en MapToView metode.
public static ViewType MapToView<EntityType, ViewType>(EntityType entity) where ViewType : new()
{
var view = new ViewType();
var entityType = entity.GetType();
var viewType = view.GetType();
foreach(var property in entityType.GetProperties())
{
var viewProp = viewType.GetProperty(property.Name);
if(viewProp != null && viewProp.PropertyType == property.PropertyType)
{
viewProp.SetValue(view, property.GetValue(entity, null), null);
}
}
return view;
}
Den er naturligvis reflection baseret, og så siger ens barnelærdom jo at man skal passe på hvad det betyder for performance. En helt kort test hvor jeg har to klasser med 10 string properties som jeg mapper 1000 gange viste over 5 observationer at det tager ca. 53 gange så lang tid med MapToView frem for med manuel mapning. Det skal dog ses i det lys at vi snakker omkring 145 millisekunder på en 3,2 GHz Pentium 4 for de 1000 mapninger - så med mindre der virkelig er skarpe designkrav omkring performance vil det næppe være et issue.
by DotNetNerd
19. March 2009 15:42
Idag løb jeg ind i en lille gotcha forbindelse med brug af JQuerys getJSON til at sende brugerinput til en MVC controller action. Problemet var at karaktererne æøå blev encoded i forbndelse med kaldet.
Efter uden held at have roddet med at ændre hvilken encoding JQuery bruger fik jeg et tip fra min kollega Morten Bock om at det kunne være fordi det (naturligvis) sendes via http get og dermed skulle urlencodes. Doh! Derfra tog det så ikke lang tid at finde ud af at der i javascript findes en escape funktion der gør netop det - og så var det blot at decode ved hjælp af Server.UrlDecode på serveren.
Anyhow, håber hermed min erfaring kan være til nytte for andre der løber ind i samme problem.
by DotNetNerd
9. March 2009 20:36
Jeg løb fornylig ind i at jeg ville lave et ajax kald ved hjælp af JQuery og $.getJSON, men min action blev aldrig ramt og der blev ikke kastet nogen exceptions. Det viser sig at skyldes at getJSON forsøger at lave kaldet, men hvis det fejler ignorerer den det blot. Løsningen er at for at kunne debugge skal man istedet bruge $.ajax, som gør det muligt at registrere en errorhandler. Herfra kan man så tilgå det response der returneres, og hvis man udskriver det til siden får man en overraskende god fejlside, der gør det nemt at debugge.
Det var ikke et trick jeg fandt beskrevet nogen steder, så jeg synes det var værd at dele - og så er det ellers en af den slags posts jeg tror jeg selv bliver glad for næste gang jeg skal bruge den her lille snippet :-)
$.ajax(
{
type: "GET",
url: "/Controller/Action",
data: { registrationTypeId: selectedValue },
dataType: "json",
error: function(xhr, status, error) {
document.write(xhr.responseText);
}, success: function(json) {
alert("Data Returned: " + json);
}
});
by DotNetNerd
3. March 2009 17:11
Noget så basalt som validering der på overfladen virker som en simpel ting har alligvel en tendens til at ende med at ende med at blive uskønt i webløsninger. Der er to problemer jeg tit har set når jeg har kigget både mine egne og andres projekter igennem.
-
Man bør implementere sin validering både client- og serverside. Dette fører til at man bryder DRY princippet, og laver valideringen dobbelt i henholdsvis javascript og ens eget CLR language of choise.
-
Om noget er validt er i høj grad afhængig af kontekst - se who knew domain validation was so hard .
Især punkt 1 er tit en tjørn i øjet på webudviklere, da de færreste synes det er sjovt at lave validering. Ligefrem at skulle gøre det samme to gange kan derfor være en pain - især når det så senere skal vedligeholdes.
Her kommer xVal til undsætning hvis man arbejder med ASP.NET MVC, da det gør det muligt at udtrykke sin validering ved hjælp af attributter man angiver på properties på sine entiteter. Samtidig gør det at man får flyttet sin validering ned i modellen, hvor man gerne vil have den. Jeg vil undlade at komme med eksempler, da Steve Sanderson allerede har lavet nogle gode eksempler på sin blog. En stor bonus ved frameworket der fortjener at blive nævnt er at det er meget fleksibelt, både i forhold til valg af framework til clientside validering, og når man ønsker at implementere sine egne custom valideringer.
I forhold til punkt 2 bryder xVal umiddelbart med princippet om ikke at ligge valideringen på sine entiteter. Jeg vil imidlertid spille gråzone kortet, idet selve det at foretage valideringen er noget man styrer server- og clientside. Det er dermed helt muligt at lave andre typer af validering også, og anvende xVal specifikt til at validere brugerinput fra formularer.