Jump to content
bc-vnt

ASP.NET Web service and Web API

Recommended Posts

Posted

1 : Web service and Web API

Utilizarea de c?tre dumneavoastr? a Web-ul ca o platform? pentru programare este o idee care sa r?spândit în jurul valorii de anul 2000 cu introducerea de servicii Web, ?i anume un mecanism de interoperabilitate între aplica?iile bazate pe tehnologiile ?i standardele definite pentru Web

Servicii Web v? permit s? interac?ioneze dou? solicit?ri, indiferent de sistemul de operare care se execut? pe ?i limbajul de programare folosit. Punct de vedere tehnic, mecanismul de interac?iune se bazeaz? pe protocolul SOAP, un set de reguli care definesc structura mesajelor schimbate de c?tre aplica?ii ?i o serie de m?suri pentru a asigura siguran?a, fiabilitatea, buna gestionare a evenimentelor, etc. Abordarea se bazeaz? în principal pe o defini?ie a func?iei nev?rsat prin Web

O abordare alternativ? la serviciile Web bazate pe SOAP, care a fost propus, în acela?i an, dar a fost redescoperit abia în timpurile recente, este cunoscut sub numele de abordarea ODIHN? (Representational State Transfer), ?i se bazeaz? pe un set de principii care trebuie s? o aplica?ie respect. În rezumat, în vederea unui serviciu Web odihnitor nu define?te o func?ie nev?rsat de la distan??, dar regimul care asigur? resursele pe care le pute?i efectua opera?iile obi?nuite CRUD folosind metodele de protocolul HTTP.

Doua viziuni diferite ale web ca o platforma de calcul, care sunt din ce în ce fiind diferit doar vorbesc despre serviciile de web, atunci când se refer? la cei care sunt bazate pe SOAP ?i Web API atunci când, dup? modelul de odihn?.

Pentru mai multe informa?ii cu privire la diferite filozofii de punere în aplicare a serviciilor Web ?i o compara?ie între cele dou? abord?ri poate fi g?sit:

****Odihnitoare Web Service - Ajutor

****Ghidul Web serviciu

Acest ghid se dore?te a fi un tutorial practice privind punerea în aplicare a odihnitor tipul de serviciu Web utilizând cadrul Web API-ul introdus de Microsoft cu MVC 4. Dup? introducerea cadrul ?i instrumentele necesare pentru utilizarea sa, vom explora func?iile disponibile pentru a exploata ?i de a crea un API simplu Web.

Abordarea restul de Microsoft

Înainte de introducerea Web ASP.NET API, Microsoft a avut nici un sprijin oficial pentru modul de serviciu REST Web. Cei care au dorit s? adopte avut dou? drumuri: utilizarea WCF, subsistemul NET dedicat pentru construirea aplica?iilor orientate spre servicii, sau s? adopte o bibliotec? extern, cum ar fi OpenRasta sau Stiva de service..

Profita?i de WCF pentru a crea servicii Web în func?ie de abordarea odihnitor nu este o chestiune u?oar?. Din acest motiv, Microsoft a introdus ini?ial WCF REST Starter Kit ?i apoi WCF Web API. Ambele pachete au fost concepute pentru a simplifica crearea de servicii Web bazate pe WCF, dar nici unul dintre ei nu a v?zut realizarea o versiune stabil?.

Cu ASP.NET Web API, Microsoft a decis s? î?i modifice abordarea în crearea de servicii web odihnitoare bazându-ne pe mecanismul de rutare de MVC în loc de a încerca s? simplifice complexitatea inerent? a WCF subsistemului.

ASP.NET Web API este o parte integrant? a ASP.NET MVC 4. Prin urmare, este necesar pentru a desc?rca ?i instala aceast? versiune a pachetului de ASP.NET MVC ?i de a folosi Visual Studio Web Developer sau video 2010 SP1 de la versiunea în sus. Nu va fi, de asemenea, un pachet de NuGet care nu are nevoie de instalarea întregul cadru MVC, dar în acest caz, trebuie s? fac? anumite set?ri manual ?i s? renun?e la anumite facilit??i oferite de mediul înconjur?tor.

În urm?torul ghid ne vom referi la o instalare complet? a ASP.NET MVC 4 ?i Visual Web Developer 2010 SP1

2 : First step with API

În acest tutorial vom explora caracteristicile aplica?ie Web ASP.NET, prin crearea unui API REST simplu, care ne va permite s? gestioneze un glosar on-line, o list? de defini?ii poate fi numit prin specificarea unui termen limit?. Un client care acceseaz? glosar cu ajutorul API-urile pe care le vom crea va necesita definirea unui termen, o list? de defini?ii ale unei anumite categorii ?i, dac? este autorizat, pute?i ad?uga, edita sau ?terge intr?ri în glosar.

Dup? ce a?i desc?rcat ?i instalat tot ce ai nevoie, lansa Visual Web Developer sau Visual Studio ?i de a crea un proiect nou bazat pe ?ablonul Application ASP.NET MVC web 4.

print1v.png

În urm?toarea fereastr? de dialog, selecta?i Web API ca tipul de proiect.

print2x.png

Acest lucru va genera toate necesare pentru a fi în m?sur? s? înceap? cu realizarea unei cereri MVC 4, care define?te un set de API odihnitor.

Înainte de a începe cu punerea în aplicare efectiv?, este necesar s? fie clar ca un API Web este structurat? ?i modul în care aceasta func?ioneaz? în interiorul sistemului. Un API Web const? în principal din resurse accesibile prin Web prin unul sau mai multe reprezent?ri.

O resurs? este, de obicei, o instan?? a unei clase, care este trimis la client dup? ce a fost serializat. ASP.NET Web API suport? de c?tre serializare implicit la JSON ?i XML. Fiecare resursa poate fi g?sit? pe Web folosind un URI specific reprezentate în cadrul noastr? folosind mecanismul de rutare în ASP.NET.De gestionare a metodelor HTTP asupra resurselor este încredin?at? controler, un tip de clas? al c?rui metode de a pune în aplicare cereri de aplica?ii primite prin HTTP.

În esen??, un client solicit? executarea unei metode HTTP GET, cum ar fi pe o resurs? identificat? printr-un URI.Cadru, interpretarea URI identific? operatorul asociat cu resurse ?i, în func?ie de metoda specific? HTTP ?i parametrii specificate de c?tre client invoc? metoda corespunz?toare.Rezultatul metodei este o resurs? ?i / sau un cod de stare HTTP. Dac? o resurs? este returnat, aceasta este serializat în conformitate cu formatul impus de c?tre client prin antetul HTTP Accept.

În lumina a ceea ce am descris-o, vom vedea cum s? pun? în aplicare API-ul nostru în primul rând c? permite definirea unui termen.

Mai întâi vom crea un folder resurse în proiect ?i s? defineasc? ca un articol de clas?. Aceast? clas? reprezint? o intrare în glosar, ca suma de un termen ?i definirea acesteia, astfel cum se specific? de c?tre codul de mai jos.

public class Item
{
****public string term { get; set; }
****public string definition { get; set; }
}

Crearea folderului resurselor nu este punct de vedere tehnic necesar, dar este necesar s? se creeze o mai bun? organizare a elementelor proiectului.

Dup? ce a?i definit resursa a noastra, de a crea un controler s? se ocupe de aceste cereri HTTP de la client. În dosarul Controleri proiectului nostru adaug? un API Controler de gol ?i ItemsController apel.

print3m.png

Acest lucru va crea o clas? derivat? din ApiController vom finaliza cu codul de mai jos:

public class ItemsController : ApiController
{
****List<item> items = new List<item>
****{
********new Item { term = "API", definition = "Insieme di subroutine o di funzioni che un programma..."},
********new Item { term = "World Wide Web", definition = "L'insieme delle informazioni pubblicate..."},
********new Item { term = "HTTP", definition = "Protocollo per il trasferimento di..."}
****};
*****
****public Item GetItemByTerm(string id)
****{
********var myVoce = items.FirstOrDefault((p) => p.term == id);
********if (myVoce == null)
********{
************var resp = new HttpResponseMessage(HttpStatusCode.NotFound);
************throw new HttpResponseException(resp);
********}
********return myVoce;
****}
}
</item></item>

Pentru simplitate, având în vedere natura ghid de predare, am p?strat Intr?ri în glosar într-o list?. În realitate, elementele trebuie s? fie stocate într-o baz? de date ?i gestionate prin intermediul interogare specifice.

Singura metod? disponibile în prezent este GetItemByTerm (), care ofer? un parametru id, reprezentând termenul de c?utare, ?i întoarce exemplu determinat de clasa de postul în cazul în care exist?, în caz contrar cod de stare HTTP care indic? faptul c? resursa solicitat? nu exist?.

3 : Call Web API

În ultima lec?ie am înfiin?at prima noastr? API simplu, accesibil printr-o adres? URL care urmeaz? http://server:xxx/api/items/yyy modelul. De exemplu, în cazul în care cererea noastr? este publicat pe ma?ina de dezvoltare a portului 1039, am deschis un browser ?i indica?i-l la http://localhost:1039/api/items/API pentru a ob?ine un rezultat similar cu urm?torul text:

print4v.png

În acest caz, am ob?inut o reprezentare a resursei în XML, dar clien?ii pot solicita reprezentare în alte formate prin specificarea HTTP Accept set de antet la cererea valoarea / JSON.

Accesa un API prin intermediul unui browser Web, îns? situa?ia standard. Un serviciu Web este, de obicei, menit s? fie folosit în noul cod. Deci, haideti sa vedem cum se utilizeaz? API-ul nostru folosind JavaScript pentru a crea o pagin? Web pe care le vizita?i simplu glosarul nostru.

În exemplul nostru vom folosi jQuery, dar pute?i folosi orice bibliotec? pentru a interoga Web prin intermediul Ajax API.

Vom crea astfel o simpl? pagin? HTML cu o caset? text ?i un buton:

<div>
****<label for="termine">Inserisci il termine da ricercare</label>
****<input id="termine" type="text" />
****<button onclick="findItem();">Cerca</button>
</div>

Acum insera?i o referin?? la jQuery ?i punerea în aplicare a FindItem function (), care va avea grij? de interogare API-ul nostru ?i va afi?a rezultatul:

function findItem() {
****var id = $('#termine').val();
*****
****$.getJSON("api/items/" + id,
********function (data) {
************var str = '<p><b>' + data.term + '</b><br/>' + data.definition + '</p>';
************$('#divDefinizioni').html(str);
********}).fail(
************function (jqXHR, textStatus, err) {
****************$('#divDefinizioni').html('Error: ' + err);
****************});
}

Prin introducerea unui termen ?i f?când clic pe butonul Find utilizatorul va primi defini?ia acestuia sau un mesaj de eroare dac? termenul nu exist? în glosar.

print5x.png

În cazul în care clientul JavaScript trebuie s? aib? în vedere problemele legate de eco-domenii apeluri. În exemplul nostru, nu exist? nici o problem? în API client ?i apar?in aceluia?i domeniu, dar dac? dori?i s? apela?i prin intermediul unui API JavaScript care apar?ine unui alt domeniu este necesar s? se ?in? seama de limitele impuse de politicile de securitate ale browser-ului. Desigur, pentru alte tipuri de client ODIHN? aceast? problem? nu se pune.

Behind the Scenes: conventions

În descrierea general? a lucr?rilor interioare ale cadrului am spus c? o resurs? este identificat? printr-un URI ?i, în func?ie de metoda HTTP ?i a parametrilor, dac? este cazul, este g?sit metoda de controlerul de a invoca. Dar cum nu-cadru pentru a identifica resursa corect? Cum ?tii ce este controlor de asociat ?i metoda sa este special, metoda HTTP specificat? de client?

Func?ion?rii sistemului se bazeaz? pe unele conven?ii predefinite, care îns? pot fi personalizate pentru a se potrivi nevoilor dumneavoastr?, dup? cum vom vedea mai târziu în acest ghid.

The scheme of the URI

Prima conven?ie este cea referitoare la modelul de URI pentru a identifica o resurs?. Dac? ne uit?m în jurul valorii de Global.asax a cererii dumneavoastr?, vom descoperi c? a?i definit un traseu cum ar fi urmatoarele:

/api/{controller}/{id}

Traseul define?te o schem? URL cu {} ?i {controler id} ca un substituent pentru controlerul de resurse, precum ?i orice identificator.

La primirea unei cereri HTTP, sistemul de analiza URL-ul va fi în c?utarea pentru un controler pentru resursa specificat?.Identificarea operatorului se face prin concatenarea denumirea utilizat? în loc de {} cu controler controler de cuvinte cheie. Astfel, referindu-se la exemplul nostru, s? se ocupe de URL / API / articole / API, sistemul va c?uta un controller numit ItemsController.

Pentru a afla care este metoda de a invoca controler, sistemul se refer? la metoda HTTP utilizat? de client. În practic?, în cazul în care clientul a utilizat metoda GET, sistemul va c?uta o metod? de controlor al c?rui nume începe cu ajunge, g?sind în cazul nostru GetItemByTerm metoda ().Acela?i mecanism va fi valabil pentru metodele de UPT, POST, DELETE ?i.

În cazul în care mai multe metode care încep cu acela?i prefix, cadrul va identifica una corect? prin analiza num?rul ?i tipul de parametri oferite de metoda ?i compararea acestora cu argumente trecute de client.

În exemplul nostru, valoarea asociat? cu {id} este atribuit parametrului id-ul de GetItemByTerm ().

4 : Generate a list of resources

Exemplu de API-am pus în aplicare se refer? recuperarea defini?ia unui termen, care este, de identificare a unei resurse unice. S? vedem acum cum s? pun? în aplicare o metod? care returneaz? o list? de resurse, cum ar putea fi, de exemplu, o list? de defini?ii care apar?in unei anumite categorii.

În primul rând, vom modifica clasa postul prin ad?ugarea de proprietate Categorie:

public class Item
{
****public string term { get; set; }
****public string definition { get; set; }
****public string category { get; set; }
}

Noi apreciem proprietate pentru toate elementele din gama noastr? de defini?ii ?i de a crea o nou? metod? GetItemsByCategory () pentru a ItemsController controler.

public Item[] GetItemsByCategory(string category)
{
****return items.Where(
********(p) => string.Equals(p.category, category,
*****************************StringComparison.OrdinalIgnoreCase)).ToArray();
}

Metoda presupune un parametru care specific? categoria de defini?ii. Bazat pe acest parametru sunt selectate Intr?ri în glosar care vor face parte din rezultat, care va consta dintr-o serie de obiecte de Tip articol.

Pe partea de client, putem accesa lista defini?iilor dintr-o anumit? categorie, cum ar fi Web, printr-un URI ca / api / articole? Categorie = Web Profitând de jQuery putem face apel ?i a vedea rezultatele cu urm?toarea func?ie:

function findItemsByCategory(category) {
****$.getJSON("api/items?category=" + category,
****function (data) {
********$('#divDefinizioni').html('');
********$.each(data, function (key, val) {
************var str = '<p><b>' + val.term + '</b><br/>' + val.definition + '</p>';
************$('<li/>', { html: str }).appendTo($('#divDefinizioni'));
********});
****})
****.fail(
********function (jqXHR, textStatus, err) {
************$('#divDefinizioni').html('Error: ' + err);
********});
}

Dup? cum se poate vedea din cod, ca r?spuns al Ajax solicita avem o serie de obiecte care reprezint? Intr?ri în glosar identificate de c?tre aplica?ia noastr?.Rezultatul pe ecran va fi similar cu cel de mai jos:

print6t.png

5 : CRUD management of resources

Pân? acum am analizat acces de citire la o singur? resurs? sau o list? de resurse de glosarul nostru. În conformitate cu principiile REST, citi?i accesul la resurse este asociat? cu metoda HTTP GET. De multe ori, cu toate acestea, este necesar s? se prevad? accesul în scris, în scopul de a crea, edita sau ?terge resurse. Acesta este în esen?? de a pune în aplicare CRUD clasic: Crearea, Read, Update, Delete.

Abordarea REST este de a?teptat ca aceste patru opera?iuni corespund, respectiv, la cele patru metode principale de protocolul HTTP, cum au fost rezumate în tabelul de mai jos:

Metodo HTTP Operation Schema URI risorsa

POST Create /api/items

GET Read /api/items?category=XXX

PUT Update /api/items/XXX

DELETE Delete /api/items/XXX

La fiecare tranzac?ie, am asociat URI schema de resurse pe care o vom aplica.

Insertion : POST

Acum hai sa vedem cum de a integra proiectul nostru cu opera?iunile de lips?. S? începem prin a insera?i o nou? defini?ie în glosar, în conformitate cu tabelul de mai sus, se trimite la client o cerere cu metoda POST pentru URI / API / articole.

În urma conven?ia de mai sus, gestionarea acestei cereri este pus în aplicare prin crearea unei metode de a clasa al c?rui nume începe cu ItemsController Mesaj:

public HttpResponseMessage PostItem(Item myItem)
{
****HttpResponseMessage response;
****string uri;
*
****items.Add(myItem);
****response = Request.CreateResponse(HttpStatusCode.Created, myItem);
****uri = Url.Link("DefaultApi", new { id = myItem.term });
****response.Headers.Location = new Uri(uri);
*
****return response;
}

Analizeaza codul pentru a intelege cum functioneaza. Innanziatutto observ?m c? metoda returneaza un obiect de tip HttpResponseMessage. Am putea avea s? se întoarc? un obiect de tip articol, dar aceast? solu?ie, de?i lucreaz?, el a înc?lcat dou? reguli de orient?ri REST:

**** trimiterea codul de stare 201 (Creat)

**** indicând URI nou? resurs? pe care tocmai a?i creat

De fapt, nici un dispozitiv special, cadrul ar trimite în mod automat un r?spuns cu codul de stare 200 (OK) ?i resursa serializat în organism r?spuns. Codul nostru, cu toate acestea, dup? ce ad?uga?i noi resurse în lista intern?, ??creeaz? un r?spuns care con?ine resursa serializate ?i codul de stare corect (HttpStatusCode.Created). Adaug? URI de resurse nou creat în antetele HTTP ale r?spunsului.

Ne amintim înc? o dat? accentul pe scopuri educa?ionale ale exemplul vedem c? ad?ugarea unei noi resurse pentru a lista intern nu are practic nici un efect tangibil. Cu alte cuvinte, din moment ce fiecare cerere API este apatrid, adic? nu exist? nici o între?inere de stat între o cerere HTTP ?i urm?toarea, pentru fiecare nou? cerere va fi re-creat lista de defini?ii, a pierde, de fapt, ad?ug?ri posibile ?i / sau modific?ri.

Dup? cum sa men?ionat mai sus, în cazurile reale list? ar trebui s? fie stocate pe o baz? de date.

Modification PUT

Editarea unei defini?ii glosar corespunde performan?ei metodei UPT un URI de forma / API / articole / xxx, unde xxx este termenul de a schimba.

În urma conven?iilor implicit, în acest caz, vom crea o metod? de clasa ItemsController al c?rui nume începe cu "Put":

public void PutItem(string id, Item myItem)
{
****int i;
*
****i = items.FindIndex(p => p.term == myItem.term);
****if (i != -1)
****{
********items[i] = myItem;
****}
****else
****{
********throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound));
****}
}

Metoda prime?te ca parametri de identificare a resurselor, care, în cazul nostru corespunde la sfâr?itul intr?rii în glosar, ?i de resurse modificat de la client. Prin urmare, se asigur? faptul c? resursa exist? în lista de defini?ii ?i, în caz pozitiv de sotituisce cu cele furnizate de client.

În cazul în care resursa nu exist? în clientul trimite un r?spuns HTTP cu cod de stare 404 Nu, g?sit.

Re?ine?i c?, de?i nu este trimis în mod explicit orice cod de stare de pe succesul schimb?rii, cadrul are grij? de automat comunic? clientului codul de stare 200, OK.

Cancel : DELETE

În cele din urm?, în ceea ce prive?te eliminarea unui element din glosarul nostru, trebuie s? ne gestioneze metoda DELETE pe un URI de forma / API / articole / xxx, unde xxx este termenul care urmeaz? s? fie eliminate.

De aceea, vom pune în aplicare o metod? de al c?rui nume începe cu "Delete":

public HttpResponseMessage DeleteItem(string id)
{
****int i;
*
****i = items.FindIndex(p => p.term == id);
****if (i != -1)
****{
********items.RemoveAt(i);
****}
****return new HttpResponseMessage(HttpStatusCode.NoContent);
}

Metoda verific? dac? exist? ?i dac? resursa elimin? astfel intrarea din list?.Codul de stare returnat este, în orice caz, 204 (nr de con?inut), alegerea motivat? de faptul c? urma?i specifica?iile HTTP, cu condi?ia ca metoda DELETE este idempotent, care are acela?i efect, chiar dac? aceasta este executat? de mai multe ori. Acest lucru înseamn?, în termeni practici, faptul c? clientul nu are nici un indiciu în cazul ?tergerii unei resurse deja ?ters anterior.

De asemenea, în conformitate cu caietul de sarcini HTTP, metoda DELETE poate oferi un r?spuns cu codul de stare 200 (OK) sau 204 (nr de con?inut) sau 202 (Acceptat). În timp ce primele dou? cazuri pot fi considerate echivalente, al treilea caz ar trebui s? se aplice atunci când cererea este acceptat? de c?tre server, dar nu imediat executat, cum ar fi atunci când cererea este plasat într-o coad? pentru procesarea lotului.

6 : Costumize your routing

Am v?zut modul în care cadrul are avantajul de a mecanismului de rutare în ASP.NET ?i o serie de conven?ii pentru a localiza controler de resurse, iar metoda care urmeaz? s? fie efectuate f?r? configura?ie special?. Ar putea fi util?, cu toate acestea, în unele cazuri, s? fie capabil s? mearg? dincolo de conven?ii implicite pentru a personaliza modul în care s? se refere URI-uri, resurse, metode HTTP ?i metode de clas?.

De exemplu, în ceea ce prive?te structura URI, am v?zut c? sistemul propune structura implicit?:

/api/{controller}/{id}

Care este propus pentru a prefix / API pentru URI-uri de API-ului nostru Web este motivat? exclusiv de necesitatea de a evita coliziunile cu rutare standard, într-un proiect de ASP.NET MVC. În cazul în care proiectul nostru va pune în aplicare doar API-ul Web poate foarte bine schimba schema prin eliminarea API / sau înlocuindu-l cu ceea ce ne dorim.

Dac? nu dori?i s? utiliza?i conven?ia c? o metod? HTTP este compensat? o metod? de controler care începe cu acelasi nume, putem folosi HttpGet atribute, HttpPost, ?i HttpDelete HttpPut.

De exemplu, putem mapa la FindItemByTerm metoda GET () astfel:

[HttpGet]
public Item FindItemByTerm(string id)
{
****...
}
Avem, de asemenea, capacitatea de a asocia mai multe metode HTTP în aceea?i metod? de un controlor, ca în urm?torul exemplu:
[AcceptVerbs("GET", "HEAD")]
public Item FindItemByTerm(string id)
{
****...
}

In questo casi verrà eseguito il metodo FindItemByTerm() sia quando il client invia una richiesta HTTP con metodo GET sia quando viene specificato il metodo HEAD. Come si può intuire dall’esempio, oltre a superare le convenzioni, l’attributo AccetpVerbs può essere utilizzato per mappare metodi HTTP diversi dai quattro principali.

7 : content negotiation Json or XML

Introducerea ASP.NET Web API am spus c? vom avea dou? tipuri de reprezentare a resurselor trimise clientului: JSON ?i XML.Alegerea tipului de reprezentare este rezultatul negocierii con?inutului a?a-numita, care este, procesul de selec?ie mai bun? reprezentare a unei resurse în r?spuns la o solicitare.

Cu alte cuvinte, este mecanismul prin care serverul decide, pe baza cererea clientului, care reprezentare a utiliza pentru a trimite resurse pentru client.

Conform specifica?iilor din protocolul HTTP, aceast? decizie trebuie s? se fac? prin analiza anteturile urm?toarele servere de cererea HTTP:

Header

Accept Specific? unul sau mai multe mass-media de tip pentru reprezentarea resurse solicitate, cum ar fi text / simplu, cererea / JSON, cererea / xml, etc.

Accept-Charset Specific? setul de caractere pe care clientul este în m?sur? s? accepte, cum ar fi UFT-8,, ISO 8859-1 etc.

Accept-Encoding Specific? codificarea de con?inut, cum ar fi

Accept-Language Indic? limba preferat? de client, cum ar fi en-US sau en-US

În prezent, ASP.NET Web API este capabil s? se ocupe de automat anteturile Accepta?i ?i Accept-Charset.Gestionarea anteturile altor trebuie s? se fac? prin cod. De exemplu, pentru o cerere HTTP de acest tip:

GET http://localhost:1039/api/items/Web HTTP/1.1
Host: localhost:1039
Accept: application/json, text/plain, */*

API-ul nostru ar putea oferi un r?spuns similar cu urm?torul, f?r? nici o interven?ie din partea noastr? cu privire la cererea:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Content-Length: 254
*
{"Term":"API","Definition":"Insieme di subroutine o di funzioni ...","Category":"Programming"}

Pentru fiecare valoare a anteturile prev?zute de negociere, clientul are posibilitatea de a specifica o valoare zecimal? care indic? o preferin?? a spus factor de calitate (factorul de calitate). De exemplu, urm?torul titlu:

Accept: application/json, application/xml; q=0.8, */*; q=0.2 

indic? un factor de calitate de 1,0 pentru o reprezentare implicit? în JSON, în timp ce a doua preferin?? merge la XML ?i în cele din urm? la orice alt? reprezentare.Serverul trebuie s? îndeplineasc? cererea clientului în func?ie de aceste preferin?e ?i disponibilitatea lor de reprezentare.

8 : Custom formatter to format media for Json and XML

Componentele din ASP.NET Web API care se ocup? cu serializarea ?i deserializing o resurs?, care este, s?-l reprezinte în func?ie de un anumit format transmise prin HTTP ?i vice-versa, sunt numite mass-media formatorului.

Formatorului dou? implicit media utilizate pentru a reprezenta resursele gestionate de un API Web în JSON ?i XML. În mod normal, nu ave?i nevoie pentru a face orice interven?ie a gestiona serializare în dou? formate, dar poate fi situa?ii în care este necesar s? se intervin? în reprezentarea resurselor c?tre ?i de la client. Am vedea mai jos cum putem interveni.

Personalizarea rezultate JSON

În ceea ce prive?te reprezentarea în JSON, se efectueaz? de c?tre mass-media JsonMediaTypeFormatter formatorului, care se bazeaz? pe Json.NET bibliotec?.Alegerea acestei biblioteca pentru a face parte din echipa de dezvoltare este dictat? de motive de flexibilitate ?i performan??, dar dac? dintr-un motiv pe care prefera?i s? utiliza?i NET clasa. DataContractJsonSerializer, acest lucru poate fi f?cut cu urm?toarele instruc?iuni pentru a insera la metoda Application_Start () în Global.asax:

var json = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
json.UseDataContractJsonSerializer = true;

În mod implicit, toate câmpurile publice ?i propriet??i ale unei resurse sunt incluse în serializare. Pentru a preveni un câmp sau a propriet??ii care urmeaz? s? fie incluse în procesul de serializare, putem specifica atributul JsonIgnore, ca în urm?torul exemplu:

public class Item
{
****public string term { get; set; }
****public string definition { get; set; }
****[JsonIgnore]
****public string code { get; set; }
}

Acest lucru va asigura faptul c? cod nu este inclus în versiunea JSON a resurselor pentru a trimite la client.

Un alt aspect controlabile serializare JSON este generarea de date.Formatul implicit al Json.NET este cel prev?zut de standardul ISO 8601. De exemplu, în conformitate cu acest standard, datele sunt reprezentate ca ?ir similar? în 2012-06-23T12: 59:22 Z

Dac? prefera?i formatul Microsoft în forma \ / Data (1234) \ / ar trebui s? se aplice urm?toarele set?ri:

var json = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
json.SerializerSettings.DateFormatHandling
****= Newtonsoft.Json.DateFormatHandling.MicrosoftDateFormat;

Customize riusultati XML

Chiar ?i pentru serializarea în XML, pute?i face particulariz?ri. De exemplu, dac? în loc de default clasa DataContractSerializer vrut s? foloseasc? XmlSerializer, ar trebui s? ne scrie instruc?iunile de mai jos:

var xml = GlobalConfiguration.Configuration.Formatters.XmlFormatter;
xml.UseXmlSerializer = true;

Pentru serializarea XML este furnizat, de asemenea, posibilitatea de a alege un serializer diferite în func?ie de tipul de resurs? pentru a reprezenta. În urm?torul exemplu vom folosi numai pentru XmlSerializer clasa postul, p?strând serializer implicit pentru orice alte resurse gestionate de API-ul nostru:

var xml = GlobalConfiguration.Configuration.Formatters.XmlFormatter;
xml.SetSerializer<item>(new XmlSerializer(typeof(Item)));
</item>

Pentru a avea mai mult control asupra ambelor tipuri de serializare, pute?i alege o abordare explicit? bazat? pe utilizarea atributelor DataContract ?i DataMember. De fapt, în timp ce în mod normal, serializarea resursa este implicat, c? o resurs? este serializat în conformitate cu normele stabilite de c?tre mass-media specifice formatorului, cu o abordare explicit? ne s? spunem ceea ce poate fi serializat ?i cum.

Lua?i în considerare urm?torul cod:

[DataContract]
public class Item
{
[DataMember]
private int id;

[DataMember]
public string term { get; set; }
[DataMember]
public string definition { get; set; }
[DataMember(Name="topic")]
public string category { get; set; }
public string code { get; set; }
}

Atributul DataContract indic? faptul c? clasa este serializat, urmând instruc?iunile oferite de dezvoltator. Dac? nu se specific? acest atribut, orice asocia?ie atribut DataMember la membrii clasei vor fi ignorate. Numai membrii marcate de DataMember atributul vor fi luate în considerare de c?tre serializer, indiferent de accesibilitatea lor.

În cazul nostru, de aceea, vom include câmpul ID ?i propriet??ile termen, defini?ie, ?i categorie. Pentru proprietatea din urm?, în special, va genera numele subiect în loc de categorii.

În rezumat, un exemplu de serializare în JSON din aceast? clas? ar putea fi urm?toarele:

{** "id":"123"
****"term":"API",
****"definition":"Insieme di subroutine o di funzioni che ...",
****"topic":"Programming"
}

9 : Create new media formatter

Dac? avem nevoie pentru a genera reprezentari într-un format diferit de resurse JSON ?i XML gestionate de API-ul nostru, putem crea propriul nostru formatorului mass-media.

S? vedem cum de a utiliza acest presupunând c? vrei s? genereze intr?ri noastre glosar în format CSV.

În primul rând, a crea un folder de formatare în cadrul proiectului nostru ?i introduce?i un ItemCSVFormatter clas?. A?a cum am men?ionat la începutul acestui ghid, de creare a directorului nu este strict necesar, dar ar trebui s? crea?i pentru a organiza mai bine diferitele elemente ale proiectului nostru.

O formatare mass-media este o clasa care poate rezulta din una dintre urm?toarele clase: MediaTypeFormatter sau BufferedMediaTypeFormatter.Primul foloseste metode asincrone de citire ?i scriere în timp ce al doilea sprijin? o abordare sincron.

În cazul nostru, vom folosi abordarea sincron?, deoarece este mai u?or ?i bloca firul de asteptare in timp ce I / O este neglijabil? având în vedere dimensiunea redus? a obiectelor care urmeaz? s? fie serializate ?i deserialized.

De aceea, vom defini clasa noastra, dup? cum urmeaz?:

using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Http.Formatting;
using System.Net.Http.Headers;
using Glossario.Models;

namespace Glossario.Formatters
{
public class ItemCSVFormatter : BufferedMediaTypeFormatter
{
}
}

Indichiamo poi nel costruttore della classe i media-type supportati:

public ItemCSVFormatter()
{
SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/csv"));
}

Redefini?i CanWriteType metoda () pentru a indica ce tipuri de obiecte formatorului nostru este capabil de a serializa:

public override bool CanWriteType(System.Type type)
{
if (type == typeof(Item))
{
return true;
}
else
{
Type enumerableType = typeof(IEnumerable<Item>);
return enumerableType.IsAssignableFrom(type);
}
}

Aceast? metod? prime?te un tip ca un parametru ?i returneaz? o valoare booleana care determin? dac? accept? clasa. Dup? cum pute?i vedea din cod, formatorul nostru mass-media sprijin? serializare a unui singur obiect, care este o list? de obiecte de Tip articol.

În mod similar, pentru a indica tipurile de obiecte care formatorului nostru poate efectua deserialize suprascrie CanReadType ():

public override bool CanReadType(System.Type type)
{
****if (type == typeof(Item))
****{
********return true;
****}
****else
****{
********Type enumerableType = typeof(IEnumerable<Item>);
********return enumerableType.IsAssignableFrom(type);
****}
}

Dup? cum putem vedea punerea în aplicare este identic cu cel al CanWriteType (), pentru care ar fi oportun s? se concentreze codul într-o func?ie privat? ?i îl numesc pân? ambele metode.

Serializarea ?i Deserialization

La acest punct vom trece la punerea în aplicare efectiv? de serializare ?i a opera?iunilor deserialization. Pentru serializarea trebuie s? suprascrie metoda WriteToStream (), ca în exemplul urm?tor:

public override void WriteToStream(Type type, object value, Stream stream, HttpContentHeaders contentHeaders)
{
****using (var writer = new StreamWriter(stream))
****{
********var items = value as IEnumerable<Item>;
********if (items != null)
********{
************foreach (var myItem in items)
************{
****************WriteItem(myItem, writer);
************}
********}
********else
********{
************var singleItem = value as Item;
************if (singleItem == null)
************{
****************throw new InvalidOperationException("Cannot serialize type");
************}
************WriteItem(singleItem, writer);
********}
****}
****stream.Close();
}

În rezumat, metoda returneaz? o list? de rânduri sau un singur rând CSV în func?ie de valoarea primit? în intrare.Serializarea valabil pentru fiecare obiect este realizat? de WriteItem func?ia ():

private void WriteItem(Item myItem, StreamWriter writer)
{
****writer.WriteLine("\"{0}\",\"{1}\",\"{2}\"", Escape(myItem.term),
****Escape(myItem.definition), Escape(myItem.category));
}
*
static char[] _specialChars = new char[] { ',', '\n', '\r', '"' };
*
private string Escape(object o)
{
****if (o == null)
****{
********return "";
****}
****string field = o.ToString();
****if (field.IndexOfAny(_specialChars) != -1)
****{
********return String.Format("\"{0}\"", field.Replace("\"", "\"\""));
****}
****else return field;
}

Astfel cum rezult? din cod, WriteItem function () folose?te un Escape () func?ia s? se ocupe de caractere speciale, cum ar fi virgule, se întoarce transport, etc.

În mod similar, pentru a pune în aplicare deserialization redefini ReadFromStream metoda ():

public override object ReadFromStream(Type type, Stream stream, HttpContentHeaders contentHeaders, IFormatterLogger formatterLogger)
{
****object result;
*
****using (var reader = new StreamReader(stream))
****{
********var CSVText = reader.ReadToEnd();
********var itemLinesArray = CSVText.Split('\n');
********var itemsCount = itemLinesArray.Length;
********Item[] itemArray;
*
********if (itemsCount == 1)
********{
************result = ReadItem(itemLinesArray[0]);
********}
********else
********{
************itemArray = new Item[itemsCount];
************for (var i = 0; i < itemsCount;i++ )
************{
****************itemArray[i] = ReadItem(itemLinesArray[i]);
************}
************result = itemArray;
********}
****}
****stream.Close();
*
****return result;
}

De asemenea, în acest caz, avem în vedere dou? situa?ii legate de un singur obiect sau la o list? de obiecte.Deserialization real? a obiectului individual este realizat de ReadItem func?ia ():

private Item ReadItem(string itemLine)
{
****var itemArray = itemLine.Replace("\"","").Split(',');
****Item myItem = new Item();
*
****myItem.term = itemArray[0];
****myItem.definition = itemArray[1];
****myItem.category = itemArray[2];
*
****return myItem;
}

În acest moment formatorului nostru media este gata. Trebuie doar s?-l integreze în sistemul în a?a fel încât, în conformitate cu solicit?rile clientului, poate reprezenta vocile glosarul nostru în format CSV. Pentru a face acest lucru, pur ?i simplu introduce?i urm?toarea declara?ie la Application_Start metoda ()

în Global.asax: 
protected void Application_Start()
{
...
GlobalConfiguration.Configuration.Formatters.Add(new Glossario.Formatters.ItemCSVFormatter());
...
}

Rezultatul ob?inut de c?tre un client care specific? textul / con?inutul negociere CSV va fi similar cu cel prezentat în figura de mai jos:

print7y.png

SURSA : Guida ASP.NET WEB API | .NET, Development | HTML.it

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...