Odesílání dat formuláře HTML ve webovém rozhraní API ASP.NET: Data s kódem url formuláře

Část 1: Data ve formátu urlencoded

Tento článek ukazuje, jak publikovat data s kódem urlencoded formuláře do kontroleru webového rozhraní API.

Přehled formulářů HTML

Formuláře HTML používají k odesílání dat na server příkaz GET nebo POST. Atribut method elementu form poskytuje metodu HTTP:

<form action="api/values" method="post">

Výchozí metoda je GET. Pokud formulář používá funkci GET, data formuláře se kódují v identifikátoru URI jako řetězec dotazu. Pokud formulář používá post, data formuláře se umístí do textu požadavku. Pro posted data určuje atribut enctype formát textu požadavku:

enctype Description
application/x-www-form-urlencoded Data formuláře se kódují jako páry název/hodnota, podobně jako řetězec dotazu URI. Toto je výchozí formát pro POST.
multipart/form-data Data formuláře jsou kódována jako zpráva MIME s více částmi. Tento formát použijte, pokud nahráváte soubor na server.

Část 1 tohoto článku se zabývá formátem x-www-form-urlencoded. Část 2 popisuje vícedílné MIME.

Odesílání komplexních typů

Obvykle odešlete komplexní typ, který se skládá z hodnot převzatých z několika ovládacích prvků formuláře. Představte si následující model, který představuje aktualizaci stavu:

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; }
    }
}

Tady je kontroler webového rozhraní API, který přijímá Update objekt přes 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);
            }
        }

    }
}

Poznámka

Tento kontroler používá směrování na základě akcí, takže šablona trasy je api/{controller}/{action}/{id}. Klient odešle data do souboru /api/updates/complex.

Teď napíšeme formulář HTML, který uživatelům umožní odeslat aktualizaci stavu.

<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>

Všimněte si, že atribut action ve formuláři je identifikátorem URI akce kontroleru. Tady je formulář s některými zadanými hodnotami:

Snímek obrazovky s formulářem Komplexní typ H T M L s polem Stav a polem Datum vyplněné hodnotami

Když uživatel klikne na Odeslat, prohlížeč odešle požadavek HTTP podobný následujícímu:

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

Všimněte si, že text požadavku obsahuje data formuláře formátovaná jako páry název/hodnota. Webové rozhraní API automaticky převede páry název/hodnota na instanci Update třídy.

Odesílání dat formuláře přes AJAX

Když uživatel odešle formulář, prohlížeč přejde mimo aktuální stránku a vykreslí text zprávy s odpovědí. To je v pořádku, pokud je odpovědí stránka HTML. U webového rozhraní API je ale tělo odpovědi obvykle buď prázdné, nebo obsahuje strukturovaná data, například JSON. V takovém případě je vhodnější odeslat data formuláře pomocí požadavku AJAX, aby stránka mohl zpracovat odpověď.

Následující kód ukazuje, jak publikovat data formuláře pomocí 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>

Funkce jQuery submit nahradí akci formuláře novou funkcí. Tím se přepíše výchozí chování tlačítka Odeslat. Funkce serializace serializuje data formuláře do dvojic název/hodnota. Pokud chcete odeslat data formuláře na server, zavolejte .$.post()

Po dokončení požadavku zobrazí obslužná rutina .success() nebo .error() uživateli příslušnou zprávu.

Snímek obrazovky s formulářem Komplexní typ H T M L s chybou místního hostitele zobrazenou tučným písmem pro uživatele

Odesílání jednoduchých typů

V předchozích částech jsme odeslali komplexní typ, který webové rozhraní API deserializovalo do instance třídy modelu. Můžete také posílat jednoduché typy, například řetězec.

Poznámka

Před odesláním jednoduchého typu zvažte zabalení hodnoty do komplexního typu. Získáte tak výhody ověření modelu na straně serveru a v případě potřeby ho můžete snadněji rozšířit.

Základní kroky pro odeslání jednoduchého typu jsou stejné, ale existují dva drobné rozdíly. Nejprve v kontroleru musíte název parametru opatřovat atributem 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);
    }

Ve výchozím nastavení se webové rozhraní API pokusí získat jednoduché typy z identifikátoru URI požadavku. Atribut FromBody říká webovému rozhraní API, aby přečetlo hodnotu z textu požadavku.

Poznámka

Webové rozhraní API čte text odpovědi maximálně najednou, takže z textu požadavku může pocházet jenom jeden parametr akce. Pokud potřebujete získat více hodnot z textu požadavku, definujte komplexní typ.

Za druhé, klient musí odeslat hodnotu v následujícím formátu:

=value

Konkrétně musí být část názvu v páru název/hodnota pro jednoduchý typ prázdná. Ne všechny prohlížeče to podporují pro formuláře HTML, ale tento formát vytvoříte ve skriptu následujícím způsobem:

$.post('api/updates/simple', { "": $('#status1').val() });

Tady je příklad formuláře:

<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>

A tady je skript pro odeslání hodnoty formuláře. Jediným rozdílem oproti předchozímu skriptu je argument předaný do funkce 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;
});

Stejný přístup můžete použít k odeslání pole jednoduchých typů:

$.post('api/updates/postlist', { "": ["update one", "update two", "update three"] });

Další materiály

Část 2: Nahrávání souborů a vícedílné mime