Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Teil 1: Form-urlencodierte Daten
In diesem Artikel wird gezeigt, wie Sie formular-urlencodierte Daten an einen Web-API-Controller senden.
- Übersicht über HTML-Formulare
- Senden komplexer Typen
- Senden von Formulardaten über AJAX
- Senden einfacher Typen
Übersicht über HTML-Formulare
HTML-Formulare verwenden ENTWEDER GET oder POST, um Daten an den Server zu senden. Das Methodenattribute des Formularelements gibt die HTTP-Methode an:
<form action="api/values" method="post">
Die Standardmethode ist GET. Wenn das Formular GET verwendet, werden die Formulardaten im URI als Abfragezeichenfolge codiert. Wenn das Formular POST verwendet, werden die Formulardaten im Anforderungstext abgelegt. Für POSTed-Daten gibt das Attribut "enctype " das Format des Anforderungstexts an:
| Enctype | Beschreibung |
|---|---|
| application/x-www-form-urlencoded | Formulardaten werden als Name-Wert-Paare codiert, ähnlich wie eine URI-Abfragezeichenfolge. Dies ist das Standardformat für POST. |
| Mehrteilige/Formulardaten | Formulardaten werden als mehrteilige MIME-Nachricht codiert. Verwenden Sie dieses Format, wenn Sie eine Datei auf den Server hochladen. |
Teil 1 dieses Artikels befasst sich mit dem x-www-form-urlencoded-Format. Teil 2 beschreibt mehrteiliges MIME.
Senden komplexer Typen
Normalerweise senden Sie einen komplexen Typ, der aus Werten besteht, die von mehreren Formularsteuerelementen stammen. Betrachten Sie das folgende Modell, das eine Statusaktualisierung darstellt:
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; }
}
}
Hier ist ein Web-API-Controller, der ein Update Objekt über POST akzeptiert.
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);
}
}
}
}
Hinweis
Dieser Controller verwendet aktionsbasiertes Routing, sodass die Routenvorlage "api/{controller}/{action}/{id}" lautet. Der Client sendet die Daten in "/api/updates/complex".
Jetzt schreiben wir ein HTML-Formular für Benutzer, um eine Statusaktualisierung zu senden.
<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>
Beachten Sie, dass das Aktions-Attribut im Formular der URI unserer Controlleraktion ist. Hier ist das Formular mit einigen eingegebenen Werten:
Wenn der Benutzer auf "Absenden" klickt, sendet der Browser eine HTTP-Anforderung ähnlich wie folgt:
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
Beachten Sie, dass der Anforderungstext die Formulardaten enthält, die als Name-Wert-Paare formatiert sind. Die Web-API konvertiert automatisch die Namen-Wert-Paare in eine Instanz der Update Klasse.
Senden von Formulardaten über AJAX
Wenn ein Benutzer ein Formular sendet, navigiert der Browser von der aktuellen Seite ab und rendert den Textkörper der Antwortnachricht. Das ist ok, wenn die Antwort eine HTML-Seite ist. Bei einer Web-API ist der Antworttext jedoch in der Regel leer oder enthält strukturierte Daten, z. B. JSON. In diesem Fall ist es sinnvoller, die Formulardaten mithilfe einer AJAX-Anforderung zu senden, damit die Seite die Antwort verarbeiten kann.
Der folgende Code zeigt, wie Formulardaten mithilfe von jQuery gepostt werden.
<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>
Die jQuery Submit-Funktion ersetzt die Formularaktion durch eine neue Funktion. Dadurch wird das Standardverhalten der Schaltfläche "Absenden" außer Kraft gesetzt. Die Serialisierungsfunktion serialisiert die Formulardaten in Name-Wert-Paare. Rufen Sie $.post()auf, um die Formulardaten an den Server zu senden.
Wenn die Anforderung abgeschlossen ist, zeigt der .success().error() Handler dem Benutzer eine entsprechende Meldung an.
Senden einfacher Typen
In den vorherigen Abschnitten haben wir einen komplexen Typ gesendet, den die Web-API an eine Instanz einer Modellklasse deserialisiert hat. Sie können auch einfache Typen senden, z. B. eine Zeichenfolge.
Hinweis
Bevor Sie einen einfachen Typ senden, sollten Sie stattdessen den Wert in einen komplexen Typ umschließen. Dadurch erhalten Sie die Vorteile der Modellüberprüfung auf serverseitiger Seite und können Ihr Modell bei Bedarf einfacher erweitern.
Die grundlegenden Schritte zum Senden eines einfachen Typs sind identisch, aber es gibt zwei subtile Unterschiede. Zuerst müssen Sie im Controller den Parameternamen mit dem FromBody-Attribut versehen.
[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);
}
Standardmäßig versucht die Web-API, einfache Typen aus dem Anforderungs-URI abzurufen. Das FromBody-Attribut weist die Web-API an, den Wert aus dem Anforderungstext zu lesen.
Hinweis
Die Web-API liest den Antworttext höchstens einmal, sodass nur ein Parameter einer Aktion aus dem Anforderungstext stammen kann. Wenn Sie mehrere Werte aus dem Anforderungstext abrufen müssen, definieren Sie einen komplexen Typ.
Zweitens muss der Client den Wert mit dem folgenden Format senden:
=value
Insbesondere muss der Namensteil des Namens-Wert-Paares für einen einfachen Typ leer sein. Nicht alle Browser unterstützen dies für HTML-Formulare, aber Sie erstellen dieses Format in Skript wie folgt:
$.post('api/updates/simple', { "": $('#status1').val() });
Hier ist ein Beispielformular:
<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>
Und hier ist das Skript zum Übermitteln des Formularwerts. Der einzige Unterschied zum vorherigen Skript ist das Argument, das an die Postfunktion übergeben wird.
$('#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;
});
Sie können denselben Ansatz verwenden, um ein Array einfacher Typen zu senden:
$.post('api/updates/postlist', { "": ["update one", "update two", "update three"] });