Nell'articolo di seguito, spiegheremo come pubblicare dati di un modulo codificati in formato URL su un controller di API web. Questo processo è utile quando si desidera inviare dati da un modulo HTML al server utilizzando una richiesta HTTP POST.
Panoramica dei form HTML
I form HTML possono utilizzare il metodo GET o POST per inviare dati al server. Il metodo predefinito è GET, che codifica i dati del modulo nell'URI come una stringa di query. Se il form utilizza il metodo POST, i dati del modulo vengono inseriti nel corpo della richiesta. Per i dati inviati tramite POST, l'attributo enctype specifica il formato del corpo della richiesta.
Il formato x-www-form-urlencoded è il formato predefinito per i dati di un modulo inviati tramite POST. In questo formato, i dati del modulo vengono codificati come coppie nome/valore, simili a una stringa di query dell'URI.
Invio di tipi complessi
Quando si invia un tipo complesso, che consiste in valori estratti da più controlli di un modulo, è necessario considerare la struttura del modello di dati. Ad esempio, supponiamo di avere il seguente modello di dati per una "Update":
namespace FormEncode.Models
{
using System;
using System.ComponentModel.DataAnnotations;
public class Update
{
[Required]
[MaxLength(140)]
public string Status { get; set; }
public DateTime Date { get; set; }
}
}
Di seguito è riportato un esempio di un controller di API web che accetta un oggetto "Update" tramite una richiesta POST:
namespace FormEncode.Controllers
{
using FormEncode.Models;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Web;
using System.Web.Http;
public class UpdatesController : ApiController
{
static readonly Dictionary<Guid, Update> updates = new Dictionary<Guid, Update>();
[HttpPost]
[ActionName("Complex")]
public HttpResponseMessage PostComplex(Update update)
{
if (ModelState.IsValid && update != null)
{
// Convert any HTML markup in the status text.
update.Status = HttpUtility.HtmlEncode(update.Status);
// Assign a new ID.
var id = Guid.NewGuid();
updates[id] = update;
// Create a 201 response.
var response = new HttpResponseMessage(HttpStatusCode.Created)
{
Content = new StringContent(update.Status)
};
response.Headers.Location = new Uri(Url.Link("DefaultApi", new { action = "status", id = id }));
return response;
}
else
{
return Request.CreateResponse(HttpStatusCode.BadRequest);
}
}
[HttpGet]
public Update Status(Guid id)
{
Update update;
if (updates.TryGetValue(id, out update))
{
return update;
}
else
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
}
}
}
Invio di dati di un modulo tramite AJAX
Quando un utente invia un modulo, il browser si sposta dalla pagina attiva e mostra il corpo della risposta. Tuttavia, con un'API web, il corpo della risposta di solito è vuoto o contiene dati strutturati, come JSON. In questo caso, è più conveniente inviare i dati del modulo utilizzando una richiesta AJAX, in modo che la pagina possa gestire la risposta senza dover ricaricare l'intera pagina.
Il seguente codice mostra come inviare dati di un modulo utilizzando jQuery:
$("#form1").submit(function () {
var jqxhr = $.post('api/updates/complex', $('#form1').serialize())
.success(function () {
var loc = jqxhr.getResponseHeader('Location');
var a = $('<a/>', { href: loc, text: loc });
$('#message').html(a);
})
.error(function () {
$('#message').html("Errore durante l'invio dell'aggiornamento.");
});
return false;
});
La funzione di invio di jQuery sostituisce l'azione del modulo con una nuova funzione. Ciò modifica il comportamento predefinito del pulsante di invio. La funzione serialize
serializza i dati del modulo come coppie nome/valore. Per inviare i dati del modulo al server, viene chiamato $.post()
.
Una volta completata la richiesta, il gestore .success()
o .error()
mostra un messaggio appropriato all'utente.
Invio di tipi semplici
Nelle sezioni precedenti, abbiamo inviato un tipo complesso che viene deserializzato dall'API web in un'istanza di una classe di modello. Tuttavia, è anche possibile inviare tipi semplici, come una stringa.
Prima di inviare un tipo semplice, è consigliabile considerare l'incapsulamento del valore in un tipo complesso. Ciò offre i vantaggi della convalida del modello lato server e semplifica l'estensione del modello, se necessario.
Le fasi di base per inviare un tipo semplice sono le stesse, ma ci sono due differenze sottili. In primo luogo, nel controller, è necessario decorare il nome del parametro con l'attributo [FromBody]
:
[HttpPost]
[ActionName("Simple")]
public HttpResponseMessage PostSimple([FromBody] string value)
{
if (value != null)
{
Update update = new Update()
{
Status = HttpUtility.HtmlEncode(value),
Date = DateTime.UtcNow
};
var id = Guid.NewGuid();
updates[id] = update;
var response = new HttpResponseMessage(HttpStatusCode.Created)
{
Content = new StringContent(update.Status)
};
response.Headers.Location = new Uri(Url.Link("DefaultApi", new { action = "status", id = id }));
return response;
}
else
{
return Request.CreateResponse(HttpStatusCode.BadRequest);
}
}
Per impostazione predefinita, l'API web cerca di ottenere i tipi semplici dall'URI della richiesta. L'attributo [FromBody]
indica all'API web di leggere il valore dal corpo della richiesta.
In secondo luogo, il client deve inviare il valore nel seguente formato: =value
. In particolare, la parte del nome della coppia nome/valore deve essere vuota per un tipo semplice. Non tutti i browser lo supportano per i form HTML, ma è possibile creare questo formato in uno script come segue:
$.post('api/updates/simple', { "": $('#status1').val() });
Ecco un esempio di un modulo HTML per inviare un tipo semplice:
<h1>Tipo semplice</h1>
<form id="form2">
<div>
<label for="status">Stato</label>
</div>
<div>
<input id="status1" type="text" />
</div>
<div>
<input type="submit" value="Invia" />
</div>
</form>
Lo script seguente invia il valore del modulo. L'unica differenza rispetto allo script precedente è l'argomento passato alla funzione post
:
$('#form2').submit(function () {
var jqxhr = $.post('api/updates/simple', { "": $('#status1').val() })
.success(function () {
var loc = jqxhr.getResponseHeader('Location');
var a = $('<a/>', { href: loc, text: loc });
$('#message').html(a);
})
.error(function () {
$('#message').html("Errore durante l'invio dell'aggiornamento.");
});
return false;
});
È possibile utilizzare lo stesso approccio per inviare un array di tipi semplici:
$.post('api/updates/postlist', { "": ["aggiornamento uno", "aggiornamento due", "aggiornamento tre"] });
Conclusioni
In questo articolo, abbiamo esaminato come pubblicare dati di un modulo codificati in formato URL su un controller di API web. Abbiamo discusso dei form HTML, dell'invio di tipi complessi e semplici, nonché dell'invio di dati di un modulo tramite AJAX. Speriamo che queste informazioni ti siano state utili per comprendere come gestire l'invio di dati di un modulo in un'applicazione web.