webForumDet fria alternativet

get and set i ASP.NET 3.5 Lätt fråga

.NET

6 svar · 534 visningar · startad av SebastianE

Medlem sedan nov. 2004100 inlägg
Frågan#1

Har en applikation som består utav fem lager. Där vi har affärslagret och dataåtkomstlagret bland annat.

I mitt affärslager är jag väldigt noggrann att validera data. När jag använde mig av ASP.NET 2.0 fungerade properties lite annorlunda jämfört mot vad det gör i ASP.NET 3.5.

Förut när jag skulle validera data i mitt affärslager skapade jag en instans av affärslagret ifrån dataåtkomstlagret och skickade in mina värden från databasen till en konstruktor i affärslagret som satt properties. I min properties validerade jag sen datan.

Så här har jag löst det nu

rivate string _userID;

  public string UserID
  {
  get { return _userID; }
  set
  {
  ListPropRegex reg = RegexC.GUserID(_userID)[0];
  try
  {
  if (!reg.validate)
  {
  throw new Exception(reg.errorMessage);
  }
  _userID = value;
  }
  catch (Exception)
  {
  throw new Exception(reg.sendBug);
  }
  }
  }

  //Constructor
      public User(string userID)
      {
  this._userID = userID;
  this.UserID = _userID;
      }

Har även försökt att sätta UserID direkt genom att skriva this.UserID = userID i konstruktorn. Men då flippar hela applikationen ut totalt. Debuggen i Visual Studio får knäpp och slutar att fungera bland annat.

Finns det något snyggare sätt att lösa det hela?

Medlem sedan aug. 20003 575 inlägg
#2

SebastianE skrev:

Har en applikation som består utav fem lager. Där vi har affärslagret och dataåtkomstlagret bland annat.

I mitt affärslager är jag väldigt noggrann att validera data. När jag använde mig av ASP.NET 2.0 fungerade properties lite annorlunda jämfört mot vad det gör i ASP.NET 3.5.

Förut när jag skulle validera data i mitt affärslager skapade jag en instans av affärslagret ifrån dataåtkomstlagret och skickade in mina värden från databasen till en konstruktor i affärslagret som satt properties. I min properties validerade jag sen datan.

Så här har jag löst det nu

rivate string _userID;

  public string UserID
  {
  get { return _userID; }
  set
  {
  ListPropRegex reg = RegexC.GUserID(_userID)[0];
  try
  {
  if (!reg.validate)
  {
  throw new Exception(reg.errorMessage);
  }
  _userID = value;
  }
  catch (Exception)
  {
  throw new Exception(reg.sendBug);
  }
  }
  }

  //Constructor
      public User(string userID)
      {
  this._userID = userID;
  this.UserID = _userID;
      }

Har även försökt att sätta UserID direkt genom att skriva this.UserID = userID i konstruktorn. Men då flippar hela applikationen ut totalt. Debuggen i Visual Studio får knäpp och slutar att fungera bland annat.

Finns det något snyggare sätt att lösa det hela?

Inte många rätt där?

Kan du förklara vad du gör? Du slänger ett excption för att sedan fånga det och slänga ett nytt exception?

Sedan typen Exception skall man aldrig kasta.

Sedan enligt många böcker skall man inte kasta exception när man sätter värdet utan det är bättre att kunna sätta värdet och sedan fråga objektet om det går igenom valideringen så slipper man oftast exceptions.

user.Id = id;
if(!user.IsValid())
//meddela användaren.

 try
  {
  if (!reg.validate)
  {
  throw new Exception(reg.errorMessage);
  }
  _userID = value;
  }
  catch (Exception)
  {
  throw new Exception(reg.sendBug);
  }
Medlem sedan nov. 2004100 inlägg
#3

Nickemannen skrev:

Inte många rätt där?

Kan du förklara vad du gör? Du slänger ett excption för att sedan fånga det och slänga ett nytt exception?

Sedan typen Exception skall man aldrig kasta.

Sedan enligt många böcker skall man inte kasta exception när man sätter värdet utan det är bättre att kunna sätta värdet och sedan fråga objektet om det går igenom valideringen så slipper man oftast exceptions.

user.Id = id;
if(!user.IsValid())
//meddela användaren.

 try
  {
  if (!reg.validate)
  {
  throw new Exception(reg.errorMessage);
  }
  _userID = value;
  }
  catch (Exception)
  {
  throw new Exception(reg.sendBug);
  }

Först kollar om jag om man skickar in rätt datatyp kan man säga genom min try catch sats.
Det variabeln reg gör att hämta en bool ifrån klassen RegexC som kontrollerar då om datan är rätt. Om så inte är fallet får användaren ett exception där det står klart och tydligt att det är felaktig data.

Varför ska man aldrig slänga en exception?

Jo jag vet att man ska sätta variablen först men problemet när jag gör det är att jag får ett exception av debuggern som inte säger mig något. Annars förstår jag inte riktigt vad du menar.

Hade först följande kod i konstruktorn
UserID = userID; men det blir knas.

Medlem sedan juni 20014 421 inlägg
#4

Jag tror att nickemannen menar att du aldrig ska slänga Exception-typen exception, utan i detta fallet kanske ett ValidationErrorException() eller liknande.

Medlem sedan nov. 2004100 inlägg
#5

colione skrev:

Jag tror att nickemannen menar att du aldrig ska slänga Exception-typen exception, utan i detta fallet kanske ett ValidationErrorException() eller liknande.

AHA! Då förstår jag. Tusen tack :)

Medlem sedan aug. 20003 575 inlägg
#6

Exakt men jag undrar också varför du slänger exception två gånger?

Hur menar du med rätt datatyp? Rätt formatering på strängen?

Medlem sedan maj 20012 812 inlägg
#7

rivate string _userID;

public string UserID
{
get { return _userID; }
set
{
ListPropRegex reg = RegexC.GUserID(_userID)[0];
try
{
if (!reg.validate)
{
throw new Exception(reg.errorMessage);
}
_userID = value;
}
catch (Exception)
{
throw new Exception(reg.sendBug);
}
}
}

//Constructor
public User(string userID)
{
this._userID = userID;
this.UserID = _userID;
}

Det första som jag reagerar på är att du i din Set-property använder dig av _userId för att kontrollera UserId. Det är rent felaktigigt eftersom du inte kontrollera det värde som du skickar till metoden utan det värde som redan finns i _userId. Använd value eller en temporär variable som du sätter innan du gör din kontroll.

Det andra är din hantering av exceptions som kanske inte är helt lyssande :). Jag vet att det finns en hel del som förespråkar att Exception används endast när det inträffar fel som du inte kan förvänta dig, och i ditt fall så gör du en kontroll om userId är valit eller ej, och bör alltså du förvänta dig att det inte är valit och skall alltså då inte använda exceptions precis som nickemannen säger...

Med det sagt så är det bra i visa situationer och mindre bra i andra. Själv så använder jag exceptions på det sättet som du när det gäller fel som användaren bör få information om, men skulle inte göra det i en applikation utan grafisk gränssnitt eftersom exception suger prestanda ur en applikation... Men när det gäller att avbryta ett flöde och meddela användaren att något är fel, så är exceptions outstanding, jämdört med att själv hantera allt detta....

I vilket fall som helst så bör man bara fånga fel som man kan hantera och göra något åt, och då när man kastar felet vidare så bör det vara specifika fel.

Det sista som jag reagerar på är din konstruktor, att först sätta den privat variablen och sedan där efter göra hela kontrollen av värdet som du sätter är också helt felaktigit eftersom din variable kommer innehålla det värde som du satt även om det inte är valit...

Så det mest skrämmande är att din kod kan få programmet in ett tillstånd som du inte förväntar dig, och det är en riktigt fet NO NO...

Så här hade jag skrivit koden...

private string _userID;

public string UserID
{
  get { return _userID; }
  
  set
  {
	string tmpUserId = value;
	try
  	{
  		ListPropRegex reg = RegexC.GUser(IDtmpUserId)[0];
  
		if (!reg.validate)
	  		throw new MyValidateErrorException(reg.errorMessage);
		  
		_userId = tmpUserId;
  	}
	catch(MyValidateErrorException exception)
	{
		throw new (MyValidateErrorException (reg.sendBug, exception);
	}
  }

//Constructor
public User(string userID)
{
	this.UserId = userId;
}

Eller om du vill använda lite mer .Net 3.5 finesser.

Ta bort koden i din konstruktor och skapa din user så här:

//Constructor
public User() { }
User user = new User(UserId = "Gladh rocks...");

p.s

När jag använde mig av ASP.NET 2.0 fungerade properties lite annorlunda jämfört mot vad det gör i ASP.NET 3.5.

Nej då de fungerar precis likadant, bara att man har fått lite fler möjligheter att korta ner sin kod, och dessutom sätta olika åtkomst på get och set metoden....

263 ms totalt · 4 externa anrop · v20260731065814-full.6fe65c25
124 ms — deklarationer (db)
0 ms — hämta statistik (cache)
136 ms — hämta tråd, inlägg och bilagor (db)
117 ms — ändringar (db)