ASP.NET Web API에서 HTML 양식 데이터 보내기: 양식 x-www-form-urlencoded 데이터Sending HTML Form Data in ASP.NET Web API: Form-urlencoded Data

Mike Wassonby Mike Wasson

1 부: 양식 x-www-form-urlencoded 데이터Part 1: Form-urlencoded Data

이 문서에서는 Web API 컨트롤러에 양식-x-www-form-urlencoded 데이터를 게시 하는 방법을 보여 줍니다.This article shows how to post form-urlencoded data to a Web API controller.

HTML 양식 개요Overview of HTML Forms

HTML 양식은 GET 또는 POST를 사용 하 여 서버에 데이터를 보냅니다.HTML forms use either GET or POST to send data to the server. Form 요소의 METHOD 특성은 HTTP 메서드를 제공 합니다.The method attribute of the form element gives the HTTP method:

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

기본 메서드는 GET입니다.The default method is GET. 폼에서 GET을 사용 하는 경우 양식 데이터는 URI에서 쿼리 문자열로 인코딩됩니다.If the form uses GET, the form data is encoded in the URI as a query string. 폼에서 POST를 사용 하는 경우 양식 데이터가 요청 본문에 배치 됩니다.If the form uses POST, the form data is placed in the request body. 게시 된 데이터의 경우 enctype 특성은 요청 본문의 형식을 지정 합니다.For POSTed data, the enctype attribute specifies the format of the request body:

enctypeenctype DescriptionDescription
application/x-www-form-urlencodedapplication/x-www-form-urlencoded 양식 데이터는 URI 쿼리 문자열과 비슷하게 이름/값 쌍으로 인코딩됩니다.Form data is encoded as name/value pairs, similar to a URI query string. POST에 대 한 기본 형식입니다.This is the default format for POST.
다중 파트/폼 데이터multipart/form-data 양식 데이터는 다중 파트 MIME 메시지로 인코딩됩니다.Form data is encoded as a multipart MIME message. 서버에 파일을 업로드 하는 경우이 형식을 사용 합니다.Use this format if you are uploading a file to the server.

이 문서의 1 부에서는 x-www-form-urlencoded 형식을 살펴봅니다.Part 1 of this article looks at x-www-form-urlencoded format. 2 부 에서는 다중 부분 MIME을 설명 합니다.Part 2 describes multipart MIME.

복합 형식 보내기Sending Complex Types

일반적으로 여러 양식 컨트롤에서 가져온 값으로 구성 되는 복합 형식을 보냅니다.Typically, you will send a complex type, composed of values taken from several form controls. 상태 업데이트를 나타내는 다음 모델을 고려 하십시오.Consider the following model that represents a status update:

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 컨트롤러입니다.Here is a Web API controller that accepts an Update object via 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);
            }
        }

    }
}

Note

이 컨트롤러는 작업 기반 라우팅을사용 하므로 경로 템플릿은 api/{controller}/{action}/{id}""됩니다.This controller uses action-based routing, so the route template is "api/{controller}/{action}/{id}". 클라이언트는 "/api/updates/complex"에 데이터를 게시 합니다.The client will post the data to "/api/updates/complex".

이제 사용자가 상태 업데이트를 제출 하는 HTML 양식을 작성해 보겠습니다.Now let's write an HTML form for users to submit a status update.

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

폼의 action 특성은 컨트롤러 작업의 URI입니다.Notice that the action attribute on the form is the URI of our controller action. 다음은에 입력 된 일부 값이 있는 폼입니다.Here is the form with some values entered in:

사용자가 제출을 클릭 하면 브라우저에서 다음과 같은 HTTP 요청을 보냅니다.When the user clicks Submit, the browser sends an HTTP request similar to the following:

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

요청 본문에는 이름/값 쌍으로 형식이 지정 된 양식 데이터가 포함 되어 있습니다.Notice that the request body contains the form data, formatted as name/value pairs. Web API는 이름/값 쌍을 자동으로 Update 클래스의 인스턴스로 변환 합니다.Web API automatically converts the name/value pairs into an instance of the Update class.

AJAX를 통해 폼 데이터 보내기Sending Form Data via AJAX

사용자가 폼을 제출 하면 브라우저가 현재 페이지에서 벗어나 응답 메시지의 본문을 렌더링 합니다.When a user submits a form, the browser navigates away from the current page and renders the body of the response message. 응답이 HTML 페이지인 경우에는이 기능을 사용할 수 없습니다.That's OK when the response is an HTML page. 그러나 web API를 사용 하는 경우 응답 본문은 일반적으로 비어 있거나 JSON과 같은 구조화 된 데이터를 포함 합니다.With a web API, however, the response body is usually either empty or contains structured data, such as JSON. 이 경우 페이지에서 응답을 처리할 수 있도록 AJAX 요청을 사용 하 여 폼 데이터를 전송 하는 것이 더 적합 합니다.In that case, it makes more sense to send the form data using an AJAX request, so that the page can process the response.

다음 코드에서는 jQuery를 사용 하 여 폼 데이터를 게시 하는 방법을 보여 줍니다.The following code shows how to post form data using 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 함수는 form 작업을 새 함수로 바꿉니다.The jQuery submit function replaces the form action with a new function. 이는 제출 단추의 기본 동작을 재정의 합니다.This overrides the default behavior of the Submit button. Serialize 함수는 폼 데이터를 이름/값 쌍으로 serialize 합니다.The serialize function serializes the form data into name/value pairs. 서버에 폼 데이터를 전송 하려면 $.post()를 호출 합니다.To send the form data to the server, call $.post().

요청이 완료 되 면 .success() 또는 .error() 처리기가 사용자에 게 적절 한 메시지를 표시 합니다.When the request completes, the .success() or .error() handler displays an appropriate message to the user.

단순 형식 보내기Sending Simple Types

이전 섹션에서는 모델 클래스의 인스턴스로 deserialize 된 Web API를 복합 형식으로 보냈습니다.In the previous sections, we sent a complex type, which Web API deserialized to an instance of a model class. 문자열 등의 단순 형식을 보낼 수도 있습니다.You can also send simple types, such as a string.

Note

단순 형식을 보내기 전에 복합 형식의 값을 대신 래핑하는 것이 좋습니다.Before sending a simple type, consider wrapping the value in a complex type instead. 이렇게 하면 서버 쪽에서 모델 유효성 검사의 이점을 얻을 수 있으며 필요한 경우 모델을 더 쉽게 확장할 수 있습니다.This gives you the benefits of model validation on the server side, and makes it easier to extend your model if needed.

단순 유형을 전송 하는 기본 단계는 동일 하지만 두 가지 미묘한 차이점이 있습니다.The basic steps to send a simple type are the same, but there are two subtle differences. 먼저 컨트롤러에서 Frombody 특성을 사용 하 여 매개 변수 이름을 데코레이팅 해야 합니다.First, in the controller, you must decorate the parameter name with the FromBody attribute.

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

기본적으로 웹 API는 요청 URI에서 단순 형식을 가져오려고 시도 합니다.By default, Web API tries to get simple types from the request URI. Frombody 특성은 요청 본문에서 값을 읽도록 웹 API에 지시 합니다.The FromBody attribute tells Web API to read the value from the request body.

Note

Web API는 응답 본문을 한 번만 읽어서 요청 본문에서 동작의 매개 변수를 하나만 가져올 수 있습니다.Web API reads the response body at most once, so only one parameter of an action can come from the request body. 요청 본문에서 여러 값을 가져와야 하는 경우에는 복합 형식을 정의 합니다.If you need to get multiple values from the request body, define a complex type.

둘째, 클라이언트는 다음 형식의 값을 보내야 합니다.Second, the client needs to send the value with the following format:

=value

특히 이름/값 쌍의 이름 부분은 단순 형식에 대해 비어 있어야 합니다.Specifically, the name portion of the name/value pair must be empty for a simple type. 모든 브라우저에서 HTML 폼에 대해이 기능을 지원 하지는 않지만 다음과 같이 스크립트에서이 형식을 만들 수 있습니다.Not all browsers support this for HTML forms, but you create this format in script as follows:

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

예제 폼은 다음과 같습니다.Here is an example form:

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

폼 값을 제출 하는 스크립트는 다음과 같습니다.And here is the script to submit the form value. 이전 스크립트의 유일한 차이점은 post 함수로 전달 되는 인수입니다.The only difference from the previous script is the argument passed into the post function.

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

동일한 방법을 사용 하 여 단순 형식의 배열을 보낼 수 있습니다.You can use the same approach to send an array of simple types:

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

추가 리소스Additional Resources

2 부: 파일 업로드 및 다중 파트 MIMEPart 2: File Upload and Multipart MIME