【ASP.NET Web API教程】5.2 發送HTML表單數據:URL編碼的表單數據


注:本文是【ASP.NET Web API系列教程】的一部分,如果您是第一次看本系列教程,請先看前面的內容。

5.2 Sending HTML Form Data
5.2 發送HTML表單數據

本文引自:http://www.asp.net/web-api/overview/working-with-http/sending-html-form-data,-part-1

By Mike Wasson|June 15, 2012
作者:Mike Wasson | 日期:2012-6-15

Part 1: Form-urlencoded Data
第1部分:URL編碼的表單數據

This article shows how to post form-urlencoded data to a Web API controller.
本文顯示如何向Web API控制器遞交URL編碼的表單數據。

  • Overview of HTML Forms
    HTML表單概述
  • Sending Complex Types
    發送復合類型
  • Sending Form Data via AJAX
    通過AJAX發送表單數據
  • Sending Simple Types
    發送簡單類型

Overview of HTML Forms
HTML表單概述

HTML forms use either GET or POST to send data to the server. The method attribute of the form element gives the HTTP method:
HTML表單使用GET或POST將數據發送給服務器。form元素的method標簽屬性給出HTTP方法:

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

The default method is GET. If the form uses GET, the form data is encoded in the URI as a query string. If the form uses POST, the form data is placed in the request body. For POSTed data, the enctype attribute specifies the format of the request body:
默認方法是GET。如果form使用GET,表單數據作為查詢字符串被編碼到URI中。如果form使用POST,表單數據被放在請求體中。對於POST的數據,enctype標簽屬性會指明請求體的格式:

enctype Description
描述
application/x-www-form-urlencoded Form data is encoded as name/value pairs, similar to a URI query string. This is the default format for POST.
表單數據被編碼成“名字/值”對,類似於URI查詢字符串。這是POST的默認格式。
multipart/form-data Form data is encoded as a multipart MIME message. Use this format if you are uploading a file to the server.
表單數據被編碼成多部分MIME消息。如果把文件上傳到服務器,使用的是這種格式。

MIME指Multipurpose Internet Mail Extensions — 多用途互聯網郵件擴展,它是通過網絡傳遞郵件消息的一個互聯網標准。MIME規定了用於表示各種數據類型的符號化方法。在HTTP協議中,對HTTP消息的內容類型也采用了MIME的這種表示數據類型的方法。上述enctype標簽屬性意為“編碼類型”,就是用來指定HTTP消息的Content-Type(內容類型)報頭屬性。給這個標簽屬性所指定的值必須是MIME對Content-Type所規定的值之一。上表中便是MIME中關於內容類型的其中兩個值。更多內容請參閱MIME的有關資料 — 譯者注

Part 1 of this article looks at x-www-form-urlencoded format. Part 2 describes multipart MIME.
本文的第1部分考察x-www-form-urlencoded格式。第2部分描述多部分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; } } }

Here is a Web API controller that accepts an Update object via POST.
以下是通過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. // 轉換status文本中的HTML標記。 update.Status = HttpUtility.HtmlEncode(update.Status);
// Assign a new ID. // 賦一個新的ID。 var id = Guid.NewGuid(); updates[id] = update;
// Create a 201 response. // 創建一個201響應。 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); } } } }

This controller uses action-based routing, so the route template is "api/{controller}/{action}/{id}". The client will post the data to "/api/updates/complex".
這個控制器使用了“基於動作的路由(本系列教程的第4.1小節 — 譯者注)”,因此,路由模板是“api/{controller}/{action}/{id}”。客戶端會把這些數據遞交給“/api/updates/complex”。

Now let’s write an HTML form for users to submit a status update.
現在,讓我們編寫一個用戶遞交狀態更新的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>

Notice that the action attribute on the form is the URI of our controller action. Here is the form with some values entered in:
注意,form的action標簽屬性是控制器動作的URI。以下是已經輸入了一些值的表單:

WebAPI5-6

圖5-6. 輸入了一些數據的表單

When the user clicks Submit, the browser sends an HTTP request similar to the following:
當用戶點擊“Submit”時,瀏覽器發送一個類似於以下數據的HTML請求:

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 automatically converts the name/value pairs into an instance of the Update class.
注意,請求體包含了表單數據,被格式化成“名字/值”對。Web API會自動地把“名字/值”對轉換成Update類的實例。

Sending Form Data via AJAX
通過AJAX發送表單數據

When a user submits a form, the browser navigates away from the current page and renders the body of the response message. That’s OK when the response is an HTML page. With a web API, however, the response body is usually either empty or contains structured data, such as JSON. In that case, it makes more sense to send the form data using an AJAX request, so that the page can process the response.
當用戶遞交表單時,瀏覽器會離開當前頁面,並渲染響應消息體。當響應是HTML頁面時,這沒問題。然而,對於Web API,響應體通常是空的,或是如JSON那樣的結構化數據。在這種情況下,用AJAX請求發送表單數據,以使頁面能夠處理響應,會更有意義些。

The following code shows how to post form data using jQuery.
以下代碼演示如何用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>

The jQuery submit function replaces the form action with a new function. This overrides the default behavior of the Submit button. The serialize function serializes the form data into name/value pairs. To send the form data to the server, call $.post().
jQuery的submit函數用一個新函數替換了表單的action。它重寫了Submit按鈕的默認行為。serialize函數把表單數據序列化成“名字/值”對。為了將表單數據發送給服務器,調用$.post()

When the request completes, the .success() or .error() handler displays an appropriate message to the user.
當請求完成時,.success().error()處理器會給用戶顯示一條相應的消息(見圖5-7)。

WebAPI5-7

圖5-7. 通過AJAX發送表單數據

Sending Simple Types
發送簡單類型

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.
在前一小節中,我們發送的是復合類型,Web API會將其解序列化成一個模型類實例。你也可以發送簡單類型,如字符串。

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. First, in the controller, you must decorate the parameter name with the FromBody attribute.
發送簡單類型的基本步驟是相同的,但有兩個細微的差別。第一,在控制器中,你必須用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); }

By default, Web API tries to get simple types from the request URI. The FromBody attribute tells Web API to read the value from the request body.
默認地,Web API試圖通過請求的URI獲取簡單類型。FromBody注解屬性告訴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.
Web API最多讀取響應體一次,因此只有動作的一個參數可以獲自請求體。如果需要從請求體得到多個值,需要定義復合類型。

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. Not all browsers support this for HTML forms, but you create this format in script as follows:
特別地,“名字/值”對的值部分對於簡單類型必須為空。並不是所有瀏覽器對HTML表單都支持這種格式,但你在腳本中按下列方式創建了格式:

$.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.
以下是遞交表單值的腳本。與前面的腳本唯一的差別是在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; 
});

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
其它資源

Part 2: File Upload and Multipart MIME
第2部分:文件上傳與多部分MIME格式(本系列教程的第5.3小節 — 譯者注)


看完此文如果覺得有所收獲,請給個推薦


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM