Login Login
MORE

WIDGETS

Widgets

Wanted articles
Who is online?
Article tools

CSharp:WebAPI Teoria

From Aino Wiki

Jump to: navigation, search

Cosa sono

Sono uno strumento per fornire elaborazioni ad applicazioni web e non. Le Web API risiedono su un Server e da lì sono richiamate da Clients che ne richiedono elaborazioni ricevendo ed inviando dati. Queste transazioni avvengono supportate dal protocollo HTTP ecco perché quando si richiedono delle operazioni alle Web API si specifica il metodo HTTP sottostante (chiamato anche verbo): GET, POST, PUT, PATCH, DELETE.
Le Web API NON SUPPORTANO il protocollo SOAP (leggere qui).

Architettura

Da docs.microsoft.com
WebAPI architecture.png
  • Il Client è ciò che usa la Web API (browser, App mobile etc). Per testare si può usare postman
  • Il Model è un oggetto che rappresenta i dati dell'applicazione. Nel grafico si vede solo il modello "To-Do".
  • Il controller è un oggetto che gestisce richieste HTTP e crea le risposte (HTTP response).

Storia

Predecessori delle WebAPI sono i Web Services che sono sostanzialmente dei metodi disponibili sul WEB e come tali il loro compito è quello di comandare una elaborazione, in questo "comando" c'è un flusso di informazioni che può essere prevalentemente inviato o ricevuto che è o sarà il frutto dell'elaborazione.

Le Web API (Web Application Program Interface) sono simili a Web Services ma in architettura REST (Representational State Transfer).
REST è un'architettura per sistemi distribuiti rappresenta un sistema di trasmissione di dati su HTTP senza ulteriori livelli (quali ad esempio SOAP). I sistemi REST non prevedono il concetto di sessione (sono, come approfondito successivamente, stateless).
L'architettura REST si basa su HTTP; il funzionamento prevede una struttura degli URL ben definita (per identificare univocamente risorse) e l'utilizzo dei verbi HTTP: (GET), per la modifica (POST, PUT, PATCH, DELETE) e per altri scopi (OPTIONS, ecc.).

I Metodi

Le Web API, intendendo quelle ottenute mediante applicazioni .Net Microsoft, essendo interrogabili mediante chiamate HTTP in funzione di queste possono richiedere l'esecuzione di determinate operazioni. Per esempio molti metodi HTTP possono esser usati per estrarre dati da un server o per inviare dati (Submit) per opportune elaborazioni, metodi HTTP posson esser usati per richiedere cancellazioni di elementi etc. (Da [1]) Ci sono 4 metodi che corrispondono a queste azioni (CRUD):

  • C - Create - POST (in una WebAPI corrisponderà a far precedente la definizione del metodo con l'attributo [HttpPost])
  • R - Read - GET (in una WebAPI corrisponderà a far precedente la definizione del metodo con l'attributo [HttpGet])
  • U - Update - PUT (in una WebAPI corrisponderà a far precedente la definizione del metodo con l'attributo [HttpPut])
  • D - Delete - DELETE 

Ci sono anche altri metodo ma si useranno solo per casi particolari ed essi sono: HAED, OPTIONS, PATCH.

POST e PUT

Esempio di chiamata ad un metodo server per l'aggiunta di una entità:

[HttpPost]
public IHttpActionResult Add(string title)  
{
    //Creates a Movie based on the Title
    return Ok();
}

Se si ha bisogno che un metodo, lato server, supporti più di un metodo HTTP, si potrà usare l'attributo [AcceptVerbs], es.:

[AcceptVerbs("POST", "PUT")]
public IHttpActionResult Add(string title)  
{
    //Creates a Movie based on the Title
    return Ok();
}

Metodi POST e PUT sono molto simili, entrambi inviano dati al server di cui si richiede di immagazzinare qualcosa. Tecnicamente, si possono attivare indipendentemente scenari di creazione o aggiornamento.

PUT is idempotente. Questo vuol dire che se si fa la stessa richiesta due volte, usando la PUT, con gli stessi parametri entrambe le volte, la seconda richiesta non sortirà alcun effetto. Questo è il motivo per cui la PUT è generalmente usata per gli scenari di Update; chiamando l'Update più di una volta con stessi parametri non farà nulla di diverso da quel che ha fatto la prima chiamata.

POST non è idempotente; effettuare la stessa chiamata con POST con stessi parametri ogni volta compierà differenti comportamenti, ecco perché il POST è usualmente usato per scenari di Creazione (sottomettendo due items identici al metodo Create produrrà due entità in archivio).

Metodo di default

Secondo ASP .NET è il POST.The algorithm ASP.NET uses to calculate the "default" method for a given action goes like this:

  1. Se il metodo ha un attributo che specifica direttamente l'uso del metodo HTTP (es.: [HttpGet], [HttpPost], [HttpPut], [AcceptVerbs], etc), the action will accept the specified HTTP method(s).
  2. If the name of the controller action starts the words "Get", "Post", "Put", "Delete", "Patch", "Options", or "Head", use the corresponding HTTP method.
  3. Altrimenti si suppone che l'azione richiesta sia sempre sul metodo POST.

Output

HttpResponseMessage

Un HttpResponseMessage è particolarmente utile come oggetto di output di un metodo di una Web API. Come parametro di output di un'azione, es. POST\GET etc, del protocollo HTTP (Per Esempio con le proprietà headers) consente di uniformare il tipo restituito in output.

Semplicemente un HttpResponseMessage è un modo per restituire un messaggio/dato in seguito ad una azione.
[HttpPost]
public HttpResponseMessage Post_Stampa_menu_anteprimaordini_HttpResponse(AnteprimaOrdiniFornitoriIN aof)
{
   //...
	HttpResponseMessage cResponse = new HttpResponseMessage(HttpStatusCode.OK);
	cResponse.Content = new ByteArrayContent(streamPDF.ToArray());
	cResponse.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
	cResponse.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("Content-Disposition")
	{
		FileName = string.Format("{0}{1}" , c_PDF_RelativeOutputPath, Path.GetFileName(pdfFileNameFullPath)) 
	};
	return cResponse;
}

Esempi presi da c-sharpcorner.com

Content

Come accennato la HttpResponseMessage fornisce un metodo strutturato ed uniforme per lavorare nei diversi ambiti di dominio d'uso. Infatti, mette a disposizione, oltre ad un modo standard di definire l'esito della operazione richiesta (es. l'HttpStatusCode) l'oggetto Content per veicolare in output il risultato di una operazione. Il Content può essere comodamente di diverso tipo: dato scalare, vettoriale o un oggetto personalizzato.

Esempio stringa in output

L'output è una stringa contenente il testo di quel che dovrà essere il contenuto di un file CSV, si usa lo StringBuilder per costruirne il contenuto.Notare lo StringContent che definisce il Content.

[ActionName("genera-report-previsioni-csv")]
[Route("genera-report-previsioni-csv")]
[HttpGet]
public HttpResponseMessage Get_GeneraPrevisioniCSV(string impianto, string settimana)
{
        StringBuilder reportString = new StringBuilder();	
	reportString.Append("bla, bla";\r\n");		
	reportString.Append("bla, bla";\r\n");
 
	using (StringWriter sw = new StringWriter())
	{
		using (HtmlTextWriter htw = new HtmlTextWriter(sw))
		{
			HttpResponseMessage cResponse = new HttpResponseMessage(HttpStatusCode.OK);
			cResponse.Content = new StringContent(reportString.ToString(), System.Text.Encoding.Unicode);
			cResponse.Content.Headers.ContentType = new MediaTypeHeaderValue("application/vnd.ms-excel");
			cResponse.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
			{
				FileName = "file.csv"
			};
		}
	}
	return cResponse;
}
Esempio array di un File PDF
Notare lo ByteArrayContent che definisce il tipo del Content. Notare anche la gestione dell'eccezione nel blocco Catch ed il ContentType Text/html
[ActionName("stampa-menu-anteprimaordini")]
[Route("stampa-menu-anteprimaordini")]
[HttpPost]
public HttpResponseMessage Get_GeneraPrevisioniCSV(string impianto, string settimana)
{
        HttpResponseMessage cResponse;
	try
	{
		using (StringWriter sw = new StringWriter())
		{
			using (HtmlTextWriter htw = new HtmlTextWriter(sw))
			{		
				MemoryStream streamPDF = new MemoryStream();
				streamPDF = CostruisciPDF_AnteprimaOrdini(aof, ref pdfFileNameFullPath); // <-- !
 
				cResponse = new HttpResponseMessage(HttpStatusCode.OK);
				cResponse.Content = new ByteArrayContent(streamPDF.ToArray());
				cResponse.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
				cResponse.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("Content-Disposition")
				{
					FileName = "file.pdf"
				};
				return cResponse;
			}
		}	
	}
	catch (Exception e)
	{
		string errorMessage = string.Format("Errore generico {0}, {1}", e.HResult, e.Message);
                log.ErrorFormat(errorMessage);
                cResponse = new HttpResponseMessage(HttpStatusCode.InternalServerError);
                cResponse.Content = new StringContent(errorMessage, System.Text.Encoding.Unicode, "text/html");
            }
	}
	return cResponse;
}

Esempi

Esempio di come si possa passare una dato strutturato di ritorno o un errore per entità non trovata o un errore come emerso da un blocco try catch:

// GetEmployee action  
public HttpResponseMessage GetEmployee(int id)  
{  
   try  
   {  
      Employee emp = EmployeeContext.Employees.Where(e => e.Id == id).FirstOrDefault();  
 
      if (emp != null)  
      {  
         return Request.CreateResponse<Employee>(HttpStatusCode.OK, emp);  
      }  
      else  
      {  
         return Request.CreateErrorResponse(HttpStatusCode.NotFound, " Employee Not Found");  
      }  
   }  
   catch (Exception ex)  
   {  
      // Log exception code goes here  
      return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, "Error occured while executing GetEmployee”);  
   }    
}

Routing

  • Teoria sul routing MVC qui [2]
  • Teoria sul Routing al controller [3]

Sicurezza

Autenticazione e Autorizzazione

WEBAPI authWithToken.png

Risorse:

Basic Autentication

Esempio: technical-recipes.com

Mappa e Link


WEB API | WebAPI Esempi | WCF | C# | Teoria


Soluzioni varie | Visual Studio


Parole chiave: WebAPI, Web API

Author