Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Część 1: Dane zakodowane jako Form-urlencoded
W tym artykule pokazano, jak przesyłać dane zakodowane w formacie form-urlencoded do kontrolera interfejsu API sieci Web.
- Omówienie formularzy HTML
- Wysyłanie typów złożonych
- Wysyłanie danych formularza za pośrednictwem technologii AJAX
- Wysyłanie typów prostych
Uwaga / Notatka
Omówienie formularzy HTML
Formularze HTML używają metody GET lub POST do wysyłania danych na serwer. Atrybut metody elementu formularza daje metodę HTTP:
<form action="api/values" method="post">
Domyślną metodą jest GET. Jeśli formularz używa metody GET, dane formularza są kodowane w identyfikatorze URI jako ciąg zapytania. Jeśli formularz używa funkcji POST, dane formularza są umieszczane w treści żądania. W przypadku danych POSTed atrybut entype określa format treści żądania:
| typ kodowania | Opis |
|---|---|
| application/x-www-form-urlencoded | Dane formularza są kodowane jako pary nazwa/wartość, podobnie jak ciąg zapytania identyfikatora URI. Jest to domyślny format post. |
| multipart/form-data | Dane formularza są kodowane jako wieloczęściowy komunikat MIME. Użyj tego formatu, jeśli przekazujesz plik na serwer. |
Część 1 tego artykułu dotyczy formatu x-www-form-urlencoded. Część 2 opisuje wieloczęściowy MIME.
Wysyłanie typów złożonych
Zazwyczaj wysyła się typ złożony składający się z wartości pobranych z kilku kontrolek formularza. Rozważmy następujący model reprezentujący aktualizację stanu:
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; }
}
}
Oto kontroler internetowego interfejsu API, który akceptuje Update obiekt za pośrednictwem funkcji 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);
}
}
}
}
Uwaga / Notatka
Ten kontroler używa routingu opartego na akcjach, więc szablon trasy to "api/{controller}/{action}/{id}". Klient opublikuje dane w pliku "/api/updates/complex".
Teraz napiszmy formularz HTML, aby użytkownicy przesyłali aktualizację stanu.
<h1>Complex Type</h1>
<form id="form1" method="post" action="api/updates/complex"
enctype="application/x-www-form-urlencoded">
<div>
<label for="status">Status</label>
</div>
<div>
<input name="status" type="text" />
</div>
<div>
<label for="date">Date</label>
</div>
<div>
<input name="date" type="text" />
</div>
<div>
<input type="submit" value="Submit" />
</div>
</form>
Zwróć uwagę, że atrybut akcji w formularzu jest identyfikatorem URI akcji kontrolera. Oto formularz z pewnymi wartościami wprowadzonymi w:
Gdy użytkownik kliknie przycisk Prześlij, przeglądarka wyśle żądanie HTTP podobne do następującego:
POST http://localhost:38899/api/updates/complex HTTP/1.1
Accept: text/html, application/xhtml+xml, */*
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)
Content-Type: application/x-www-form-urlencoded
Content-Length: 47
status=Shopping+at+the+mall.&date=6%2F15%2F2012
Zwróć uwagę, że treść żądania zawiera dane formularza sformatowane jako pary nazwa/wartość. Internetowy interfejs API automatycznie konwertuje pary nazw/wartości na wystąpienie Update klasy.
Wysyłanie danych formularza za pośrednictwem technologii AJAX
Gdy użytkownik prześle formularz, przeglądarka odchodzi od bieżącej strony i renderuje treść komunikatu odpowiedzi. Jest to ok, gdy odpowiedź jest stroną HTML. Jednak w przypadku internetowego interfejsu API treść odpowiedzi jest zwykle pusta lub zawiera dane ustrukturyzowane, takie jak JSON. W takim przypadku warto wysłać dane formularza przy użyciu żądania AJAX, aby strona mogła przetworzyć odpowiedź.
Poniższy kod pokazuje, jak publikować dane formularza przy użyciu zapytania jQuery.
<script type="text/javascript">
$("#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("Error posting the update.");
});
return false;
});
</script>
Funkcja jQuery submit zastępuje akcję formularza nową funkcją. Spowoduje to zastąpienie domyślnego zachowania przycisku Prześlij. Funkcja serialize serializuje dane formularza do par nazwa/wartość. Aby wysłać dane formularza do serwera, wywołaj metodę $.post().
Po zakończeniu żądania, program obsługi .success() lub .error() wyświetla odpowiedni komunikat użytkownikowi.
Wysyłanie typów prostych
W poprzednich sekcjach wysłaliśmy typ złożony, który internetowy interfejs API deserializował do wystąpienia klasy modelu. Można również wysyłać proste typy, takie jak ciąg.
Uwaga / Notatka
Przed wysłaniem prostego typu rozważ opakowanie wartości w typ złożony. Zapewnia to korzyści z weryfikacji modelu po stronie serwera i ułatwia rozszerzanie modelu w razie potrzeby.
Podstawowe kroki wysyłania prostego typu danych są takie same, ale istnieją dwie subtelne różnice. Najpierw w kontrolerze należy udekorować nazwę parametru za pomocą atrybutu 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);
}
Domyślnie Web API próbuje uzyskać proste typy z URI żądania. Atrybut FromBody informuje internetowy interfejs API o odczytaniu wartości z treści żądania.
Uwaga / Notatka
Internetowy interfejs API odczytuje treść odpowiedzi co najwyżej raz, więc tylko jeden parametr akcji może pochodzić z treści żądania. Jeśli musisz pobrać wiele wartości z treści żądania, zdefiniuj typ złożony.
Po drugie, klient musi wysłać wartość w następującym formacie:
=value
W szczególności część nazwy w parze nazwa/wartość musi być pusta dla prostego typu. Nie wszystkie przeglądarki obsługują tę funkcję dla formularzy HTML, ale ten format można utworzyć w skryfcie w następujący sposób:
$.post('api/updates/simple', { "": $('#status1').val() });
Oto przykładowy formularz:
<h1>Simple Type</h1>
<form id="form2">
<div>
<label for="status">Status</label>
</div>
<div>
<input id="status1" type="text" />
</div>
<div>
<input type="submit" value="Submit" />
</div>
</form>
Oto skrypt do przesłania wartości formularza. Jedyną różnicą z poprzedniego skryptu jest argument przekazany do funkcji 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("Error posting the update.");
});
return false;
});
Możesz użyć tego samego podejścia do wysyłania tablicy prostych typów:
$.post('api/updates/postlist', { "": ["update one", "update two", "update three"] });