Ieri am promis ca revin cu un post despre ce nu ar trebuii sa contina un view.
Pornim de la o clasa PersonModel care are urmatoarea definitie:
public class PersonModel
{
public string Name { get; set; }
public int Age { get; set; }
public string Address { get; set; }
}
Pentru acest model avem urmatorul view:@model PersonModel
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<title>Person</title>
</head>
<body>
<fieldset>
<legend>PersonModel</legend>
<div class="display-label">Name</div>
<div class="display-field">
@Html.DisplayFor(model => model.Name)
</div>
<div class="display-label">Age</div>
<div class="display-field">
@Html.DisplayFor(model => model.Age)
</div>
<div class="display-label">Address</div>
<div class="display-field">
@Html.DisplayFor(model => model.Address)
</div>
</fieldset>
</body>
</html>
Mai tarziu apare o noua cerinta in aplicatie, ca sa se afiseze si coodonatele GPS a locatiei date. Pentru acest lucru se foloseste o adresa web care stie sa rezolve orice adresa. O implementare simpla este urmatoarea:@model CIC.PersonModel
@{
Layout = null;
string coordLat;
string coordLong;
var request = WebRequest.Create(someAddress + "?location=" + Model.Address);
var webResponse = request.GetResponse();
using (var contentStream = new StreamReader(webResponse.GetResponseStream()))
{
var content = contentStream.ReadToEnd();
webResponse.Close();
string[] coords = content.Split(' ');
coordLong = coords[0];
coordLat = coords[1];
}
}
<!DOCTYPE html>
<html>
<head>
<title>Person</title>
</head>
<body>
<fieldset>
<legend>PersonModel</legend>
<div class="display-label">
Name</div>
<div class="display-field">
@Html.DisplayFor(model => model.Name)
</div>
<div class="display-label">
Age</div>
<div class="display-field">
@Html.DisplayFor(model => model.Age)
</div>
<div class="display-label">
Address</div>
<div class="display-field">
@Html.DisplayFor(model => model.Address)
</div>
<div class="display-label">
GPS Location</div>
<div class="display-field">
@coordLong
@coordLat
</div>
</fieldset>
</body>
</html>
Pagina functioneaza fara nici o problema doar ca in viewul face mult prea multe lucruri. Din el se face un request spre o alta componenta( serviciu), prin intermediul caruia se obtin coordonatele GPS a unei adrese, care se afiseza in view.Modelul nu contine toate datele necesare pentru a afisa tot ce este necesar. Din aceasta cauza se ajunge sa se faca un apel spre o componenta externa. Nu are importanta daca aceasta componenta este un serviciu extern sau o clasa din assemblyul nostru. Toate datele necesare trebuie sa fie continute de catre model. Orice data trebuie sa ajunga in view prin intermediul modelului.
O solutie este sa adaugam doua propietati in PersonModel care sa reprezinte coordonatele GPS( sau putem sa ne cream o clasa care sa stocheze longitudinea si latitudinea - dar tot ca si o propietate din PersonModel o sa fie).
public class PersonModel
{
public string Name { get; set; }
public int Age { get; set; }
public string Address { get; set; }
public string Longitude { get; set; }
public string Latitude { get; set; }
}
Inițializarea coordonatelor urmeaza sa fie mutata in controler. Problema de la care am pornit a fost rezolvata, insa ... apare un smell la orizont. Nu foarte puternic, dar extrem de periculos. Apelul spre serviciu se face direct din controler, cea ce nu e normal. Da, este adevarat ca controlerul ar trebuii sa pregateasca modelul, dar obtinerea coordonatelor ar trebuii sa se faca in alt loc. De exemlu putem sa scoatem acest apel intr-o alta clasa.
0 comments:
Post a Comment