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

Mike Wassonby Mike Wasson

1부: Form-urlencoded 데이터Part 1: Form-urlencoded Data

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

HTML 폼의 개요Overview of HTML Forms

HTML 양식 사용 하 여 GET 또는 게시 서버로 데이터를 보내도록 합니다.HTML forms use either GET or POST to send data to the server. 메서드 특성을 HTTP 메서드를 제공 하는 요소:The method attribute of the form element gives the HTTP method:

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

기본 메서드는 GET입니다.The default method is 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 설명Description
application/x-www-form-urlencodedapplication/x-www-form-urlencoded 양식 데이터는 URI 쿼리 문자열로 비슷합니다 이름/값 쌍으로 인코딩됩니다.Form data is encoded as name/value pairs, similar to a URI query string. 게시물에 대 한 기본 형식입니다.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-형식-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; }
    }
}

다음은 허용 하는 Web API 컨트롤러는 Update POST 통해 개체입니다.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 / {컨트롤러} / {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>

작업 양식의 특성이 컨트롤러 작업의 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. 웹 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 제출 함수는 새 함수를 사용 하 여 form action을 대체 합니다.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

이전 섹션에서는 Web API 모델 클래스의 인스턴스로 deserialize 하는 복합 형식을 보냈습니다.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 특성은 요청 본문에서 값을 읽을 수 있는 Web API에 알립니다.The FromBody attribute tells Web API to read the value from the request body.

Note

웹 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. 이전 스크립트에서 유일한 차이점은에 전달 된 인수를 게시물 함수입니다.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