ASP.NET Web API'sinde HTML Form Verileri Gönderme: Form-urlencoded Data

Bölüm 1: Form urlencoded Verileri

Bu makalede, form urlencoded verilerinin bir Web API denetleyicisine nasıl gönderıldığı gösterilmektedir.

HTML Formlara Genel Bakış

HTML formları, sunucuya veri göndermek için GET veya POST kullanır. form öğesinin method özniteliği HTTP yöntemini verir:

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

Varsayılan yöntem GET'dir. Form GET kullanıyorsa, form verileri URI'de sorgu dizesi olarak kodlanır. Form POST kullanıyorsa, form verileri istek gövdesine yerleştirilir. POSTed verileri için enctype özniteliği istek gövdesinin biçimini belirtir:

enctype Description
application/x-www-form-urlencoded Form verileri, URI sorgu dizesine benzer şekilde ad/değer çiftleri olarak kodlanır. Bu, POST için varsayılan biçimdir.
multipart/form-data Form verileri çok parçalı bir MIME iletisi olarak kodlanır. Sunucuya dosya yüklüyorsanız bu biçimi kullanın.

Bu makalenin 1. bölümünde x-www-form-urlencoded biçimine bakılır. 2. Bölüm , çok parçalı MIME'leri açıklar.

Karmaşık Türler Gönderme

Genellikle, çeşitli form denetimlerinden alınan değerlerden oluşan karmaşık bir tür gönderirsiniz. Durum güncelleştirmesini temsil eden aşağıdaki modeli göz önünde bulundurun:

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

Post aracılığıyla bir nesneyi kabul eden bir Update Web API denetleyicisi aşağıda verilmiştir.

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

    }
}

Not

Bu denetleyici eylem tabanlı yönlendirme kullandığından, yol şablonu "api/{controller}/{action}/{id}" şeklindedir. İstemci verileri "/api/updates/complex" adresine gönderir.

Şimdi kullanıcıların durum güncelleştirmesi göndermesi için bir HTML formu yazalım.

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

Formdaki eylem özniteliğinin denetleyici eylemimizin URI'sine sahip olduğuna dikkat edin. Bazı değerlerin girilmiş olduğu form aşağıdadır:

Durum alanı ve değerlerle doldurulmuş bir Tarih alanı içeren Karmaşık Tür H T M L formunun ekran görüntüsü.

Kullanıcı Gönder'e tıkladığında tarayıcı aşağıdakine benzer bir HTTP isteği gönderir:

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

İstek gövdesinin ad/değer çiftleri olarak biçimlendirilmiş form verilerini içerdiğine dikkat edin. Web API'sinde ad/değer çiftleri otomatik olarak sınıfın bir örneğine Update dönüştürülür.

AJAX Aracılığıyla Form Verileri Gönderme

Kullanıcı form gönderdiğinde, tarayıcı geçerli sayfadan uzaklaşır ve yanıt iletisinin gövdesini işler. Yanıt bir HTML sayfası olduğunda bu sorun olmaz. Ancak bir web API'si ile yanıt gövdesi genellikle boş olur veya JSON gibi yapılandırılmış veriler içerir. Bu durumda, sayfanın yanıtı işleyebilmesi için form verilerini bir AJAX isteği kullanarak göndermek daha mantıklıdır.

Aşağıdaki kod, jQuery kullanarak form verilerinin nasıl gönder yapılacağını gösterir.

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

jQuery submit işlevi, form eylemini yeni bir işlevle değiştirir. Bu, Gönder düğmesinin varsayılan davranışını geçersiz kılar. seri hale getirme işlevi form verilerini ad/değer çiftleri halinde serileştirir. Form verilerini sunucuya göndermek için çağrısında bulunur $.post().

İstek tamamlandığında, .success() veya .error() işleyicisi kullanıcıya uygun bir ileti görüntüler.

Kullanıcıya kalın metin olarak görüntülenen yerel bir konak hatasıyla Birlikte Karmaşık Tür H T M L formunun ekran görüntüsü.

Basit Türler Gönderme

Önceki bölümlerde, Web API'sinin model sınıfı örneğine seri durumdan çıkarıldığı karmaşık bir tür gönderdik. Dize gibi basit türler de gönderebilirsiniz.

Not

Basit bir tür göndermeden önce, bunun yerine değeri karmaşık bir türe sarmalamayı göz önünde bulundurun. Bu, sunucu tarafında model doğrulamanın avantajlarını sunar ve gerekirse modelinizi genişletmeyi kolaylaştırır.

Basit bir tür göndermenin temel adımları aynıdır, ancak iki küçük fark vardır. İlk olarak, denetleyicide parametre adını FromBody özniteliğiyle süslemeniz gerekir.

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

Web API'si varsayılan olarak istek URI'sinden basit türler almaya çalışır. FromBody özniteliği Web API'sine isteğin gövdesinden değeri okumasını söyler.

Not

Web API'si yanıt gövdesini en çok bir kez okur, bu nedenle bir eylemin yalnızca bir parametresi istek gövdesinden gelebilir. İstek gövdesinden birden çok değer almanız gerekiyorsa karmaşık bir tür tanımlayın.

İkincisi, istemcinin değeri aşağıdaki biçimde göndermesi gerekir:

=value

Özellikle, ad/değer çiftinin ad bölümü basit bir tür için boş olmalıdır. Tüm tarayıcılar HTML formları için bunu desteklemez, ancak bu biçimi betikte aşağıdaki gibi oluşturursunuz:

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

Örnek bir form aşağıda verilmiştir:

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

Form değerini göndermek için betiği de burada bulabilirsiniz. Önceki betikten tek fark post işlevine geçirilen bağımsız değişkendir.

$('#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;
});

Basit türlerden oluşan bir dizi göndermek için aynı yaklaşımı kullanabilirsiniz:

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

Ek Kaynaklar

Bölüm 2: Dosya Yükleme ve Çok Parçalı MIME