My Ajaxy JavaScript stack

by DotNetNerd 24. January 2010 12:12

I have been working primarily with ASP.NET MVC for a little over a year now, and this has prompted me to do quite a bit more Ajaxy functionality. So while doing this I have been looking at quite a few Ajax/Javascript libraries.

As most other developers I have been swept away by JQuery, which by far is the most important component when I am doing Ajax and manipulating the html DOM - see cheatsheet. Besides making a lot of these things easier, it also provides a wide variety of plugins that enable all sorts of shiny fancy features without much work. One of the very usefull ones that I find myself using on all kinds of projects is tablesorter- that makes clientside table sorting almost free.

Working in the Microsoft domain I have of course also been working with Microsofts ASP.NET Ajax Librarywhich also brings quite a few cool things to the table. Most basically it enriches the javascript experience by providing namespaces, intellisence and a bunch of extentions to the basic javascript type system. On top of that there are a lot of extenders to work with accordions, watermarks, listsearch etc. were most projects will find something that is useful to provide a better UI experience. The latest addition, that I am already very fond of even though it is still just in the beta version is templates. This gives us a easy way to do databinding on the client - one-way/two-way livebindings, and ways to do this both declaratively and imperatively. In other words it provides a rich templating experience and no more clumbsy string manipulation!

Next thing that is important when working with Ajax is having some solid libraries to do JSon serialization. Here I will strongly recommend JSON2for the client because eval is evil. Also a small but important thing to know is that data must be serialized and provided as a string when using JQuery to call a WCF service. On the serverside, I recommend Json.NET or maybe Json for the compact framework if you need something that is easier and more extendable than the .NET build in DataContractSerializer.

Finally something that might also be worth looking at to get better performance is using a content delivery network to reference the different scripting librarys. Here I will recommend looking at either Microsoft Ajax Content Delivery Networkor Google AJAX Libraries. Both seem very reliable and will give what you need, so its mostly a matter of personal preference.

18okt04_ajax_logo_150_rgb

ajax_logo2

Tags: , ,

MVC podcast

by DotNetNerd 7. November 2009 12:24

About one year after I did my first podcast, which was about F#, the second has now been released on ANUG.dk. This time I am talking with Søren about MVC, and I think that in spite of some technical difficulties we managed to do a good episode. It is still strange to hear my own voice recorded, but it is still fun to do and as always I love to get involved. If your interested in hearing what I have to say (in danish) about MVC the episode can be downloaded from ANUG.

 

Tags: ,

ViewData, reflectionbaseret typemapping og performance implikationer

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.

Tags:

JQuery Ajax debugging

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);
    }
});

Tags: ,

xVal - fin løsning på klassisk problemstilling

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.

  1. 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.
  2. 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.

 

Tags:

Authorization i MVC

by DotNetNerd 9. February 2009 15:46

Ud af boksen er MVC frameworket udstyret med en AuthorizeAttribute, således at man kan angive på sine actions at det kun er brugere i bestemte roller der har lov at tilgå den.

[Authorize(Roles="Employee")]

Det i sig selv virker smart nok, men hvor tit har du lavet en løsning hvor authentization ikke er mere komplekst end det?

På mit nuværende projekt løb jeg hurtigt på det problem at en bruger godt må tilgå en action, hvis det id metoden tager som parameter er id’et på hans egen bruger. Altså med andre ord, han/hun må godt se egne data.

Jeg ville stadig helst undgå at skulle skrive kode i starten af mine actions til at undersøge den slags, da det er en af de ting der er oplagt at lave ved hjælp af AOP. Da attributter kun kan tage statiske værdier, var det udelukket at løse det ved at lave min egen FilterAttribute. Efter at have været lidt i tænkeboks fandt jeg frem til at bruge Castle Windsors IInterceptor til at lave validering af actions.

public class AuthorizationInterceptor : IInterceptor
{
    public void Intercept(IInvocation invocation)
    {
        if (invocation.Arguments != null && invocation.Arguments.Length > 0 && invocation.Arguments[0] != null)
        {
            if (invocation.Arguments[0].GetType() == typeof(RequestContext))
            {
                var context = (RequestContext)invocation.Arguments[0];
                var values = context.RouteData.Values;
                var auth = new AuthorizationManager();

                if (!auth.Authorize((string)values["controller"] + "/" + (string) values["action"], (string) values["id"]))
                {
                    throw new UnauthorizedAccessException("You are not authorized for this action");
                }
            }
        }

        invocation.Proceed();
    }
}

Selve det at lave authorization kan nu implementeres i en separat AuthorizationManager klasse, der også kan bruges i forbindelse med f.eks at generere en menu med de punkter, en bruger har ret til at se.

Efter blandt andet at have ladet mig inspirere af authorization via en config-fil fandt jeg frem til at jeg gerne ville samle konfigurationen, men at jeg dog ville undgå en xml-fil, og istedet have mulighed for at lave mere advanceret authentization. Det førte til nedenstående løsning, som jeg er blevet rimeligt godt tilfreds med, da det giver mig en stor grad af fleksibilitet.

public bool Authorize(string controllerAction, string id)
{
    IPrincipal user = HttpContext.Current.User;
    Employee empl = _repo.GetByUserName(user.Identity.Name);
    var employeeId = 0;
    int.TryParse(id, out employeeId);
    var dic = new Dictionary<string, Predicate<Employee>>
                  {
                      {
                          "Employee/Edit", employee => user.IsInRole(Config.Admin) ||
                                                       (user.IsInRole(Config.Employee) &&
                                                       employee.Id == employeeId)
                          },
                  };

    Predicate<Employee> pred;
    return !dic.TryGetValue(controllerAction, out pred) || pred.Invoke(empl);
}

Tags:

Technology overflow

by DotNetNerd 21. January 2009 19:24

Nye frameworks, tools og principper

Starten på det nye år, som samtig har været starten på nyt job for mig, har betydet at det var tid til at lære nogle frameworks at kende som jeg ikke tidligere har brugt professionelt. Det har været rigtigt spændende, men har også fået mit hoved til at eksplodere i forhold til tanken om at skulle blogge om det. Jeg vil derfor skrive lidt om hvad jeg har set på, fordi det nok er en del af de ting bloggen kommer til at omhandle fremadrettet.

Vi er en shop der gør alvor af at arbejde efter agile pricipper så jeg har haft tid til at kigge på ORM, Unit testing, mocking, Dependency Injection, Continuous Integration og Migrations. Dertil kommer Office Interop og ASP.NET MVC, som jeg endelig får mulighed for at bruge professionelt, hvor det ellers har været på todo-listen hjemme siden jeg fik leget med de helt tidlige bits. Og sidste men ikke mindst har jeg kigget op tools til synkronisering og deling af data.

Object relationel mappers

Mere præcist har jeg i forbindelse med ORM's kigget på NHibernate, Fluent NHibernate og LINQ to NHibernate, samtidig med at jeg har en bog på vej om LINQ to entities. Jeg håber LINQ to Entities udvikler sig til et reelt alternativ til NHibernate, som jeg lige knap synes det er idag. Hovedanklagen idag er at det ikke giver persistence ignorence, hvilket er et stort minus i forhold til at få et pænt løst koblet design. Det er dog et issue Microsoft er klar over, og noget de arbejder på til vNext. Et andet issue der arbejdes på som er væsentligt er iøvrigt model drevet design, hvor LINQ to Entities idag er meget datadriven.

Continuous Integration

Opsætning af et continuous integration miljø, som skal baseres på Team Foundation Server er en anden ting jeg er ved at se på. Umiddelbart virker det nemt at komme igang med, men udarbejdning af build scrips skal nok blive interessant at se på. En overvejelse er blandt andet om man skal holde sig til at bruge MS Build Server eller om NAnt viser sig at være den rigtige vej at gå?

Migrations

Migrator.NET har været rimeligt nemt at komme igang med, bortset fra at dokumentationen er rimeligt tynd, så selve konfigurationen skulle det lige pilles lidt ved for at få det til at spille.

Data synkronisering og deling af data

Idet jeg er begyndt at pendle er synkronisering af data imellem min desk- og laptop også blevet et super relevant emne, hvilket fik mig til at afprøve synctoy, live sync, mesh, skydrive samt servicen delicious. Mesh har jeg forelsket mig lidt i, selvom jeg må erkende at stabiliteten ikke er god nok endnu i beta versionen, samtidig med at de 5 GB plads man får idag er lidt tyndt når man på et skydrive får 25 GB.

Who am I?

My name is Christian Holm Diget, and I work as an independent consultant, in Denmark, where I write code, give advice on architecture and help with training. On the side I get to do a bit of speaking and help with miscellaneous community events.

Some of my primary focus areas are code quality, programming languages and using new technologies to provide value.

Microsoft Certified Professional Developer

Microsoft Most Valuable Professional

Month List

bedava tv izle