ASP.NET Web API HTML 양식 데이터 보내기: Form-urlencoded 데이터
1부: 양식 urlencoded 데이터
이 문서에서는 Form-urlencoded 데이터를 Web API 컨트롤러에 게시하는 방법을 보여줍니다.
참고
완료된 프로젝트를 다운로드합니다.
HTML Forms 개요
HTML 양식은 GET 또는 POST를 사용하여 데이터를 서버로 보냅니다. form 요소의 메서드 특성은 HTTP 메서드를 제공합니다.
<form action="api/values" method="post">
기본 메서드는 GET입니다. 양식에서 GET을 사용하는 경우 양식 데이터는 URI에서 쿼리 문자열로 인코딩됩니다. 양식에서 POST를 사용하는 경우 양식 데이터는 요청 본문에 배치됩니다. POSTed 데이터의 경우 enctype 특성은 요청 본문의 형식을 지정합니다.
enctype | Description |
---|---|
application/x-www-form-urlencoded | 양식 데이터는 URI 쿼리 문자열과 유사하게 이름/값 쌍으로 인코딩됩니다. POST의 기본 형식입니다. |
multipart/form-data | 양식 데이터는 다중 파트 MIME 메시지로 인코딩됩니다. 서버에 파일을 업로드하는 경우 이 형식을 사용합니다. |
이 문서의 1부에서는 x-www-form-urlencoded 형식을 살펴봅니다. 2부 에서는 다중 파트 MIME에 대해 설명합니다.
복합 형식 보내기
일반적으로 여러 양식 컨트롤에서 가져온 값으로 구성된 복합 형식을 보냅니다. 상태 업데이트를 나타내는 다음 모델을 고려합니다.
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를 통해 개체를 Update
허용하는 Web API 컨트롤러입니다.
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);
}
}
}
}
참고
이 컨트롤러는 작업 기반 라우팅을 사용하므로 경로 템플릿은 "api/{controller}/{action}/{id}"입니다. 클라이언트는 데이터를 "/api/updates/complex"에 게시합니다.
이제 사용자가 상태 업데이트를 제출할 수 있도록 HTML 양식을 작성해 보겠습니다.
<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>
폼의 작업 특성은 컨트롤러 작업의 URI입니다. 다음은 몇 가지 값이 입력된 양식입니다.
사용자가 제출을 클릭하면 브라우저는 다음과 유사한 HTTP 요청을 보냅니다.
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
요청 본문에는 이름/값 쌍으로 서식이 지정된 양식 데이터가 포함되어 있습니다. Web API는 이름/값 쌍을 클래스의 Update
instance 자동으로 변환합니다.
AJAX를 통해 양식 데이터 보내기
사용자가 양식을 제출하면 브라우저가 현재 페이지에서 벗어나 응답 메시지의 본문을 렌더링합니다. 응답이 HTML 페이지일 때는 괜찮습니다. 그러나 웹 API를 사용하는 경우 응답 본문은 일반적으로 비어 있거나 JSON과 같은 구조화된 데이터를 포함합니다. 이 경우 페이지가 응답을 처리할 수 있도록 AJAX 요청을 사용하여 양식 데이터를 보내는 것이 더 합리적입니다.
다음 코드는 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>
jQuery submit 함수는 양식 동작을 새 함수로 바꿉니다. 이렇게 하면 제출 단추의 기본 동작이 재정의됩니다. serialize 함수는 양식 데이터를 이름/값 쌍으로 직렬화합니다. 양식 데이터를 서버로 보내려면 를 호출 $.post()
합니다.
요청이 완료되면 .success()
또는 .error()
처리기가 사용자에게 적절한 메시지를 표시합니다.
단순 형식 보내기
이전 섹션에서는 Web API가 모델 클래스의 instance 역직렬화된 복합 형식을 보냈습니다. 문자열과 같은 간단한 형식을 보낼 수도 있습니다.
참고
단순 형식을 보내기 전에 값을 복합 형식으로 래핑하는 것이 좋습니다. 이렇게 하면 서버 쪽에서 모델 유효성 검사의 이점을 얻을 수 있으며 필요한 경우 모델을 더 쉽게 확장할 수 있습니다.
간단한 형식을 보내는 기본 단계는 동일하지만 두 가지 미묘한 차이점이 있습니다. 먼저 컨트롤러에서 매개 변수 이름을 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);
}
기본적으로 Web API는 요청 URI에서 간단한 형식을 얻으려고 시도합니다. FromBody 특성은 Web API에 요청 본문에서 값을 읽도록 지시합니다.
참고
Web API는 응답 본문을 한 번에 읽으므로 작업의 매개 변수는 요청 본문에서 하나만 올 수 있습니다. 요청 본문에서 여러 값을 가져와야 하는 경우 복합 형식을 정의합니다.
둘째, 클라이언트는 다음 형식으로 값을 보내야 합니다.
=value
특히 이름/값 쌍의 이름 부분은 단순 형식에 대해 비어 있어야 합니다. 모든 브라우저가 HTML 양식에 대해 이를 지원하는 것은 아니지만 다음과 같이 스크립트에서 이 형식을 만듭니다.
$.post('api/updates/simple', { "": $('#status1').val() });
다음은 예제 양식입니다.
<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>
양식 값을 제출하는 스크립트는 다음과 같습니다. 이전 스크립트와 유일한 차이점은 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;
});
동일한 방법을 사용하여 간단한 형식의 배열을 보낼 수 있습니다.
$.post('api/updates/postlist', { "": ["update one", "update two", "update three"] });