Guitar Store Magazin Virtual de Chitare

GuitarStore – magazin virtual de chitare

REZUMATUL PROIECTULUI

Prezentare generală

GuitarStore este o aplicație care explică pas cu pas cum să utilizați ASP.NET MVC și Visual Web Developer pentru dezvoltare web. 

Aplicația pe care o vom construi va conține site-ul online al unui magazin de chitare. 

Vizitatorii pot vizualiza lista de chitare dupa o anumită marcă (dupa un anumit producător) :

Ei vor putea vizualiza o singură chitară pe care o vor putea adăuga la coșul de cumpăraturi :

Ei pot revizui coșul lor putand îndepărta orice produs pe care nu îl mai doresc:

Ajungand la partea de checkout utilizatorilor li se va cere introducerea datelor contului si a parolei sau inregistrarea pentru un nou cont.

După crearea unui cont, comanda se poate finaliza prin completarea datelor de livrare si plata. Pentru a păstra lucrurile simple vom folosi o promoție gratis cu codul de promovare "FREE".

După finalizarea comenzii pe ecran va aparea confirmarea :

Vom construi de asemenea, o secțiune administrator care afișează o listă de chitare din care administratorii pot crea, edita și șterge produse :

Vom avea și o secțiune de căutare a chitarelor dupa marcă și/sau după gen:

CUPRINSUL

1 Introducere

1.1 Motivația

2 Aspecte teoretice

2.1 MVC

2.2 Baze de date

2.3 Concepte client server

2.4 Functiile de gestiune ale bazelor de date

2.5 HTML

2.6 Modelul relational

2.7 CSS

2.8 ASP.NET

2.9 Jquery

3 Prezentare proiect

3.1 Crearea unui nou proiect

3.2 Adaugarea unui controller Home . Adaugarea unui StoreController

3.3 Adaugarea unui View Template

3.4 Elemetele comune ale aspectului site-ului

3.5 Folosind un model pentru a trece informatia catre un View

Legaturile dintre pagini

3.6 Accesul la baza de date cu Entity Frameword Code-First

3.6.1 Modificarile claselor Model

3.6.1.1 Adaugarea clasei Model Chitara

3.6.1.2 Modificam clasele Model

3.6.2 Adaugarea fisierului App_Data

3.6.3 Modificam fisierul web.config

3.6.4 Adaugarea unei clase Context

3.6.5 Adaugarea unei baze de date

3.7 Interogarea bazei de date

3.7.1 Actualizarea Index-ului Store

3.7.2 Actualizarea Store Browse si Details

3.8 Crearea controller-ului StoreManagerCotroller

3.9 Scaffolded View

3.10 Store Manager

3.11 Codul controller-ului Store Manager

3.11.1 Index-ul Store Manager

3.11.2 Manevrarea valorilor Posted Form

3.11.3 Manevrarea Edit-ului

3.11.4 Manevrarea Delete-ului

3.12 Alte actualizari

3.13 Adaugarea validarilor la formulare

3.14 Adaugarea controllerului Account controller

3.15 Adaugarea unui user Administrator folosind metoda ASP.Net Configuration

3.16 Role-based authorization

3.17 Adugarea claselor model Cart, Order si Order Detail

3.18 Menajarea cosului de cumparaturi

3.19 ViewModels

3.19.1 Controller-ul Shopping Cart

3.20 Actualizari Ajax jQuery

3.21Migrating the Shoping Cart

3.22 Crearea controller-ului Checkout Controller

3.23 Adaugarea AddressAndPayment view

3.24 Regulile definite ale validarii clasei Order

3.25 Adaugarea completa Checkout view

3.26 Actualizarea Error view.

3.27 Crearea partiala a Shopping Cart-ului

3.28 Crearea partiala a meniului Marca

3.29 Actualizam SiteLayout-ul pentru a afisa Partial Views90

3.30 Actualizam pagina Store Browse

3.31 Actualizam pagina Home Page pentru a vizualiza cele mai vandute chitare

3.32 Cautare

3.33 Modelul relational sub forma .edmx

3.34 Diagrama Use case

4 Concluzii

5 Referințe web

6 Biblografie

CD / DVD

Introducere

Motivația

Aplicațiile web moderne sunt sisteme software complexe, iar dezvoltarea acestora necesită o abordare metodologică a proiectării lor. Similar cu proiectarea aplicațiilor software, proiectarea web implică utilizarea unei abordări sistematice și cuantificabile pentru realizarea specificațiilor, implementării, operațiilor și întretinerii aplicațiilor web de calitate superioară. Din punct de vedere al istoricului dezvoltării și complexității distingem anumite tipuri de aplicații web; aplicațiile web pot fi orientate pe documente, interactive, tranzacționale, pot dispune de caracteristici ubicue sau chiar de trăsături ale web-ului semantic. Cerințele particulare ale proiectării aplicațiilor web rezultă din caracteristicile lor speciale din sfera produselor software, dezvoltării și utilizării acestora. Evoluția este o caracteristică care cuprinde cele trei sfere menționate.

Inițial, web-ul a fost proiectat ca un mediu pur informațional, în prezent evoluand într-un mediu al aplicației. Aplicațiile web de astăzi sunt rapide și reprezintă sisteme software complexe care oferă servicii interactive și personabilizabile accesibile prin intermediul diferitelor dispozitive; ele oferă posibilitatea realizării tranzacțiilor între utilizatori și de obicei stochează datele într-o bază de date. Elementul distinctiv al aplicațiilor web, comparativ cu aplicațiile software tradiționale, este modul în care este utilizat web-ul: de exemplu tehnologiile și standardele sale sunt utilizate ca o platformă de dezvoltare și ca platformă utilizator în același timp.

Aspecte Teoretice si tehnologii

În această secțiune sunt detaliate convențiile de urmat în timpul editării lucrării.

MVC

Model-View-Controller (MVC) este un șablon arhitectural folosit pentru separarea logicii interne a unei aplicații de partea sa de prezentare, oferind posibilitatea modificării independente a acestor componente și făcând reutilizarea mai ușoară.

Arhitectura MVC este alcătuită din 3 componente principale:

– Componenta Model – datele cu care lucrează aplicația

– Componenta View – prezentarea datelor către utilizator, de obicei în formă unei interfețe grafice. Pot exista mai multe view-uri asociate cu un același model

– Componenta Controller – captează și procesează acțiunile utilizatorilor

Modelul reprezintă partea de hard-programming, partea logică a aplicației. El are în responsabilitate acțiunile și operațiile asupra datelor, autentificarea utilizatorilor, integrarea diverselor clase ce permit procesarea informațiilor din diverse baze de date.

View-ul se ocupă de afișarea datelor, practic această parte a programului va avea grijă de cum vede end-userul informația procesată de controller. O data ce funcțiile sunt executate de model, viewului îi sunt oferite rezultatele, iar acesta le va trimite către browser. În general viewul este o mini-aplicație ce ajută la randarea unor informații, având la bază diverse template-uri.

Controller-ul reprezintă creierul aplicației. Aceasta face legătura între model și view, între acțiunile userului și partea decizională a aplicației. În funcție de nevoile utilizatorului, controllerul apelează diverse funcții definite special pentru secțiunea de site în care se află userul. Funcția se va folosi de model pentru a prelucra (extrage, actualiza) datele, după care informațiile noi vor fi trimise către view, ce le va afișa apoi prin template-uri.

Componentele View și Controller depind de componenta Model, însă modelul nu depinde de nici una dintre cele două. Acesta este avantajul cheie al separării. Această separare permite modelului să fie proiectat și testat independent de prezentarea vizuală. Separarea componentelor view și controller este secundară în multe aplicații, multe interfețe cadru pentru utilizatori implementându-le ca pe un singur obiect. În aplicațiile web, pe de altă parte, separarea componenței view (browser-ul) de componenta controller (componentele server ce se ocupă cu cererile HTTP) este foarte bine definită.

Conceptul poate fi perceput la nivel:

arhitectural – se referă la structura întregii aplicații, în care diferitele componente își asumă rolurile de mai sus (exemplu: Grails framework)

de design – utilizat în contextul unor scenarii mai restrânse (exemplu: componentele vizuale Swing).

Structura componentelor MVC

Baze de date

Noțiuni generale

O bază de date reprezintă un ansamblu de date integrat, anume structurat și dotat cu o descriere a acestei structuri. Descrierea structurii poartă numele de dicționar de date sau metadate și crează o interdependență între datele propriu-zise și programe.

Baza de date poate fi privită ca o colecție de fișiere interconectate care conțin nucleul de date necesare unui sistem informatic. Astfel, poate fi considerată drept un model al unor aspecte ale realității unei unități economice, modelată prin intermediul datelor. Diferitele obiecte din cadrul realității ce prezintă interes sunt denumite clase sau entități. Pentru aceste obiecte sunt achiziționate și memorate date referitoare la diferite caracteristici (atribute). Baza de date se constituie ca un ansamblu intercorelat de colecții de date, prin care se realizează reprezentarea unei realități.

Datele constituie orice mesaj primit de un receptor, sub o anumtă formă.

Informațiile reprezintă cantitatea de noutate adusă de un mesaj din exterior (realitate).

Un fișier este un ansamblu de înregistrări fizice, omogene din punct de vedere al conținutului și al prelucrării.

O înregistrare fizică este o unitate de transfer între memoria internă și cea externă a calculatorului.

O înregistrare logică este unitatea de prelucrare din punct de vedere al programului utilizator. O înregistrare se compune din câmpuri (atribute) care descriu anumite aspecte ale realității.

Câmpurile sunt înregistrări logice.

O bază de date trebuie să asigure:

• abstractizarea datelor (baza de date fiind un model al realității)

• integrarea datelor (baza de date este un ansamblu de colecții de date intercorelate, curedundanță controlată)

• integritatea datelor (se referă la corectitudinea datelor încărcate și manipulate astfel încât să se respecte restricțiile de integritate)

• securitatea datelor (limitarea accesului la baza de date)

• partajarea datelor (datele pot fi accesate de mai mulți utilizatori, eventual în același timp)

• independența datelor (organizarea datelor să fie transparentă pentru utilizatori, modificările în baza de date să nu afecteze programele de aplicații).

Concepte client server

Modelul client-server este o structură sau arhitectură aplicație distribuită care partajează procesarea între furnizorii de servicii numiți servere și elementele care solicită servicii, numite clienți. Clienții și serverele comunică printr-o rețea de calculatoare, de obicei prin Internet, având suporturi hardware diferite, dar pot rula și pe același sistem fizic. Un server rulează unul sau mai multe programe server, care partajează resursele existente cu clienții. Clientul nu partajează nici una dintre resursele proprii, ci apelează la resursele serverului prin funcțiile server. Clienții inițiază comunicația cu serverele și așteaptă mesajele acestora. Pentru menționarea legăturii între cei doi, indiferent de pauzele care intervin, se folosește conceptul de sesiune, care de obicei este limitată în timp.

Aplicațiile clinet-server se pot prezenta sub mai multe forme, în mod tradițional fiind clasificate după:

1. numărul de așa-zise straturi de aplicații – aplicații cu 2, 3 și n straturi

2. natura proceselor client și server – aplicații client-server cu baze de date și aplicații client-server standard

La ora actuală, aplicațiile client-server cu baze de date sunt utilizate pe scară largain sistemele software dedicate managementului afacerilor. Într-o aplicație client-server cu baze de date, organizată pe două straturi (cea mai simplă formă de manifestare), cele două procese sunt:

1. Clientul – o aplicație scrisă într-un limbaj de programare oarecare dar care utilizează date stocate în baza de date (în marea majoritate, stratul client este formatrare fizică este o unitate de transfer între memoria internă și cea externă a calculatorului.

O înregistrare logică este unitatea de prelucrare din punct de vedere al programului utilizator. O înregistrare se compune din câmpuri (atribute) care descriu anumite aspecte ale realității.

Câmpurile sunt înregistrări logice.

O bază de date trebuie să asigure:

• abstractizarea datelor (baza de date fiind un model al realității)

• integrarea datelor (baza de date este un ansamblu de colecții de date intercorelate, curedundanță controlată)

• integritatea datelor (se referă la corectitudinea datelor încărcate și manipulate astfel încât să se respecte restricțiile de integritate)

• securitatea datelor (limitarea accesului la baza de date)

• partajarea datelor (datele pot fi accesate de mai mulți utilizatori, eventual în același timp)

• independența datelor (organizarea datelor să fie transparentă pentru utilizatori, modificările în baza de date să nu afecteze programele de aplicații).

Concepte client server

Modelul client-server este o structură sau arhitectură aplicație distribuită care partajează procesarea între furnizorii de servicii numiți servere și elementele care solicită servicii, numite clienți. Clienții și serverele comunică printr-o rețea de calculatoare, de obicei prin Internet, având suporturi hardware diferite, dar pot rula și pe același sistem fizic. Un server rulează unul sau mai multe programe server, care partajează resursele existente cu clienții. Clientul nu partajează nici una dintre resursele proprii, ci apelează la resursele serverului prin funcțiile server. Clienții inițiază comunicația cu serverele și așteaptă mesajele acestora. Pentru menționarea legăturii între cei doi, indiferent de pauzele care intervin, se folosește conceptul de sesiune, care de obicei este limitată în timp.

Aplicațiile clinet-server se pot prezenta sub mai multe forme, în mod tradițional fiind clasificate după:

1. numărul de așa-zise straturi de aplicații – aplicații cu 2, 3 și n straturi

2. natura proceselor client și server – aplicații client-server cu baze de date și aplicații client-server standard

La ora actuală, aplicațiile client-server cu baze de date sunt utilizate pe scară largain sistemele software dedicate managementului afacerilor. Într-o aplicație client-server cu baze de date, organizată pe două straturi (cea mai simplă formă de manifestare), cele două procese sunt:

1. Clientul – o aplicație scrisă într-un limbaj de programare oarecare dar care utilizează date stocate în baza de date (în marea majoritate, stratul client este format din obiecte ce alcătuiesc interfața grafică cu utilizatorul și câteva procese de prelucrare a datelor)

2. Server-ul – este de fapt sistemul de gestiune al bazei de date folosit pentru a stoca datele. Acesta va primi cereri de tip Create, Read, Update, Delete din partea clientului, va executa cererile respective, asupra datelor din baza de date, într-o manieră tranzacțională și va returna rezultatul

Acest gen de aplicații este comun sistemelor software din organizații, asigurând un punct unic de stocare și nelimitate posibilități de acces oriunde-oricând a datelor companiei.

Aplicație client-server tradițională (organizată pe două straturi cu server de baze de date)

Într-o asemenea aplicație, cele două procese distincte (client și server) sunt conectate prin intermediul a două componente specifice:

a) Componenta de rețea – asigură aspectele fundamentale de comunicare între două procese aflate pe calculatoare diferite, știind că sistemul bazei de date se află, de regulă, instalat pe un calculator server, în rețeaua companiei;

b) API de inter-conectare – un set de componente software predefinite ce implementează un API ( Application Programming Interface ) standardizat și care va asigura transferul cererilor și al datelor între procesul client și procesul server. Componentele din această categorie sunt localizate, de regulă, pe calculatorul client și vor fi utilizate de către procesul client pentru a reuși conectarea la serverul de baze de date și a executa setul de operații asupra datelor.

Clientul folosește un set de componente predefinite pentru a trimite cereri serverului de baze de date

Componentele de interconectare sunt organizate, la rândul lor, pe două straturi:

a) Componente de nivel-înalt – utilizate în mod direct de către programatorii proceselor-client. Sunt componente specifice limbajului sau platformei de programare utilizatepentru aplicația-client

b) Componente de nivel-jos – sunt utilizate de către componentele de nivel înalt pentru execuția carerilor către serverul de baze de date și asigură operațiile ce au legătură directă cu sistemul de operare și cu softul specific rețelelor. Sunt, de regulă, componente standardizate ce oferă servicii de conectare pentru toate limbajele de programare. Componentele de nivel jos vor fi utilizate în mod indirect și transparent de programatori.

Functiile de gestiune ale bazelor de date

Sistemele de gestiune a bazalor de date (SGBD) sunt sisteme informatice specializate în stocarea și prelucrarea unui volum mare de date, numărul prelucrărilor fiind relativ mic.

Termenul de bază de date se va referi la datele de prelucrat, la modul de organizare a acestora pe suportul fizic de memorare, iar termenul de gestiune va semnifica totalitatea operațiilor ce se aplică asupra datelor din baza de date.

Un SGBD trebuie să asigure următoarele funcții:

• definirea – crearea bazei de date;

• introducerea (adăugarea) datelor în baza de date;

• modificarea unor date deja existente în baza de date;

• ștergerea datelor din baza de date;

• consultarea bazei de date – interogare/extragerea datelor.

În plus un SGBD mai asigură și alte servicii:

• suport pentru limbaj de programare;

• interfață cât mai atractivă pentru comunicare cu utilizatorul;

• tehnici avansate de memorare, organizare, accesare a datelor din baza de date;

• utilitare încorporate: sistem de gestiune a fișierelor, liste, tabele etc.;

• “help” pentru ajutarea utilizatorului în lucrul cu baza de date.

Apariția și răspândirea rețelelor de calculatoare a dus la dezvoltarea SGBD-urilor în direcția multiuser: mai mulți utilizatori folosesc simultan aceeași bază de date.

Principalul avantaj al rețelelor a fost eficiența mult sporită de utilizare a resurselor sistemelor de calcul: la o bază de date aflată pe un server central au acces simultan mai mulți utilizatori, situați la distanță de server, de unde rezultă o bună utilizare a resurselor server-ului și o economie de memorie datorată memorării unice a bazei de date.

Un SGBD este dotat cu un limbaj neprocedural de interogare a bazei de date SQL care permite accesul rapid și comod la datele stocate în baza de date.

În arhitectura unui sistem de baze de date SGBD ocupă locul central.

Un SGBD este un ansamblu complex de programe care asigură interfața între o bază de date și utilizatorii acesteia. SGBD este componenta software a unui sistem de baze de date care interacționează cu toate celelalte componente ale acestuia asigurând legătura și interdependența între ele.

Un SGBD trebuie să asigure următoarele activități:

• definirea și descrierea structurii bazei de date – se realizează printr-un limbaj propriu, limbaj de definire a datelor (LDD), conform unui anumit model de date;

• încărcarea datelor în baza de date – se realizează prin comenzi în limbaj propriu, limbaj de manipulare a datelor (LMD);

• accesul la date – se realizează prin comenzi specifice din limbajul de manipulare a datelor. Accesul la date se referă la operațiile de interogare și actualizare.

Interogarea este complexă și presupune vizualizarea, consultarea, editarea de situații de ieșire (rapoarte, liste, regăsiri punctuale).

Actualizarea presupune 3 operațiuni: adăugare, modificare efectuate prin respectarea restricțiilor de integritate ale BD și ștergere;

• întreținerea bazei de date – se realizează prin utilitare proprii ale SGBD;

• reorganizarea bazei de date – se face prin facilități privind actualizarea structurii de date și modificarea strategiei de acces. Se execută de către administratorul bazei de date;

• securitatea datelor – se referă la asigurarea confidențialității datelor prin autorizarea și controlul accesului la date, criptarea datelor.

Un SGBD are rolul de a furniza suportul software complet pentru dezvoltarea de aplicații informatice cu baze de date.

El trebuie să asigure:

• minimizarea costului de prelucrare a datelor,

• reducerea timpului de răspuns,

• flexibilitatea aplicațiilor și

• protecția datelor.

Pentru satisfacerea performanțelor enumerate, SGBD trebuie să asigure un minim de obiective.

1. Asigurarea independenței datelor – trebuie privită din două puncte de vedere:

ƒ independența logică – se referă la posibilitatea adăgării de noi tipuri de înregistrări de date sau extinderea structurii conceptuale, fără a determina rescrierea programelor de aplicație;

ƒ independența fizică – modificarea tehnicilor fizice de memorare fără a determina rescrierea programelor de aplicație.

2. Asigurarea redundanței minime și controlate a datelor – stocarea informațiilor în bazele de date se face astfel încât datele să nu fie multiplicate. Totuși, pentru a îmbunătăți performanțele legate de timpul de răspuns, se acceptă o anumită redundanță a datelor, controlată, pentru a asigura coerența bazei de date și eficiența utilizării resurselor hardware.

3. Asigurarea facilităților de utilizare a datelor – presupune ca SGBD-ul să aibă anumite componente specializate pentru:

• folosirea datelor de către mai mulți utilizatori în diferite aplicații – datele de la o aplicație trebuie să poată fi utilizate și în alte aplicații.

• accesul cât mai simplu al utilizatorilor la date – fără ca ei să fie nevoiți să cunoască

structura întregii baze de date; această sarcină cade în seama administratorului bazei de date.

• existența unor limbaje performante de regăsire a datelor – care permit exprimarea interactivă a unor cereri de regăsire a datelor.

• sistemul de gestiune trebuie să ofere posibilitatea unui acces multicriterial la informațiile din baza de date – spre deosebire de sistemul clasic de prelucrare pe fișiere unde există un singur criteriu de adresare, cel care a stat la baza organizării fișierului.

4. Asigurarea securității datelor împotriva accesului neautorizat.

5. Asigurarea coerenței și integrității datelor împotriva unor ștergeri intenționate sauneintenționate – se realizează prin intermediul unor proceduri de validare, a unor protocoale de control concurent și a unor proceduri de refacere a bazei de date.

6. Asigurarea partajabilității datelor – se referă pe de o parte la asigurarea accesului mai multor utilizatori la aceleași date și de asemenea la posibilitatea dezvoltării unor aplicații fără a se modifica structura bazei de date.

7. Asigurarea legăturilor între date – corespund asocierilor care se pot realiza între obiectele unei aplicații informatice. Orice SGBD trebuie să permită definirea și descrierea structurii de date, precum și a legăturilor dintre acestea, conform unui model de date (de exemplu modelul relațional).

8. Administrarea și controlul datelor – sunt asigurate de SGBD, în sensul că datele pot fi folosite de mai mulți utilizatori în același timp, iar utilizatorii pot avea cerințe diferite și care pot fi incompatibile. SGBD trebuie să rezolve probleme legate de concurență la date, problemă care apare mai ales în lucrul în mediu de rețea de calculatoare.

Funcțiile unui SGBD.

ƒ funcția de descriere a datelor – se face cu ajutorul LDD, realizându-se descrierea atributelor din cadrul structurii BD, legăturile dintre entitățile BD, se definesc eventualele criterii de validare a datelor, metode de acces la date, integritatea datelor. Concretizarea acestei funcții este schema BD.

ƒ funcția de manipulare – este cea mai complexă și realizează actualizarea și regăsirea datelor.

ƒ funcția de utilizare – asigură mulțimea interfețelor necesare pentru comunicare a tuturor utilizatorilor cu BD.

Categorii de utilizatori:

neinformaticieni – beneficiarii informației, nu trebuie să cunoască structura BD, nu trebuie să programeze aplicații ci doar să le folosească prin intermediul unei interfețe suficient de prietenoase.

informaticieni – crează structura BD și realizează procedurile complexe de exploatare a BD;

administratorul bazei de date – utilizator special, cu rol hotărâtor în funcționarea optimă a întregului sistem.

ƒ funcția de administrare – administratorul este cel care realizează schema conceptuală a bazei de date, iar în perioada de exploatare a BD autorizează accesul la date, reface baza în caz de incident.

ƒ funcția de protecție a bazei de date – ansamblul de măsuri necesare pentru asigurarea integrității (semantică, acces concurent, salvare/restaurare) și securității datelor (autorizare acces, utilizare viziuni, criptare).

Functiile sistemului de gestiune al bazei de date

HTML

HTML (Hypertext Markup Language) este un limbaj creat în scopul de a descrie, în mod text, formatul paginilor Web; fisierele create în acest limbaj vor fi interpretate de navigatoare, care vor afisa paginile în forma doritã (cu texte formatate, liste, tabele, formule, imagini, hiperlegãturi, obiecte multimedia etc.). HTML a apãrut ca o aplicatie ISO standard (apartine standardului SGML – Standard Generalized Markup Language, specializat pentru hipertext si adaptat la Web).

Asa cum se poate deduce din numele limbajului, HTML descrie caracteristicile de format ale elementelor incluse prin procedee de marcare. Acestea pot fi asemãnate intuitiv cu marcajele folosite în tipografie pentru a indica scrierea unui text cu un anumit tip de caractere. Fiecare element va fi introdus între douã marcaje ("tags", în limba englezã) – de început si sfârsit – (uzual) de forma <marcaj> … </marcaj>. Caracterele speciale de delimitare a marcajelor "<", ">" permit deosebirea acestora de textul propriu-zis. De exemplu, pentru textele aldine (îngrosate), marcajul de început este <B> iar de sfârsit – </B>.

În informaticã, limbajele de marcare sunt foarte convenabile fiindcã comenzile lor pot fi interpretate simplu. LaTeX-ul, de exemplu, este tot un limbaj de marcare; prin interpretarea fisierelor .tex descrise în acest limbaj se va genera formatul dorit al documentelor pe diverse tipuri de sisteme de calcul (în cazul, LaTeX-ului, se obtine uzual format PostScript sau PDF). În schimb, procesoarele de documente uzuale nu au un limbaj de marcare standardizat, care sã ofere compatibilitate între diverse tipuri de calculatoare si sisteme de operare. Astfel, se poate spune cã avantajele aplicãrii limbajelor de marcare constau în portabilitate si flexibilitate: fisierele create cu ajutorul lor pot fi transferate pe orice tip de sistem, unde vor fi interpretate cu ajutorul unor programe specifice.

De fapt, procesoarele de texte uzuale folosesc adesea procedee de marcare pentru formatãri (de exemplu, formatãrile de tip caracter din Word); în acest caz însã, caracterele de control introduse sunt ascunse iar rezultatul editãrii este direct vizibil ("What You See Is What You Get"). În schimb, în limbajele de marcare – inclusiv HTML – marcajele sunt introduse în text, astfel încât acestea sunt exclusiv succesiuni de caractere (litere, cifre, caractere speciale) – fisiere de tip text.

Referitor la legãtura dintre procesoarele de documente uzuale si limbajul HTML, mai trebuie mentionat faptul cã ultimele versiuni ale editoarelor de documente oferã facilitãti de salvare în format HTML – de exemplu, Word, începând cu versiunea Microsoft Office '97. Mai mult, toate produsele incluse în aceastã gamã dedicatã biroticii (MS Office) oferã compatibilitate cu formatul HTML.

Procesele de standardizare si de includere a comenzilor de marcare în fisierele HTML permit navigatoarelor sã citeascã si sã formateze paginile Web, lucru foarte important în conditiile în care ele contin nu numai texte alb-negru, ci si culori, imagini, hiperlegãturi, diverse obiecte. Practic, marcajele HTML asigurã controlul asupra modului de afisare a obiectelor corespunzãtoare în cadrul programelor de vizualizare a documentelor HTML – navigatoarele.

Limbajul HTML a evoluat în versiuni succesive, odatã cu evolutia protocolului HTTP si a programelor de navigare. Astfel, HTML 1.0 era compatibil cu Mosaic, primul program de navigare, dar dupã aparitia unor navigatoare noi, a fost necesarã introducerea unui standard oficial Internet pentru construirea paginilor (HTML 2.0) si extinderea sa cu noi facilitãti: formule matematice, tabele, moduri avansate de descriere a organizãrii paginilor (începând cu HTML 3.0).

Standardizarea oficialã a limbajului HTML a fost realizatã de consortiul WWW si dezvoltatã de diversi producãtori de soft (unii dintre acestia urmãresc chiar promovarea navigatoarelor proprii prin introducerea unor particularitãti în formatele oficiale).

Paginile HTML se pot crea cu orice editor de texte de cãtre utilizatorii care cunosc limbajul HTML sau, mai simplu, se pot utiliza editoare speciale, în care obiectele se introduc interactiv iar codul HTML se genereazã automat. Având în vedere cã si în acest caz este utilã cunoasterea marcajelor generate pentru corectarea eventualelor erori (mai ales în cazul link-urilor), vom prezenta în continuare entitãtile care se pot introduce în paginile HTML si marcajele caracteristice acestora:

Modelul relational

Modelul relational ca si orice alt model de date utilizat in proiectarea logica a bazelor de date elivereaza utilizatorul de cunoasterea detaliilor despre structura fizica si metodele de acces la date.

In afara de aceasta, el are 2 avantaje suplimentare : e simplu si elegant. Simplitatea sa consata in structurile de date omogene in forma de relatii tabelare. Iar eleganta modelului se explica prin temelia sa striintifica. El este riguros din punct de vedere matematic gratie faptului ca se sprijina pe teoriile din matematica a relatiilor sip e logica de ordinal unu.

Modelul relational a fost primul exemplu de model de date formal si a fost propus de E. Codd in 1970.

Prin model datele utilizatorului sunt reprezentate si manipulate in mod abstract. Modelul de asemenea presupune tehnici ce ajuta administratorul de a detecta si corecta posibilele problem de proiectare ce pot aparea o data cu pregatirea datelor pentru implementare intr-un SGBD concret.

Orice model de date , conform unei sugetii a lui Codd, trebuie sa se bazeze pe tri component : structure de date, constrangerile de integritate si operatorii de manipulare a datelor.

Structurile de date . Structurile sunt definite de un limbaj de definire a datelor. Datele in modelul relational sunt structurate in relatii bidimensionale. Elementele principale ale structurii relationale sunt relatiile, tuplurile, atributele, domeniile.

Constrangerile de integritate. Prin integritatea datelor se subintelege ca datele raman stabile, in siguranta si corecte. Integritatea in modelul relational este mentinuta de constrangeri interne care nu sunt cunoscute utilizatorului.

Manipularea datelor. Relatiile pot fi manipulate utilizand un limbaj de manipulare a datelor . In modelul relational, limbajul foloseste operatorii relationali bazati pe conceptul algebrei relationale. In afara de aceasta, exista limbaje echivalente algebrei relationale , cum ar fi calculul relational orientat pe tuplu si calculul relational orientat pe domeniu.

CSS

CSS (Cascading Style Sheets) este un standard pentru formatarea elementelor unui document HTML. Stilurile se pot atașa elementelor HTML prin intermediul unor fișiere externe sau în cadrul documentului, prin elementul <style> și/sau atributul style. CSS se poate utiliza și pentru formatarea elementelor XHTML, XML și SVGL.

ASP.NET

ASP.NET este o tehnologie Microsoft pentru crearea de aplicații web și servicii web. ASP.NET este succesorul lui ASP (Active Server Pages) și beneficiază de puterea platformei de dezvoltare .NET, și de setul de instrumente oferite de mediul de dezvoltarea al aplicației „Visual Studio .NET”.

Unele dintre avantajele ASP .NET sunt:

ASP .NET are un set larg de componente, bazate pe XML, oferind astfel un model de programare orientat obiect (OOP).

ASP .NET ruleaza cod compilat, ceea ce crește performanțele aplictiei web. Codul sursa poate fi separat în două fișiere, unul pentru codul executabil, iar un altul pentru continutul paginii (codul HTML și textul din pagină) .

.NET este compatibil cu peste 20 de limbaje diferite, cele mai utilizate fiind C# si Visual Basic.

Jquery

jQuery este o librărie Javascript ce simplifică managementul unui document HTML : navigarea, eveniment handling, animațiile, interacții Ajax pentru web development etc. Ținta acestei librării este de a schimba (în bine) modul cum Javascript-ul interacționează și își lasă amprenta asupra muncii noastre. Nu e nimic de comentat când putem spune, că aceleași efecte le obținem cu javascript, însă probabil va dura “puțin” pentru a face o implementare de acel gen.
În spatele acestei platforme lucrează o armată de oameni, extrem de bine pregătiți, asigurându-ne regulat îmbunătățirea acestei tehnologii extrem de vitale, aș putea spune eu. Lor trebuie să le mulțumim când facem ceva în jQuery.

Un exemplu de cod jQuery

Cod:     
 jQuery(document).ready(function() {
    jQuery("#exempluj").click(function() {
       jQuery("p.test").addClass("postauthor").show("slow");
    });
 });

– See more at: http://www.tutorialeonline.net/ro/article/despre-jquery-introducere#sthash.akPaqXar.dpuf

Razor

Razor este o sintaxa de programare in ASP.NET care este folosita pentru a crea pagini web dinamice cu ajutorul limbajelor de programare C# sau Visual Basic .NET . Aceasta sintaxa a fost scoasa odata cu ASP.NET MVC 3 si Microsoft WebMatrix.

Diagrama Use case

Nici un program nu este izolat, el interacționând cu oameni sau cu alte sisteme pentru îndeplinirea unui scop.

O diagramă Use Case este una din diagramele folosite în UML pentru a modela aspectele dinamice ale unui program alături de diagrama de activități, diagrama de stări, diagrama de secvență și diagrama de colaborare.

Elementele componente ale unei diagrame use case sunt:

use case-uri

actori

relațiile care se stabilesc între use case-uri, între actori și între use case-uri și actori.

Use case-uri

Un use case (caz de utilizare) reprezintă cerințe ale utilizatorilor. Este o descriere a unei mulțimi de secvențe de acțiuni (incluzând variante) pe care un program le execută atunci când interacționează cu entitățile din afara lui (actori) și care conduc la obținerea unui rezultat observabil și de folos actorului. Un use case descrie ce face un program sau subprogram, dar nu precizează nimic despre cum este realizată (implementată) o anumită funcționalitate.

Fiecare use case are un nume prin care se deosebește de celelalte use case-uri. Acesta poate fi un șir arbitrar de caractere, însă de regulă numele sunt scurte fraze verbale care denumesc un comportament ce există în vocabularul sistemului ce trebuie modelat.urmatoare prezintă notația grafică pentru use case.

Comportamentul unui use case poate fi specificat descriind un flux de evenimente într-un text suficient de clar ca să poată fi înțeles de cineva din exterior (de exemplu utilizatorul). Acest flux de evenimente trebuie să includă cum începe și se termină use case-ul atunci când acesta interacționează cu actori, ce obiecte sunt interschimbate, precum și fluxuri alternative ale acestui comportament. Aceste fluxuri de evenimente reprezintă scenarii posibile de utilizare a sistemului.

Identificarea use case-urilor se face pornind de la cerințele utilizatorului și analizând descrierea problemei.

Actori

Un actor reprezintă idealizarea unei peroane, proces sau obiect exterior care interacționează cu un sistem, subsistem sau o clasă. Actorii sunt entități exterioare sistemului. Ei pot fi utilizatori (persoane), echipamente hardware sau alte programe. Fiecare actor are un nume care indică rolul pe care acesta îl joacă în interacțiunea cu programul.

Notația grafică pentru un actor este ilustrată în figura urmatoare.

Există două moduri în care actorii pot interacționa cu un sistem:

folosind sistemul, adică inițiază execuția unor use case-uri;

sunt folosiți de către sistem, adică oferă funcționalitate pentru realizarea unor use case-uri.

Fiecare actor trebuie să comunice cu cel puțin un use case.

Relații

După cum am mai precizat, relațiile exprimă interacțiuni între use case-uri, între actori și între use case-uri și actori. Relațiile pot fi de mai multe tipuri: asociere, dependență și generalizare.

Relația de asociere se definește între actori și use case-uri, sau între use case-uri. Este folosită pentru a exprima interacțiunea (comunicarea) între elementele pe care le unește.

Relația de dependență se poate stabili numai între use case-uri. Acest tip de relație modelează două situații:

cazul în care un use case folosește funcționalitatea oferită de un alt use case – dependența de tip include;

există variante ale aceluiași use case – dependența de tip extend.

Relația de generalizare se stabilește între elemente de același tip (doi actori, sau doua use case-uri). Este similară relației de generalizare (moștenire) care se stabilește între clase.

Aplicatia guitarstore

Crearea unui nou proiect ASP.NET MVC 3

Vom începe prin selectarea optiunii New Project, din meniul File în Visual Web Developer.

Vom selecta din tabelul stang Visual C# -> Web Templates, iar din tabelul central ASP.NET MVC 3 Web Application si vom numi proiectul GuitarStore. Apoi apasam butonul OK.

Un dialog secundar va aparea care ne va permite selectarea anumitor setări specifice MVC pentru proiectul nostru. Selectați următoarele:

Project Template – selectati Empty

View Engine – selectati Razor

Use HTML5 semantic markup – bifat

Verificati setarile pentru a corespunde cu setarile din imaginea de mai jos si apasati butonul OK.

ASP.NET MVC foloseste aceste foldere cu un anumit scop:

Adăugarea unui HomeController

Vom începe aplicatia GuitarStore prin adăugarea unei clase HomeController care se va ocupa de pagina de start a site-ului nostru. Vom urma implicit conventiile de nume ASP.NET MVC și numesc HomeController.

Faceți clic dreapta pe folderul "Controllers" în Solution Explorer și selectați "Controller …"", iar apoi comanda "Add”:

In urmatoarea fereastra vom numi controller-ul "HomeController" și vom apasa butonul Add.

In acest fel va arata HomeController.cs :

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;

namespace GuitarStore.Controllers

{

public class HomeController : Controller

{

public ActionResult Index()

{

return View();

}

}

}

Pentru a începe cât mai simplu posibil vom folosi o metoda index care returnează doar un șir. Vom face două modificări:

Schimbați metoda pentru a returna un șir în loc de ActionResult

Schimba declarația de returnare pentru a afisa "Hello from Home"

Metoda ar trebui sa arate acest lucru:

public string Index()

{

return "Hello from Home";

}

Rularea aplicației

Acum, haideți să rulam site-ul. Putem începe web-server-ul folosind oricare dintre următoarele metode:

Alegeți Debug ⇨ Start Debugging element de meniu

Faceți clic pe butonul săgeată verde din bara de instrumente

Folosiți scurtătura de la tastatură, F5.

Folosind oricare dintre pașii de mai sus proiectul se va compila , iar apoi va determina serverul de Dezvoltare ASP.NET construit in Visual Web Developer pentru a începe. O notificare va apărea în colțul de jos al ecranului pentru a indica faptul că serverul de Dezvoltare ASP.NET a pornit si va afișa numărul portului care se execută.

Apoi Visual Web Developer va deschide automat o fereastră de browser cu URL-ul indicand spre web-server. Acest lucru ne va permite să încercam rapid aplicația noastră web:

Adăugarea unui StoreController

Am adaugat un HomeController simplu care implementează pagina de pornire a site-ului nostru. Să se adauge acum un alt operator pe care il vom folosi pentru a implementa funcționalitatea de navigare din GuitarStore (magazinul de chitare). Controlerul magazinul nostru va sprijini trei scenarii:

O pagina de listare a marcilor de chitare din magazin

O pagina care listează toate chitarele cu o anume marca

O pagina de detalii care afișează informații despre un chitara selectata

Opriți rularea aplicației fie prin închiderea browser-ului sau selectarea Debug ⇨ Stop Debugging .

La fel cum am făcut cu HomeController, vom face acest lucru făcând clic dreapta pe folderul "Controllers" în Solution Explorer si vom alege Add-> Controler elementul de meniu

StoreController-ul are deja o metodă de "index". Vom folosi aceasta metoda "index" pentru a implementa pagina noastră care listează toate marcile din magazinul de chitare. Vom adăuga, de asemenea, două metode suplimentare pentru a implementa celelalte două scenarii: Browse și Details.

Aceste metode  (Index, Browse and Details) din Controller sunt numite “Controller Actions” iar scopul lor este de a răspunde la cererile URL și de a determina ce conținut ar trebui să fie trimis înapoi la browser-ul sau utilizatorul care a invocat URL-ul.

Vom începe implementarea StoreController-ului prin schimbarea Index () , metoda prin care se intoarce șirul "Hello din Store.Index ()" :

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;

namespace GuitarStore.Controllers

{

public class StoreController : Controller

{

public string Index()

{

return "Hello from Store.Index()";

}

public string Browse()

{

return "Hello from Store.Browse()";

}

public string Details()

{

return "Hello from Store.Details()";

}

}

}

Rulati proiectul si folositi urmatoarele URL-uri:

/Store

/Store/Browse

/Store/Details

Accessing these URLs will invoke the action methods within our Controller and return string responses:

public string Browse(string marca)

{

string message = HttpUtility.HtmlEncode("Store.Browse, Marca = "

+ marca);

return message;

}

public string Details(int id)

{

string message = "Store.Details, ID = " + id;

return message;

}

Rulati aplicatia /Store/Details/5:

Adăugarea unui View Template

Pentru a utiliza o imagine-șablon(view-template), vom schimba metoda de index HomeController ca in

Imaginea de mai jos:

public class HomeController : Controller

{

public ActionResult Index()

{

return View();

}

}

Schimbare de mai sus indică faptul că, în locul afisarii sirului vom utiliza "View" pentru a genera un rezultat înapoi.

Vom adăuga un șablon View adecvat pentru proiect. Pentru a face acest lucru, vom pozitiona cursorul cadrul metodei Index, apoi clic dreapta și selectam "Add View". Acest lucru va aduce dialogul Add View:

Fereastra "Add View" ne permite rapid și ușor sa generam fisiere  View template. În mod implicit " Add View " pre-populează numele șablonului View pentru a crea o metoda care sa se potrivească cu metoda de acțiune pe care o va utiliza. 

Numele si locatia fisierului “Index.cshtml” este importanta si foloseste conventiile de nume default ASP.NET MVC.

public class HomeController : Controller

{

public ActionResult Index()

{

return View();

}

}

Visual Web Developer a creat si deschis “Index.cshtml” dupa ce am apasat butonul “Add” din fereastra “Add View”. Continutul fisierului Index.cshtml este:

@{

ViewBag.Title = "Index";

}

<h2>This is the Home Page</h2>

Elementele comune ale aspectului site-ului

Cele mai multe site-uri au conținut care este partajat între mai multe pagini: navigation, footers, logo images, stylesheet references, etc.  Razor face acest lucru folosind pagina numita _Layout care a fost creata automat in fisierul /Views/Shared folder.

Acesta este continutul fisierului:

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8" />

<title>@ViewBag.Title</title>

<link href="@Url.Content("~/Content/Site.css")"

rel="stylesheet" type="text/css" />

<script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")"

type="text/javascript"></script>

<script src="@Url.Content("~/Scripts/modernizr-1.7.min.js")"

type="text/javascript"></script>

</head>

<body>

@RenderBody()

</body>

</html>

<!DOCTYPE html>

<html>

<head>

<title>@ViewBag.Title</title>

<link href="@Url.Content("~/Content/Site.css")"

rel="stylesheet" type="text/css" />

<script src="@Url.Content("~/Scripts/jquery-1.4.4.min.js")"

type="text/javascript"></script>

</head>

<body>

<div id="header">

<h1>

GUITAR STORE</h1>

<ul id="navlist">

<li class="first"><a href="/"

id="current">Home</a></li>

<li><a

href="/Store/">Store</a></li>

</ul>

</div>

@RenderBody()

</body>

</html>

Folosind un Model pentru a trece informatia catre un View

Prima data vom crea clase Model care sa reprezinte marcile si chitarele din magazin. Vom incepe prin creerea unui model Marca (Marca.cs):

public class Marca

{

public string Name { get; set; }

}

Apoi vom crea o clasa chitara

public class chitara

{

public string Title { get; set; }

public Marca Marca { get; set; }

}

Vom modifica clasa StoreControllers pentru a include GuitarStore.Models

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;

using GuitarStore.Models;

public ActionResult Details(int id)

public ActionResult Details(int id)

{

var chitara = new Chitara { Title = "Chitara " + id };

return View(chitara);

}

Vom crea un nou View template cum am facut mai sus cu HomeController-ul. Pentru ca il vom crea

din StoreController el va fi generat in acest fisier \Views\Store\Index.cshtml.

Spre deosebire de ce am facut data trecuta vom bifa ”Create a strongly-typed” view. Vom selecta clasa ”Chitara” . Cand vom apasa butonul “Add” un sablon view va fi creat \Views\Store\Details.cshtml :

@model Guitar.Models.Chitara

@{

ViewBag.Title = "Details";

}

<h2>Details</h2>

Vom face o modificare mai complexa la Store Index pentru a afisa o lista cu toate marcile de chitara din magazin.

public ActionResult Index()

{

var marci = new List<Marca>

{

new Marca { Name = "Fender"},

new Marca { Name = "Ibanez"},

new Marca { Name = "Jackson"}

};

return View(marci);

}

Click dreapta pe Store index si selecteza add view folosind Marca ca o clasa Model .

Vom modifica prima linie din /Store/Index.cshtml in acest mod:

@model IEnumerable<Guitar.Models.Marca>

.

@model IEnumerable<GuitarStore.Models.Marca>

@{

ViewBag.Title = "Store";

}

<h3>Browse Marci</h3>

<p>

Select from @Model.Count()

marci:</p>

<ul>

@foreach (var marca in Model)

{

<li>@marca.Name</li>

}

</ul>

Legaturile dintre pagini

Modificam \Views\Store\Index.cshtml ca in imaginea de mai jos

<ul>

@foreach (var marca in Model)

{

<li><a href="/Store/Browse?marca=@marca.Name">@marca.Name</a></li>

}

</ul>

“Go to the Store Index” folosind :

@Html.ActionLink("Go

to the Store Index", "Index")

Vizualizarea Store Index –ului :

<ul>

@foreach (var marca in Model)

{

<li>@Html.ActionLink(marca.Name,

"Browse", new { marca = marca.Name })</li>

}

</ul>

Accesul la baza de date cu Entity Framework Code-First

Vom folosi suportul Entity Framework (EF) care este inclus în proiectele ASP.NET MVC 3 pentru a interoga și actualiza baza de date. 

Modificarile claselor Model

Adaugarea clasei Model Chitara

Vom adauga o noua clasa la fisierul Models numita Chitara.cs folosind codul de mai jos :

namespace GuitarStore.Models

{

public class Chitara

{

public int ChitaraId { get; set; }

public string Name { get; set; }

}

}

Modificam clasele Model

namespace GuitarStore.Models

{

public class Chitara

{

public int Chitara Id { get; set;

}

public int MarcaId { get; set; }

public int ChitaraId { get; set; }

public string Title { get; set; }

public decimal Price { get; set; }

public string ChitaraArtUrl { get; set; }

public Chitara Chitara { get; set; }

public Gen Gen { get; set; }

}

}

Apoi vom face urmatoarele modificari la clasa Marca:

using System.Collections.Generic;

namespace GuitarStore.Models

{

public partial class Marca

{

public int MarcaId { get; set; }

public string Name { get; set; }

public string Description { get; set; }

public List< Chitara> Chitare { get; set; }

}

}

Adaugarea fisierului App_Data

Vom adăuga un director App_Data pentru a organiza baza de date SQL Express. App_Data este un director special în ASP.NET care are deja corecte permisiunile de acces la baza de date. Din meniul Project, selectați Add ASP.NET folder, apoi App_Data.

Modificam fisierul web.config

Modificam Web.config in acest mod:

<connectionStrings>

<add name="GuitarStoreEntities"

connectionString="Data Source=|DataDirectory|GuitarStore.sdf"

providerName="System.Data.SqlServerCe.4.0"/>

</connectionStrings>

</configuration>

Adaugarea unei clase Context

In fisierul Models vom crea o noua clasa MusicStoreEntities.cs.

using System.Data.Entity;

namespace GuitarStore.Models

{

public class GuitarStoreEntities : DbContext

{

public DbSet<Chitara> Chitare { get; set; }

public DbSet<Marca> Marci { get; set; }

}

}

Adaugarea unei baze de date

Datele se afla in fisierul sampledata.cs din directorul Models

protected void Application_Start()

{

System.Data.Entity.Database.SetInitializer(

new GuitarStore.Models.SampleData());

AreaRegistration.RegisterAllAreas();

RegisterGlobalFilters(GlobalFilters.Filters);

RegisterRoutes(RouteTable.Routes);

}

Interogarea bazei de date

Modificam StoreController-ul :

public class StoreController : Controller

{

GuitarStoreEntities storeDB = new GuitarStoreEntities();

Actualizarea Index-ului Store

public ActionResult Index()

{

var marci = storeDB.Marci.ToList();

return View(marci);

}

Actualizarea Store Browse si Details

public ActionResult Browse(string marci)

{

// Intoarce marca si chitarile asociate marcii din baza de

var marcaModel = storeDB.Marci.Include("Chitare")

.Single(g => g.Name == marca);

return View(marcaModel);

}

Modificari /Views/Store/Browse.cshtml

@model GuitarStore.Models.Marca

@{

ViewBag.Title = "Browse";

}

<h2>Browsing Marca: @Model.Name</h2>

<ul>

@foreach (var chitara in Model.Chitare)

{

<li>

@chitara.Title

</li>

}

</ul>

Browse

@model GuitarStore.Models.Marca

@{

ViewBag.Title = "Browse";

}

<h2>Browsing Marca: @Model.Name</h2>

<ul>

@foreach (var chitara in Model.Chitare)

{

<li>

@Html.ActionLink(chitara.Title,

"Details", new { id = chitara.ChitaraId })

</li>

}

</ul>

Crearea controller-ului StoreManagerController

Vom incepe prin crearea controller-ului StoreManagerController. (Controller cu read /write actions , views using EF ) (model class: Chitara (GuitarStore.Models) ).

Scaffolded View

StoreManager Index view (/Views/StoreManager/Index.cshtml

<table>

<tr>

<th>

Marca

</th>

<th>

Chitara

</th>

<th>

Title

</th>

<th>

Price

</th>

<th>

ChitaraArtUrl

</th>

<th></th>

</tr>

@foreach (var item in Model) {

<tr>

<td>

@Html.DisplayFor(modelItem => item.Marca.Name)

</td>

<td>

@Html.DisplayFor(modelItem => item.Chitara.Name)

</td>

<td>

@Html.DisplayFor(modelItem => item.Title)

</td>

<td>

@Html.DisplayFor(modelItem => item.Price)

</td>

<td>

@Html.DisplayFor(modelItem => item. ChitaraArtUrl)

</td>

<td>

@Html.ActionLink("Edit", "Edit", new { id=item. ChitaraId }) |

@Html.ActionLink("Details", "Details", new { id=item. ChitaraId }) |

@Html.ActionLink("Delete", "Delete", new { id=item. ChitaraId })

</td>

</tr>

}

</table>

@model IEnumerable<GuitarStore.Models.Guitar>

@{

ViewBag.Title = "Index";

}

<h2>Index</h2>

<p>

@Html.ActionLink("Create

New", "Create")

</p>

<table>

<tr>

<th>

Marca

</th>

<th>

Gen

</th>

<th>

Title

</th>

<th>

Price

</th>

<th></th>

</tr>

@foreach (var item in Model) {

<tr>

<td>

@Html.DisplayFor(modelItem => item.Marca.Name)

</td>

<td>

@Html.DisplayFor(modelItem => item.Gen.Name)

</td>

<td>

@Html.DisplayFor(modelItem => item.Title)

</td>

<td>

@Html.DisplayFor(modelItem => item.Price)

</td>

<td>

@Html.ActionLink("Edit", "Edit", new { id=item.ChitaraId }) |

@Html.ActionLink("Details", "Details", new { id=item.ChitaraId }) |

@Html.ActionLink("Delete", "Delete", new { id=item.ChitaraId })

</td>

</tr>

}

</table>

Store Manager

Rulati aplicatia si deshideti la /StoreManager unde vom avea legaturile Edit, Details si Delete.

Codul controller-ului Store Manager

using System;

using System.Collections.Generic;

using System.Data;

using System.Data.Entity;

using System.Linq;

using System.Web;

using System.Web.Mvc;

using GuitarStore.Models;

namespace GuitarStore.Controllers

{

public class StoreManagerController : Controller

{

private GuitarStoreEntities db = new GuitarStoreEntities();

Index-ul Store Manager

public ViewResult Index()

{

var chitare = db.Chitare.Include(a => a.Marca).Include(a => a.Gen);

return View(chitare.ToList());

}

StoreManager Controller’s Details controller action

public ViewResult Details(int id)

{

Chitara chitara = db.Chitare.Find(id);

return View(chitara);

}

Manevrarea valorilor Posted Form

[HttpPost]

public ActionResult Create(Chitara chitara)

{

if (ModelState.IsValid)

{

db.Chitare.Add(chitara);

db.SaveChanges();

return RedirectToAction("Index");

}

ViewBag.MarcaId = new SelectList(db.Marci, "MarcaId",

"Name", chitara.MarcaId);

ViewBag.GenId = new SelectList(db.Genuri, "GenId",

"Name", chitara.GenId);

return View(chitara);

}

Aceasta actiune are 4 responsabilități:

1. Citirea valorilor

2. Verificarea valorilor

3. In cazul in care valorile sunt valabile ele sunt salvate , iar lista se va afisa

4. In cazul in care valorile nu sunt valabile se vor afisa erorile

Manevrarea Edit-ului

public ActionResult Edit(int id)

{

Chitara chitara = db.Chitare.Find(id);

ViewBag.MarcaId = new SelectList(db.Marci, "MarcaId",

"Name", chitara.MarcaId);

ViewBag.GenId = new SelectList(db.Genuri, "GenuriId",

"Name", chitara.GenId);

return View(chitara);

}

Afisare :/storemanager/edit

[HttpPost]

public ActionResult Edit(Chitara chitara)

{

if (ModelState.IsValid)

{

db.Entry(chitara).State = EntityState.Modified;

db.SaveChanges();

return RedirectToAction("Index");

}

ViewBag.MarcaId = new SelectList(db.Marci, "MarcaId",

"Name", chitara.MarcaId);

ViewBag.GenId = new SelectList(db.Genuri, "GenId",

"Name", chitara.GenId);

return View(chitara);

}

Manevrarea Delete-ului

public ActionResult Delete(int id)

{

Chitara chitara = db.Chitare.Find(id);

return View(chitara);

}

Vom modifica /Views/StoreManager/Delete.cshtml dupa cum urmeaza mai jos:

@model GuitarStore.Models.Chitara

@{

ViewBag.Title = "Delete";

}

<h2>Delete Confirmation</h2>

<p>Are you sure you want to delete the guitar

<strong>@Model.Title</strong>?

</p>

@using (Html.BeginForm()) {

<p>

<input type="submit" value="Delete" />

</p>

<p>

@Html.ActionLink("Back to

List", "Index")

</p>

}

[HttpPost, ActionName("Delete")]

public ActionResult DeleteConfirmed(int id)

{

Chitara chitara = db.Chitare.Find(id);

db. Chitare.Remove(chitara);

db.SaveChanges();

return RedirectToAction("Index");

}

Delete Controller Action:

1. Incarca Chitara dupa ID

2. Sterge Chitara si salveaza modificarile

3. Redirectioneaza catre index , aratand ca acea chitara a fost stearsa din lista.

Alte actualizari

Adaugarea validarilor la formulare

Vom folosi urmtoarele date:

Required – indica ca aceasta proprietate este

DisplayName – defineste textul pe care il vom folosi pe campurile de formular si mesajele de validare

StringLength – Definește lungimea maximă pentru un câmp

Range – Oferă o valoare maximă și minimă pentru un câmp numeric

Bind – Listeaza campuri care sunt excluse sau incluse atunci cand legam valoarea parametrilor sau valoarea formularului de propietatile modelului

ScaffoldColumn – Permite ascunderea câmpurilor

using System.ComponentModel;

using System.ComponentModel.DataAnnotations;

using System.Web.Mvc;

namespace GuitarStore.Models

{

[Bind(Exclude = "ChitaraId")]

public class Chitara

{

[ScaffoldColumn(false)]

public int ChitaraId { get; set; }

[DisplayName("Marca")]

public int MarcaId { get; set; }

[DisplayName("Gen")]

public int GenId { get; set; }

[Required(ErrorMessage = "Un nume de chitara este necesar")]

[StringLength(160)]

public string Title { get; set; }

[Required(ErrorMessage = "Introduceti pretul")]

public decimal Price { get; set; }

[DisplayName("Chitara Art URL")]

[StringLength(1024)]

public string ChitaraArtUrl { get; set; }

public virtual Marca Marca { get; set; }

public virtual Gen Gen { get; set; }

}

}

public virtual Marca Marca { get; set; }

public virtual Gen Gen { get; set; }

Adaugarea controller-ului AccountController

Adaugarea unui user Administrator folosind metoda ASP.NET Configuration site

Before we require Authorization in our website, we'll need to create a user with access. The easiest way to create a user is to use the built-in ASP.NET Configuration website.

Lansati ASP.NET Configuration website apasand pe icon-ul din figura de mai jos :

Apasati butonul enable roles de la Security.

Apasati "Create or Manage roles"

Scrieti "Administrator" si dati click butonului Add Role

Click Back button, apoi click Create.

Role-based Authorization

Acum putem restrictiona accesul la controller-ul StoreManagerController folosind atributul [Authorize] attribute:

[Authorize(Roles = "Administrator")]

public class StoreManagerController : Controller

{

// Controller

}

Adaugarea claselor model Cart, Order si OrderDetail

Right-click pe folderul Models si vom adauga clasa (Cart.cs) with the following code.

using System.ComponentModel.DataAnnotations;

namespace GuitarStore.Models

{

public class Cart

{

[Key]

public int RecordId { get; set; }

public string CartId { get; set; }

public int ChitaraId { get; set; }

public int Count { get; set; }

public System.DateTime DateCreated { get; set; }

public virtual Chitara Chitara { get; set; }

}

}

Order class (Order.cs)

using System.Collections.Generic;

namespace GuitarStore.Models

{

public partial class Order

{

public int OrderId { get; set; }

public string Username { get; set; }

public string FirstName { get; set; }

public string LastName { get; set; }

public string Address { get; set; }

public string City { get; set; }

public string State { get; set; }

public string PostalCode { get; set; }

public string Country { get; set; }

public string Phone { get; set; }

public string Email { get; set; }

public decimal Total { get; set; }

public System.DateTime OrderDate { get; set; }

public List<OrderDetail> OrderDetails { get; set; }

}

}

OrderDetail.cs

namespace GuitarStore.Models

{

public class OrderDetail

{

public int OrderDetailId { get; set; }

public int OrderId { get; set; }

public int ChitaraId { get; set; }

public int Quantity { get; set; }

public decimal UnitPrice { get; set; }

public virtual Chitara Chitara { get; set; }

public virtual Order Order { get; set; }

}

}

Clasa MusicStoreEntities modificari

using System.Data.Entity;

namespace GuitarStore.Models

{

public class GuitarStoreEntities : DbContext

{

public DbSet<Chitara> Chitare { get; set; }

public DbSet<Marca> Marci { get; set; }

public DbSet<Gen> Genuri {

get; set; }

public DbSet<Cart>

Carts { get; set; }

public DbSet<Order> Orders

{ get; set; }

public DbSet<OrderDetail>

OrderDetails { get; set; }

}

}

Menajarea cosului de cumparaturi Shopping Cart business logic

The ShoppingCart class exposes the following methods:

AddToCart ia o Chitara ca parametru si o adauga in cosul user-ului (user’s cart)

RemoveFromCart ia Idul de la Chitara si o sterge din cosul user-ului 

EmptyCart sterge toate produsele din cos

GetCartItems  intoarce o listă de CartItems pentru afișare sau de prelucrare

GetCount intoarce nr total de chitare pe care un user il are in cos

GetTotal calculeaza pretul total la produselor

CreateOrder transforma cosul de cumparaturi( shopping cart) la un ordin( order) in timpul checkout-ului

GetCart   este o metoda statica care da voie controllerului sa obtina un obiect al cartului

Aceasta este clasa ShoppingCart :

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;

namespace GuitarStore.Models

{

public partial class ShoppingCart

{

GuitarStoreEntities storeDB = new GuitarStoreEntities ();

string ShoppingCartId { get; set; }

public const string CartSessionKey = "CartId";

public static ShoppingCart GetCart(HttpContextBase context)

{

var cart = new ShoppingCart();

cart.ShoppingCartId = cart.GetCartId(context);

return cart;

}

public static ShoppingCart GetCart(Controller controller)

{

return GetCart(controller.HttpContext);

}

public void AddToCart(Chitara chitara)

{

var cartItem = storeDB.Carts.SingleOrDefault(

c => c.CartId == ShoppingCartId

&& c.ChitaraId == chitara.ChitaraId);

if (cartItem == null)

{

cartItem = new Cart

{

ChitaraId = chitara.ChitaraId,

CartId = ShoppingCartId,

Count = 1,

DateCreated = DateTime.Now

};

storeDB.Carts.Add(cartItem);

}

else

{

cartItem.Count++;

}

storeDB.SaveChanges();

}

public int RemoveFromCart(int id)

{

var cartItem = storeDB.Carts.Single(

cart => cart.CartId == ShoppingCartId

&& cart.RecordId == id);

int itemCount = 0;

if (cartItem != null)

{

if (cartItem.Count > 1)

{

cartItem.Count–;

itemCount = cartItem.Count;

}

else

{

storeDB.Carts.Remove(cartItem);

}

storeDB.SaveChanges();

}

return itemCount;

}

public void EmptyCart()

{

var cartItems = storeDB.Carts.Where(

cart => cart.CartId == ShoppingCartId);

foreach (var cartItem in cartItems)

{

storeDB.Carts.Remove(cartItem);

}

storeDB.SaveChanges();

}

public List<Cart> GetCartItems()

{

return storeDB.Carts.Where(

cart => cart.CartId == ShoppingCartId).ToList();

}

public int GetCount()

{

int? count = (from cartItems in storeDB.Carts

where cartItems.CartId == ShoppingCartId

select (int?)cartItems.Count).Sum();

return count ?? 0;

}

public decimal GetTotal()

{

decimal? total = (from cartItems in storeDB.Carts

where cartItems.CartId == ShoppingCartId

select (int?)cartItems.Count *

cartItems.Chitara.Price).Sum();

return total ?? decimal.Zero;

}

public int CreateOrder(Order order)

{

decimal orderTotal = 0;

var cartItems = GetCartItems();

foreach (var item in cartItems)

{

var orderDetail = new OrderDetail

{

ChitaraId = item.ChitaraId,

OrderId = order.OrderId,

UnitPrice = item.Chitara.Price,

Quantity = item.Count

};

orderTotal += (item.Count * item.Chitara.Price);

storeDB.OrderDetails.Add(orderDetail);

}

order.Total = orderTotal;

storeDB.SaveChanges();

EmptyCart();

return order.OrderId;

}

public string GetCartId(HttpContextBase context)

{

if (context.Session[CartSessionKey] == null)

{

if (!string.IsNullOrWhiteSpace(context.User.Identity.Name))

{

context.Session[CartSessionKey] =

context.User.Identity.Name;

}

else

{

Guid tempCartId = Guid.NewGuid();

context.Session[CartSessionKey] = tempCartId.ToString();

}

}

return context.Session[CartSessionKey].ToString();

}

public void MigrateCart(string userName)

{

var shoppingCart = storeDB.Carts.Where(

c => c.CartId == ShoppingCartId);

foreach (Cart item in shoppingCart)

{

item.CartId = userName;

}

storeDB.SaveChanges();

}

}

}

ViewModels

Controller-ul Shopping Cart

Vom crea un nou controller :

using System.Linq;

using System.Web.Mvc;

using GuitarStore.Models;

using GuitarStore.ViewModels;

namespace GuitarStore.Controllers

{

public class ShoppingCartController : Controller

{

GuitarStoreEntities storeDB = new GuitarStoreEntities();

public ActionResult Index()

{

var cart = ShoppingCart.GetCart(this.HttpContext);

var viewModel = new ShoppingCartViewModel

{

CartItems = cart.GetCartItems(),

CartTotal = cart.GetTotal()

};

return View(viewModel);

}

public ActionResult AddToCart(int id)

{

var addedChitara = storeDB.Chitare

.Single(chitara => chitara.ChitaraId == id);

var cart = ShoppingCart.GetCart(this.HttpContext);

cart.AddToCart(addedChitara);

return RedirectToAction("Index");

}

[HttpPost]

public ActionResult RemoveFromCart(int id)

{

var cart = ShoppingCart.GetCart(this.HttpContext);

string chitaraName = storeDB.Carts

.Single(item => item.RecordId == id).Chitara.Title;

int itemCount = cart.RemoveFromCart(id);

var results = new ShoppingCartRemoveViewModel

{

Message = Server.HtmlEncode(chitaraName) +

" a fost sters din cosul de cumparaturi.",

CartTotal = cart.GetTotal(),

CartCount = cart.GetCount(),

ItemCount = itemCount,

DeleteId = id

};

return Json(results);

}

[ChildActionOnly]

public ActionResult CartSummary()

{

var cart = ShoppingCart.GetCart(this.HttpContext);

ViewData["CartCount"] = cart.GetCount();

return PartialView("CartSummary");

}

}

}

Actualizari Ajax cu jQuery

/ShoppingCart/Index view:

@model GuitarStore.ViewModels.ShoppingCartViewModel

@{

ViewBag.Title = "Shopping Cart";

}

<script src="/Scripts/jquery-1.4.4.min.js"

type="text/javascript"></script>

<script type="text/javascript">

$(function () {

$(".RemoveLink").click(function () {

var recordToDelete = $(this).attr("data-id");

if (recordToDelete != '') {

$.post("/ShoppingCart/RemoveFromCart", {"id": recordToDelete },

function (data) {

if (data.ItemCount == 0) {

$('#row-' + data.DeleteId).fadeOut('slow');

} else {

$('#item-count-' + data.DeleteId).text(data.ItemCount);

}

$('#cart-total').text(data.CartTotal);

$('#update-message').text(data.Message);

$('#cart-status').text('Cart (' + data.CartCount + ')');

});

}

});

});

</script>

<h3>

<em>Review</em> your cart:

</h3>

<p class="button">

@Html.ActionLink("Checkout

>>", "AddressAndPayment", "Checkout")

</p>

<div id="update-message">

</div>

<table>

<tr>

<th>

Chitara

</th>

<th>

Pret (each)

</th>

<th>

Cantitate

</th>

<th></th>

</tr>

@foreach (var item in

Model.CartItems)

{

<tr id="[anonimizat]">

<td>

@Html.ActionLink(item.Chitara.Title,

"Details", "Store", new { id = item.ChitaraId }, null)

</td>

<td>

@item.Chitara.Price

</td>

<td id="[anonimizat]">

@item.Count

</td>

<td>

<a href="#" class="RemoveLink"

data-id="@item.RecordId">Remove

from cart</a>

</td>

</tr>

}

<tr>

<td>

Total

</td>

<td>

</td>

<td>

</td>

<td id="cart-total">

@Model.CartTotal

</td>

</tr>

</table>

Store Details

@model GuitarStore.Models.Chitara

@{

ViewBag.Title = "Chitara – " + Model.Title;

}

<h2>@Model.Title</h2>

<p>

<img alt="@Model.Title"

src="@Model.ChitaraArtUrl" />

</p>

<div id="chitara-details">

<p>

<em>Marca:</em>

@Model.Marca.Name

</p>

<p>

<em>Gen:</em>

@Model.Gen.Name

</p>

<p>

<em>Price:</em>

@String.Format("{0:F}",

Model.Price)

</p>

<p class="button">

@Html.ActionLink("Add to

cart", "AddToCart",

"ShoppingCart", new { id = Model.ChitaraId }, "")

</p>

</div>

Asocierea produselor cu user-ul logat(Migrating the Shopping Cart)

Deshidem clasa  AccountController si adaugam :

private void MigrateShoppingCart(string UserName)

{

// Asociaza produsele din cosul de cumparaturi cu user-ul logat

var cart = ShoppingCart.GetCart(this.HttpContext);

cart.MigrateCart(UserName);

Session[ShoppingCart.CartSessionKey] = UserName;

}

LogOn post action MigrateShoppingCart :

//

// POST: /Account/LogOn

[HttpPost]

public ActionResult LogOn(LogOnModel model, string returnUrl)

{

if (ModelState.IsValid)

{

if (Membership.ValidateUser(model.UserName, model.Password))

{

MigrateShoppingCart(model.UserName);

FormsAuthentication.SetAuthCookie(model.UserName,

model.RememberMe);

if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1

&& returnUrl.StartsWith("/")

&& !returnUrl.StartsWith("//") &&

!returnUrl.StartsWith("/\\"))

{

return Redirect(returnUrl);

}

else

{

return RedirectToAction("Index", "Home");

}

}

else

{

ModelState.AddModelError("", "The user name or password provided is incorrect.");

}

}

return View(model);

}

Actiunea Register /post

//

// POST: /Account/Register

[HttpPost]

public ActionResult Register(RegisterModel model)

{

if (ModelState.IsValid)

{

// Incearca sa inregistreze user-ul

MembershipCreateStatus createStatus;

Membership.CreateUser(model.UserName, model.Password, model.Email,

"question", "answer", true, null, out

createStatus);

if (createStatus == MembershipCreateStatus.Success)

{

MigrateShoppingCart(model.UserName);

FormsAuthentication.SetAuthCookie(model.UserName, false /*

createPersistentCookie */);

return RedirectToAction("Index", "Home");

}

else

{

ModelState.AddModelError("", ErrorCodeToString(createStatus));

}

}

return View(model);

}

Crearea controller-ului CheckoutController

namespace GuitarStore.Controllers

{

[Authorize]

public class CheckoutController : Controller

As in the StoreController, we’ll declare a field to hold an instance of the MusicStoreEntities class, named storeDB. In order to make use of the MusicStoreEntities class, we will need to add a using statement for the MvcMusicStore.Models namespace. The top of our Checkout controller appears below.

using System;

using System.Linq;

using System.Web.Mvc;

using GuitarStore.Models;

namespace GuitarStore.Controllers

{

[Authorize]

public class CheckoutController : Controller

{

GuitarStoreEntities storeDB = new GuitarStoreEntities();

const string PromoCode = "FREE";

AddressAndPayment (GET method)  va afisa o forma care va lasa user-ul sa introduca informatii

AddressAndPayment (POST method)  va valida intrarea si va procesa

Complete  va fi afisat dupa ce user-ul va realiza cu succes procesul checkout

public ActionResult AddressAndPayment()

{

return View();

}

//

// POST: /Checkout/AddressAndPayment

[HttpPost]

public ActionResult AddressAndPayment(FormCollection values)

{

var order = new Order();

TryUpdateModel(order);

try

{

if (string.Equals(values["PromoCode"], PromoCode,

StringComparison.OrdinalIgnoreCase) == false)

{

return View(order);

}

else

{

order.Username = User.Identity.Name;

order.OrderDate = DateTime.Now;

//Salveaza Order

storeDB.Orders.Add(order);

storeDB.SaveChanges();

//Proceseaza order

var cart = ShoppingCart.GetCart(this.HttpContext);

cart.CreateOrder(order);

return RedirectToAction("Complete",

new { id = order.OrderId });

}

}

catch

{

return View(order);

}

}

//

// GET: /Checkout/Complete

public ActionResult Complete(int id)

{

bool isValid = storeDB.Orders.Any(

o => o.OrderId == id &&

o.Username == User.Identity.Name);

if (isValid)

{

return View(id);

}

else

{

return View("Error");

}

}

CheckoutController code is as follows:

using System;

using System.Linq;

using System.Web.Mvc;

using GuitarStore.Models;

namespace GuitarStore.Controllers

{

[Authorize]

public class CheckoutController : Controller

{

GuitarStoreEntities storeDB = new GuitarStoreEntities();

const string PromoCode = "FREE";

//

// GET: /Checkout/AddressAndPayment

public ActionResult AddressAndPayment()

{

return View();

}

//

// POST: /Checkout/AddressAndPayment

[HttpPost]

public ActionResult AddressAndPayment(FormCollection values)

{

var order = new Order();

TryUpdateModel(order);

try

{

if (string.Equals(values["PromoCode"], PromoCode,

StringComparison.OrdinalIgnoreCase) == false)

{

return View(order);

}

else

{

order.Username = User.Identity.Name;

order.OrderDate = DateTime.Now;

//Salveaza Order

storeDB.Orders.Add(order);

storeDB.SaveChanges();

//Proceseaza order

var cart = ShoppingCart.GetCart(this.HttpContext);

cart.CreateOrder(order);

return RedirectToAction("Complete",

new { id = order.OrderId });

}

}

catch

{

return View(order);

}

}

//

// GET: /Checkout/Complete

public ActionResult Complete(int id)

{

bool isValid = storeDB.Orders.Any(

o => o.OrderId == id &&

o.Username == User.Identity.Name);

if (isValid)

{

return View(id);

}

else

{

return View("Error");

}

}

}

}

Adaugarea AddressAndPayment view

AddressAndPayment view

@model GuitarStore.Models.Order

@{

ViewBag.Title = "Address And Payment";

}

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")"

type="text/javascript"></script>

<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")"

type="text/javascript"></script>

@using (Html.BeginForm()) {

<h2>Address And Payment</h2>

<fieldset>

<legend>Shipping Information</legend>

@Html.EditorForModel()

</fieldset>

<fieldset>

<legend>Payment</legend>

<p>We're running a promotion: all music is free

with the promo code: "FREE"</p>

<div class="editor-label">

@Html.Label("Promo Code")

</div>

<div class="editor-field">

@Html.TextBox("PromoCode")

</div>

</fieldset>

<input type="submit" value="Submit Order" />

}

Regulile definite ale validarii Clasei Order

using System.Collections.Generic;

using System.ComponentModel;

using System.ComponentModel.DataAnnotations;

using System.Web.Mvc;

namespace GuitarStore.Models

{

[Bind(Exclude = "OrderId")]

public partial class Order

{

[ScaffoldColumn(false)]

public int OrderId { get; set; }

[ScaffoldColumn(false)]

public System.DateTime OrderDate { get; set; }

[ScaffoldColumn(false)]

public string Username { get; set; }

[Required(ErrorMessage = "First Name is required")]

[DisplayName("First Name")]

[StringLength(160)]

public string FirstName { get; set; }

[Required(ErrorMessage = "Last Name is required")]

[DisplayName("Last Name")]

[StringLength(160)]

public string LastName { get; set; }

[Required(ErrorMessage = "Address is required")]

[StringLength(70)]

public string Address { get; set; }

[Required(ErrorMessage = "City is required")]

[StringLength(40)]

public string City { get; set; }

[Required(ErrorMessage = "State is required")]

[StringLength(40)]

public string State { get; set; }

[Required(ErrorMessage = "Postal Code is required")]

[DisplayName("Postal Code")]

[StringLength(10)]

public string PostalCode { get; set; }

[Required(ErrorMessage = "Country is required")]

[StringLength(40)]

public string Country { get; set; }

[Required(ErrorMessage = "Phone is required")]

[StringLength(24)]

public string Phone { get; set; }

[Required(ErrorMessage = "Email Address is required")]

[DisplayName("Email Address")]

[RegularExpression(@"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}",

ErrorMessage = "Email is is not valid.")]

[DataType(DataType.EmailAddress)]

public string Email { get; set; }

[ScaffoldColumn(false)]

public decimal Total { get; set; }

public List<OrderDetail> OrderDetails { get; set; }

}

}

Adaugarea completa Checkout view

Order Id view

@model int

@{

ViewBag.Title = "Checkout Complete";

}

<h2>Checkout Complete</h2>

<p>Thanks for your order! Your order number is: @Model</p>

<p>How about shopping for some more music in our

@Html.ActionLink("store",

"Index", "Home")

</p>

Actualizarea Error view

@{

ViewBag.Title = "Error";

}

<h2>Error</h2>

<p>We're sorry, we've hit an unexpected error.

<a href="javascript:history.go(-1)">Click here</a>

if you'd like to go back and try that again.</p>

Crearea partiala a Shopping Cart-ului

[ChildActionOnly]

public ActionResult CartSummary()

{

var cart = ShoppingCart.GetCart(this.HttpContext);

ViewData["CartCount"] = cart.GetCount();

return PartialView("CartSummary");

}

In Views/ShoppingCart folder selecteaza Add View. Numeste CartSummary si bifeaza “Create a partial view”.

CartSummary.cshtml

@Html.ActionLink("Cart

(" + ViewData["CartCount"] + ")",

"Index",

"ShoppingCart",

new { id = "cart-status" })

Crearea partiala a meniului Marca

//

// GET: /Store/MarcaMenu

[ChildActionOnly]

public ActionResult MarcaMenu()

{

var marci = storeDB.Marci.ToList();

return PartialView(marci);

}

[ChildActionOnly] e un atribut care indica ca vrem ca aceasta actiune sa fie folosita doar ca un View partial

@model IEnumerable<GuitarStore.Models.Marca>

<ul id="categories">

@foreach (var marca in Model)

{

<li>@Html.ActionLink(marca.Name,

"Browse", "Store",

new { Marca = marca.Name }, null)

</li>

}

</ul>

Actualizam Site Layout-ul pentru a afisa Partial Views

(/Views/Shared/_Layout.cshtml)

<!DOCTYPE html>

<html>

<head>

<title>@ViewBag.Title</title>

<link href="@Url.Content("~/Content/Site.css")"

rel="stylesheet"

type="text/css" />

<script src="@Url.Content("~/Scripts/jquery-1.4.4.min.js")"

type="text/javascript"></script>

</head>

<body>

<div id="header">

<h1><a href="/">GUITARSTORE</a></h1>

<ul id="navlist">

<li class="first">

<a href="@Url.Content("~")" id="current">

Home</a></li>

<li><a href="@Url.Content("~/Store/")">Store</a></li>

<li>@{Html.RenderAction("CartSummary", "ShoppingCart");}</li>

<li><a href="@Url.Content("~/StoreManager/")">

Admin</a></li>

</ul>

</div>

@{Html.RenderAction("MarcaMenu", "Store");}

<div id="main">

@RenderBody()

</div>

<div id="footer">

built with <a href="http://asp.net/mvc">ASP.NET MVC 3</a>

</div>

</body>

</html>

Actualizam pagina Store Browse

/Views/Store/Browse.cshtml:

@model GuitarStore.Models.Marca

@{

ViewBag.Title = "Browse Chitare";

}

<div class="marca">

<h3><em>@Model.Name</em> Chitare</h3>

<ul id="chitara-list">

@foreach (var chitara in Model.Chitare)

{

<li>

<a href="@Url.Action("Details",

new { id = chitara.ChitaraId })">

<img alt="@chitara.Title"

src="@ chitara.ChitaraArtUrl" />

<span>@ chitara.Title</span>

</a>

</li>

}

</ul>

</div>

Actualizam pagina Home Page pentru a vizualiza cele mai vandute chitare TOP SELLING GUITARS

HomeController

public virtual Marca Marca { get; set; }

public virtual Gen Gen { get; set; }

public virtual List<OrderDetail>OrderDetails { get; set; }

}

}

private List<Chitara> GetTopSellingChitare(int count)

{

return storeDB.Chitare

.OrderByDescending(a => a.OrderDetails.Count())

.Take(count)

.ToList();

}

public ActionResult Index()

{

var chitare = GetTopSellingChitare(4);

return View(chitare);

}

HomeController cod complet:

using System.Collections.Generic;

using System.Linq;

using System.Web.Mvc;

using GuitarStore.Models;

namespace GuitarStore.Controllers

{

public class HomeController : Controller

{

GuitarStoreEntities storeDB = new GuitarStoreEntities();

public ActionResult Index()

{

var chitare = GetTopSellingChitare(4);

return View(chitare);

}

private List<Chitara> GetTopSellingChitare(int count)

{

return storeDB.Chitare

.OrderByDescending(a => a.OrderDetails.Count())

.Take(count)

.ToList();

}

}

}

@model List<GuitarStore.Models.Chitara>

@{

ViewBag.Title = "GuitarStore";

}

<div id="promotion">

</div>

<h3><em>TOP</em> SELLING GUITARS</h3>

<ul id="chitara-list">

@foreach (var chitara in Model)

{

<li><a href="@Url.Action("Details", "Store",

new { id = chitara.ChitaraId })">

<img alt="@chitara.Title" src="@chitara.ChitaraArtUrl" />

<span>@chitara.Title</span>

</a>

</li>

}

</ul>

Cautare

Controller-ul Chitara (pt cautare)

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;

using GuitarStore.Common;

using GuitarStore.Models;

using MvcContrib.UI.Grid;

namespace GuitarStore.Controllers

{

public class ChitaraController : Controller

{

private ChitaraService _service;

public ChitaraController()

{

_service = new ChitaraService();

}

public ActionResult Index(string searchWord, int? marcaId, int? genId, GridSortOptions gridSortOptions, int? page)

{

var pagedViewModel = new PagedViewModel<ChitaraViewModel>

{

ViewData = ViewData,

Query = _service.GetChitareView(),

GridSortOptions = gridSortOptions,

DefaultSortColumn = "ChitaraId",

Page = page,

PageSize = 10,

}

.AddFilter("searchWord", searchWord, a => a.ChitaraTitle.Contains(searchWord) || a.Gen.Contains(searchWord) || a.Marca.Contains(searchWord))

.AddFilter("marcaId", marcaId, a => a.MarcaId == marcaId, _service.GetMarci(), "Name")

.AddFilter("genId", genId, a => a.GenId == genId, _service.GetGenuri(), "Name")

.Setup();

return View(pagedViewModel);

}

public ActionResult Details(int id)

{

var viewModel = _service.FindChitaraView(id);

ViewBag.RouteDicForList = Request.QueryString.ToRouteDic();

return View(viewModel);

}

}

}

Modelul relational sub forma .edmx

Modelul relațional ca și orice alt model de date utilizat în proiectarea logică a bazelor de date eliberează utilizatorul de cunoașterea detaliilor despre structura fizică și metodele de acces la date. Unul din avantajele sale constă în omogenitatea sa. Toate datele sunt structurate în tabele, fiecare linie având același format. Linia dintr-un tabel reprezintă un obiect sau o relație între obiecte din lumea înconjurătoare.

Diagrama USE case

Concluzii

In concluzie am ales avantajele oferite de ASP.NET MVC pentru a crea un website care contine un magazin online de chitare .

In viitor se urmareste imbunatatirea aplicatiei GuitarStore prin adaugarea urmatoarelor functionalitati :

O functie mai complexa in care ii vom recomanda utilizatorului alte chitare de care ar putea fi interesat, pe baza similaritatii dintre utilizatori.

O functie care permite trimiterea automata a unui mail de confirmare a comenzii.

Referințe web

ASP.NET http://www.asp.net/

MVC http://elf.cs.pub.ro/idp/laboratoare/lab-03

http://www.asp.net/mvc/overview/what-is-mvc

http://www.asp.net/mvc/tutorials

http://mvccontrib.codeplex.com/documentation

Modelul relational http://www.math.md/studlib/informatica/bd_relationale/capitol1.pdf

CONCEPTE CLIENT SERVER http://ro.wikipedia.org/wiki/Client-server

HTML http://ro.wikipedia.org/wiki/HyperText_Markup_Language

BAZE DE DATE http://civile.utcb.ro/cmat/cursrt/bd2.pdf

DETALII CHITARE (poze) http://www.fender.com/guitars/stratocaster

http://ww2.squier.com/

http://www.jacksonguitars.com/

http://www.guitars-m-r-sons.com/

http://www2.gibson.com/Gibson.aspx

http://www.deanguitars.com/home.php

http://www.epiphone.com/default.aspx?

http://www.espguitars.com/

http://www.ovationguitars.com/

CSS http://ro.wikipedia.org/wiki/Cascading_Style_Sheets

FUNCTIA cautare ,afisare http://www.codeproject.com/Articles/130031/Improving-ASP-NET-MVC-MUSIC-STORE-more-usability-w

APS.NET http://ro.wikipedia.org/wiki/ASP.NET

Jquery http://www.worldit.info/articole/despre-jquery-introducere/

Razor http://en.wikipedia.org/wiki/ASP.NET_Razor_view_engine

Biblografie

Beginning ASP.NET MVC 1.0 de  Simone Chiaretta, Keyvan Nayyeri

Programming Microsoft ASP.NET MVC de Dino Esposito

ASP.NET MVC Framework Unleashed de Stephen Walther

ASP.NET MVC 1.0 Website Programming: Problem – Design – Solution de  Nick Berardi, Al

Katawazi, Marco Bellinaso

Pro ASP.NET MVC 3 Framework de Steven Sanderson Adam Freeman

CD / DVD

Biblografie

Beginning ASP.NET MVC 1.0 de  Simone Chiaretta, Keyvan Nayyeri

Programming Microsoft ASP.NET MVC de Dino Esposito

ASP.NET MVC Framework Unleashed de Stephen Walther

ASP.NET MVC 1.0 Website Programming: Problem – Design – Solution de  Nick Berardi, Al

Katawazi, Marco Bellinaso

Pro ASP.NET MVC 3 Framework de Steven Sanderson Adam Freeman

Similar Posts