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ış
- Karmaşık Türler Gönderme
- AJAX Aracılığıyla Form Verileri Gönderme
- Basit Türler Gönderme
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:
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.
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"] });