Avatar billede idiotbarn Nybegynder
26. april 2011 - 23:30 Der er 7 kommentarer og
1 løsning

3-layer architecture og bruger input validering

Hej
Jeg er ved at lave en ajax baseret web løsning og har givet mig i kast med en 3-lags arkitektur (alle i samme klasse), men mangler nogen tanker omkring min opsætning, så jeg håber i vil gi lidt input. Mit hovedproblem er at jeg ikke 100% kan finde ud af hvordan jeg bør gøre med min validering. Lige nu har jeg alt valideringen liggende i mit BA layer som kaster en exception hvis der er noget galt. Jeg har lavet min egen UserFriendlyException forbeholdt til fejl i inputs, som kan serialiseres så den kan bruges i javascript. Koden skal hovedsageligt bruges som async web app, men en lille chance for at den skal implementeres med winforms:


--- ClassLib ---
class Person
{
  //Business object
  public string name...
  public int age...
  ...
  public void Save()
  {
    PersonBAL.Save(this)
  }
}
class PersonBAL
{
  //Validation o.s.v
  public static void Save(Person person)
  {
    //Forskellig validering inden den sendes til database
  List<Errors> errors = new List...()
  if(person.Name == "")
    errors.Add(new Error("Person.Name", "RequiredField", "Feltet skal udfyldes"));
  if(person.Age<0) // (lidt tænkt måske)
    errors.Add(new Error("Person.Age","InvalidValue", "Alderen skal være større end 0"));
  if(errors.count>0)
    throw new UserFriendLyException(errors); //denne fanges af onFail herunder og indeholder nu fejlbeskederne
  PersonDAL.Save(person); //indsætter i databasen
  }
}

På denne måde kan jeg via javascript/ajax kalde min webservice

--- Præsentationslag ---
AddPerson.aspx:
  function add()
  {
    var name = ...
    var age = ...
    PersonWebservice.AddPerson(name, age,..., onSuccess, onFail)
  }
  function onSuccess(...){ ... }
  function onFail(error, method, context)
  {
    if(error.get_exceptiontype() == 'UserFriendlyException')
    {
        var errors = JSON.parse(error.Errors);
        //brug dataen fra classlib Error Klassen til at markere
        //felter der indeholder fejl og vise fejlbeskeden
    }
    else
    {
      //Exceptionen kom fra en alvorlig fejl og skal behandles anderledes
    }
  }

Hvad jeg ikke kan li ved denne metode er egentligt den ene ting at jeg altid har lært at exceptions IKKE skal bruges til at styre kode hvis andet er muligt. Jeg kunne lige så godt have indført alm. check og retuneret error objekterne gennem webservicen

Hvad jeg godt kan li ved denne metode:
- Koden er nem at læse
- Alt validering er samlet ét sted hvor det ikke kan omgåes
- Da error-teksten sættes i Error objektet har jeg mulighed for at bruge sprogversionering o.s.v gennem .net (i det her tilfælde)
- Javascript'en fanger det som en fejl (onFail) i stedet for at jeg i min onSuccess skal checke om hvorvidt der var fejl i input
- Min webservice kan retunere de oplagte objekter i stedet for at retunere en samling errors, som hvis == null betyder alt gik godt.


Jeg har læst om forskellige metoder hvor jeg fx kunne have en Validate på Personklassen, hvilket også ville fungere fint i en winform, men da jeg kører asynkron vil jeg enten skulle kalde serveren to gange (én valider, én insert) eller jeg ville ende med at skulle returnere fejlobjekter om hvorvidt der var fejl.

Mit bedste bud på forbedring er at lave javascript validering inden jeg poster, og derfor ikke får en UserFriendlyException, men at den stadig eksisterer for at sikre reglerne bliver håndhævet. Det giver dog en lille udfordring med sprogversioneringen (fejlbeskederne) samt at jeg nu vil have 2x valideringskode at vedligeholde :(

Hvad er jeres tanker omkring denne opsætning? Er det dårlig praksis at kaste exceptions over sådanne basale regler i en opsætning som denne? Og hvad kunne alternativet være?
Avatar billede arne_v Ekspert
27. april 2011 - 00:55 #1
Client side versus server side validering
-----------------------------------------

server side validering for at sikre integritet og sikkerhed

client side validering for bekvemhed

altid server side validering

client side validering hvis bruger oplevelsen er vigtig
Avatar billede arne_v Ekspert
27. april 2011 - 00:56 #2
exceptions
----------

exceptions er beregnet til og det er derfor helt fint at bruge exceptions til at styre udfoersels flowet hvis der sker noget uventet
Avatar billede arne_v Ekspert
27. april 2011 - 00:59 #3
validering i PL eller BAL
-------------------------

PL boer validere det syntaktiske

BAL boer vaere type staerk og validere det semantiske

Eksempler:

PL fanger at "ABC" ikke er en valid alder

BAL fanger at man ikke kan have faaet sin eksamen foer end man er foedt
Avatar billede arne_v Ekspert
27. april 2011 - 01:01 #4
Generelt
--------

En BAL klasse med static metoder er noget fy fy.

Din BAL klasse ser meget tynd ud funktionalitets maessigt.
Avatar billede idiotbarn Nybegynder
27. april 2011 - 18:15 #5
Hej
Tak for svarene :)
Angående statiske BAL funktioner er noget fy, er det så fordi man skal kunne implementere komplekse valideringsregler som ikke nødvendigvis kan indeholdes i en statisk funktion?

Som det er nu, er det meget simpel validering der er i mit BAL da der ikke er meget der skal checkes, kun lidt strenglængde og sådan, så det var nemmere at lave den statisk end at oprette en klasse hver gang den kaldes, men det kan være jeg kan løbe ind i problemer senere?
Avatar billede arne_v Ekspert
27. april 2011 - 18:36 #6
Den vaesentligste grund til at static ikke er godt er at du ikke kan erstatte implementeringen.

et BAL interface
en eller flere BAL implementationer
en factory eller DI maade at give PL en instans som implementerer interfacet
Avatar billede idiotbarn Nybegynder
27. april 2011 - 18:44 #7
Ah selvfølgelig, jeg havde ikke husket interface'ne
Ligger du et svar? :)
Avatar billede arne_v Ekspert
27. april 2011 - 18:57 #8
kommer her
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester