Skip to content

Instantly share code, notes, and snippets.

@daverave1212
Last active January 18, 2020 10:48
Show Gist options
  • Save daverave1212/14be7477834b04151f3297d8f127bf4e to your computer and use it in GitHub Desktop.
Save daverave1212/14be7477834b04151f3297d8f127bf4e to your computer and use it in GitHub Desktop.
Web Dev DAW

Web Dev

http://www.cezarabenegui.com/

How to create a project

Project: FIle > New > Project > ASP.NET > MVC

Routing

/ControllerName/ActionName/Parameters

Ex: /student/create/parameters..

/home/about/...

= class Home / method About

Numele claselor / metodelor trebuie sa coincida cu numele controllelor/actionurilor

Cu cat o ruta e scrisa mai jos in cod, are mai multa 'prioritate'. Ruta default trebuie sa fie mereu ultima in cod.

Ca la function overloading, routele nu trebuie sa aiba conflicte

Route custom:

routes.MapRoute(
	name: "Concatenare",
	url: "concatenare/{param1}/{param2}",
	(sau) url: "{controller}/{action}/{param1},
	defaults: new {
		controller = "Example",
		action = "Concatenare",
		param1 = "Daverave",	// Default
		param2 = UrlParameter.Optional } );

Ca sa ignoram o ruta:

 routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

Create controller:

Controllers > Right Click > Add > Controller

  • Un controller mereu are 'Controller' la sfarsit in nume

How to setup a new route:

Note: Asta e complet optional! By default, cand ai un controller, linkul se mapeaza ca localhost:420/ControllerName/MethodName!

  1. In App_Start > RouteConfig.css, add this:

     routes.MapRoute(  
     	name: "AUniqueID",  
     	url: "mycontr/mymethod/{param1}/{param2}",  
     	defaults: new {  
     		controller = "MyContr",  
     		action = "MyMethod",  
     		param1 = UrlParameter.Optional,  
     		param2 = UrlParameter.Optional  
     	}  
     );  
    
  2. Fac o clasa MyContrController, cu o metoda (public, string) MyMethod(string param1, string param2)

Daca vrem ca un parametru CHIAR sa fie optional, trebuie sa ii punem in metoda int? param2

Controller:

Proceseaza URL-urile

Aici avem toate metodele de prelucrare CRUD

Trebuie sa se numeasca CevaController (cu Controller la sfarsit)

Right Click pe folder > Add > Controller

Actions for Controllers:

  • Publice, non-statice, overloadable

Putem face 2 actiuni cu acelasi nume dar alti parametri SI alte tipuri de request! (Ex: GET si POST)

Metode

public ActionResult Index(){
	return View();	// Intoarce automat viewul Index.cshtml
}

Pot lua ca parametri clase mai complexe:

public ActionResult Show(Student stud)

Putem sa le redenumim pt mapping asa:

[ActionName("about")]
public ActionResult AboutPage()

Sau sa nu intre in routing

[NonAction]
public...

Ca sa le facem post sau delete sau whatever; by default ele sunt get

[HttpPost]
public ...

ATENTIE: Put si Delete nu merg in forms! (Nuj de ce) La form trebuie sa punem:

La form trebuie sa punem method="post"

Daca la metoda ii zicem return View();

El o sa returneze browserului pagina cu numele Controllerul/Metoda.cshtml

Nice!

Dar ca sa fim siguri, pune si tu

return View("MyCSHTMLFileName");

ActionResult:

Poate sa intoarca o groaza de chestii, gen json, html, etc

Clasele astea inheriteaza ActionResult si intorc:

ViewResult : HTML return View(...)

ContentResult : String return Content(...)

JsonResult : JSON return Json(...)

return RedirectToRoute(...)

return File(bytes, mimetype, downloadName)

TempData

Stocheza date intre 2 requesturi (DAR NU 3 SAU MAI MULTE!)

TempData["name"] = "Dave";
...
name = TempData["name"].ToString();
...
if(TempData.ContainsKey("name"))

View:

Views > Folderul controllerului > click dreapta > add > view

  • Un view e un .cshtml
  • By default, daca facem o clasa controller cu o metoda, daca scriem localhost:.../theclass/themethod/parametri

El o sa mearga oricum :) Pasam variabile din controller method in cshtml:

ViewBag.property = value;

Apoi il inseram in .cshtml:

<h4>@ViewBag.property</h4>

Forms

Numele inputurilor se binduiesc automat pe parametrii metodelor

<form method="post" action="/Panda/Add">
    <label>Nume</label>
    <input type="text" name="Name" />
    <label>Adresa e-mail</label>
    <input type="text" name="Email" />
    <label>Age</label>
    <input type="text" name="Age" />
    <button type="submit">Adauga pandalau</button>
</form>

Note: Nu exista by default Delete si Put, asa ca trebuie sa punem asta inauntrul formului ca sa il facem sa mearga (lasam method="post" sus)

@Html.HttpMethodOverride(HttpVerbs.Delete)

View html helpers

Putem insera C# in html:

@foreach (var panda in ViewBag.SelectedPandas) {
    <p>@panda.Name</p>
    <p>@panda.Email</p>
}

Iata forms cu Html Helpers:

<form...
	@Html.Label("Name", "Nume pentru panda")
	@Html.TextBox("Name", "defaultut", new {@class="form-control"}
</form>

Better yet

<form ... action="/Panda/Edit/@Model.PandaId">
	@Html.Editor("Name")
</form>

Validare (validation messages):

@Html.Editor("Lalala")
@Html.ValidationMessage("Lalala", "Not valid!!!", new {@class...}

Warning: Asta ar pute sa nu mearga! Vezi cum e corect In controller, putem sa verificam daca datele modelului sunt valide.

if (ModelState.IsValid) { ...

Filtre:

Sunt anotatii magice pe care le punem la metodele unui controller ca sa faca chestii.

Ex:

[OutputCache(Duration = 3600)] Prima oara cand e accesat linkul se salveaza si se intoarce

Layouts

Putem crea un nou layout:

Copy la Views/Shared/_Layout.cshtml > paste > rename in '_MyLayout'

Il folosim: adaugam la o pagina .cshtml, sus de tot unde e aia cu Title:

Layout = "~/Views/Shared/_MyLayout.cshtml";

Partial Views (Components)

Cream in Views/Shared un view si dam tick la 'Create as partial view' si il numim MyPartialView

<p> @Model.Name </p>
<p> @Model.Age </p>
<p> @Model.Email </p>

Si il folosim asa (ii dam ca parametru un model):

@Html.Partial("MyPartialView", pandalaulMeu);

Model:

Setup: Tools > NuGet Package Manager > aia din mijloc > Entity Framework

Models > Click Dreapta > Create class

Un model seminifica un tabel SQL; fiecare chestie din model trebuie sa corespunda cu SQL, si de aia ii punem anotari la fiecare:

[Key] [MinLength(10)] [MaxLength(10)] [Required]
[Required(ErrorMessage = "Campul este obligatoriu")]
[EmailAddress(ErrorMessage = "Adresa nu este valida")]

Pentru proiect, trebuie sa avem si un DbContext:

Ex: ArticolDBContext : DbContext

El contine:

public ArticleDBContext() : base("ArticleConnectionString") { }  
public DbSet<Article> Articles { get; set; }
public DbSet<Category> Categories {get; set; }

Din pacate C# e un bulangiu si nu creeaza singur databaseul, asa ca trebuie sa il cream noi folosind SQL din command window din visual studio.

Bun. In controllerul nostru, trebuie sa avem o instanta a acelui ArticolDBContext:

ArticolDBContext db = new ArticolDBContext();

Il vom folosi ca sa accesam chestii din baza de date si sa le punem in ViewBag:

El foloseste un fel de pseudo-sql:

var articles = from article in db.Articles select article;

E o mizerie dar asta e _=)_/

Join

Un model (clasa .cs) poate sa aiba o relatie cu alt tabel. Daca un PANDA are un REED, atunci REED are:

[ForeignKey("Panda")]
public int PandaId {get; set;}
public Panda Panda {get; set;}

Iar PANDA are:

public ICollection<Reed> Reeds {get; set;}

Il adaugam cu db.Pandas.

Legare cu Baza de Date:

Setup:

App_Data > Add > Sql Server Database > Orice nume

  • Creeaza tabelul respectiv:

    Dublu click pe databaseul tocmai creeat > Tables > Create table

      CREATE TABLE [dbo].[Pandas]
      (
      	[Name] VARCHAR(255) NOT NULL PRIMARY KEY,
      	[Email] VARCHAR(255) NOT NULL,
      	[Age] INT NOT NULL
      )
    
  • In Web.config de jos de tot din proiect, adauga asta si modifica acel PandaConnectionString sa matchuiasca cum e in DbContextul tau SI pathul catre database!

    <connectionStrings>
        <add name="PandaConnectionString" providerName="System.Data.SqlClient" connectionString="Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\Dave\source\repos\Lab6\Lab6\App_Data\MySqlDatabase.mdf;Integrated Security=True"/>
    </connectionStrings>
    

Adaugare entries in database

Note: Ai grija sa ai facut setupul cum trebuie!

db.Pandas.Add(panda);
db.SaveChanges();

Select din database

from panda in db.Pandas
orderby panda.Name
select panda;

Sau

db.Pandas.Find(name)

Update in database

if (TryUpdateModel(student)) {
	student.Name = requestStudent.Name;
	student.Email = requestStudent.Email;
	student.CNP = requestStudent.CNP;
	student.City = requestStudent.City;
	db.SaveChanges();
} 

Authentication

Pentru setup, vezi Complete project setup mai jos.

Ca sa restrictionam accesul userului laun controller/view, punem un annotation:

[Authorize(Roles = "Administrator")]

Complete project setup:

  1. Create Project

    Project: FIle > New > Project > ASP.NET Web Application (.NET Framework) > MVC, Change Authentication > Individual User Accounts > OK

  2. Setup la Identity Framework
  • In App_Start/Startup.Auth.cs, paste this DUPA cele 3 randuri cu app.CreatePerOw...:

      app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);
    
  • In App_Start/IdentityConfig.cs, adaugam asta:

      public class ApplicationRoleManager : RoleManager<IdentityRole> {
          public ApplicationRoleManager(IRoleStore<IdentityRole, string> store) : base(store){}
          public static ApplicationRoleManager Create(IdentityFactoryOptions<ApplicationRoleManager> options, IOwinContext context) {
              var roleStore = new
              RoleStore<IdentityRole>(context.Get<ApplicationDbContext>());
              return new ApplicationRoleManager(roleStore);
          }
      }
    
  • In Startup.cs, adaugam astea:

      	public void Configuration(IAppBuilder app)
          {
              ConfigureAuth(app);
              // Se apeleaza o metoda in care se adauga contul de administrator si rolurile aplicatiei
              createAdminUserAndApplicationRoles();
          }
    
      	 private void createAdminUserAndApplicationRoles()
          {
              ApplicationDbContext context = new ApplicationDbContext();
              var roleManager = new RoleManager<IdentityRole>(new
              RoleStore<IdentityRole>(context));
              var UserManager = new UserManager<ApplicationUser>(new
              UserStore<ApplicationUser>(context));
              // Se adauga rolurile aplicatiei
              if (!roleManager.RoleExists("Administrator"))
              {
                  // Se adauga rolul de administrator
                  var role = new IdentityRole();
                  role.Name = "Administrator";
                  roleManager.Create(role);
                  // se adauga utilizatorul administrator
                  var user = new ApplicationUser();
                  user.UserName = "[email protected]";
                  user.Email = "[email protected]";
                  var adminCreated = UserManager.Create(user, "Administrator1!");
                  if (adminCreated.Succeeded)
                  {
                      UserManager.AddToRole(user.Id, "Administrator");
                  }
              }
              if (!roleManager.RoleExists("Editor"))
              {
                  var role = new IdentityRole();
                  role.Name = "Editor";
                  roleManager.Create(role);
              }
              if (!roleManager.RoleExists("User"))
              {
                  var role = new IdentityRole();
                  role.Name = "User";
                  roleManager.Create(role);
              }
          }
    
  1. Install Entity Framework (if not installed automatically)

    Tools > NuGet Package manager > Manage NuGet Packages For Solution > Cauta Entity Framework and install it

  2. Create Controller

    Controllers > Right Click > New Controller > PandaController.cs

  3. Create Model

    Models > Add > Class > Panda.cs

    • In IdentityModels.cs, adaugam un collection de Pandala ApplicationDbContext:

        public DbSet<Panda> Pandas { get; set; }
      
    • Adauga un database:

      App_Data > Add > Sql Server Database > Orice nume

    • Creeaza tabelul respectiv:

      Dublu click pe databaseul tocmai creeat > Tables > Create table

        CREATE TABLE [dbo].[Pandas]
        (
        	[Name] VARCHAR(255) NOT NULL PRIMARY KEY,
        	[Email] VARCHAR(255) NOT NULL,
        	[Age] INT NOT NULL
        )
      
    • In Web.config de jos de tot din proiect, adauga asta si modifica acel PandaConnectionString sa matchuiasca cum e in DbContextul tau SI pathul catre database!

      `

    `
  4. Create View

    • In PandaController, add o functie Index: public ActionResult Index(){ return View(); }
    • Views > Panda > Add > View > Index.cshtml

Useful Snippets

[Authorize(Roles = "User,Editor,Administrator")]

var g = db.Albums.Find(id);

var query = "SELECT * FROM albums WHERE AlbumId = (SELECT MAX (AlbumId) FROM albums); ";
Album maxIDalbum = db.Albums.SqlQuery(query).FirstOrDefault();

ViewBag.ConversationMessages = db.ConversationMessages.Where(x => x.ConversationId == id).OrderBy(x => x.Timestamp);

User.Identity.GetUserId()

db.Conversations.Add(convo);
db.SaveChanges();

public ActionResult Edit(int id, Album elem)

[ForeignKey("UserId")]
public virtual ApplicationUser User { get; set; }

[DatabaseGenerated(DatabaseGeneratedOption.None)]

<form method="post" action="/Conversation/New">
    @Html.Hidden("UserId", User.Identity.GetUserId())
    @Html.Label("Username", "I want to talk to... (username)")
    @Html.TextBox("Username", null, new { @class = "form-control" })
    <button type="submit">Talk now!</button>
</form>

Index la cursuri

Ciclul de viata al unei pagini web - Cursul 1 Arhitectura MVC - Cursul 2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment