首页 > 代码库 > 水煮 ASP.NET Web API(1-3)如何接收 HTML 表单请求

水煮 ASP.NET Web API(1-3)如何接收 HTML 表单请求

问题

我们想创建一个能够处理 HTML 表单的 ASP.NET Web API 应用程序(使用 application/x-www-form-urlencoded 方式提交数据)。

 

解决方案

我们可以创建一个 Controller Action 接收一个 ModdelModel 的结构和准备从HTML 表单提交的准备处理的结构相似,模型绑定依赖于 ASP.NET Web API 来处理。模型中的属性名字和 HTTP 请求中要用的名字要匹配。

public HttpResponseMessage Post(RegistrationModel model)
{
    //omitted for brevity}

 

  另外,我们可以使用 System.Net.Http.Formatting.FormDataCollection作为 Action 方法的参数。框架将会通过键值对集合的方式传值,允许我们手动处理我们想要的值。

public HttpResponseMessage Post(FormDataCollection form)
{
    //omitted for brevity}

 

工作原理

  当时使用 ASP.NET Web API 构建 web 应用程序,甚至,为了促进现有 Web 应用程序(MVCWeb Form,或者其他技术)而是用 Web API 的时候,提交 form-URL-encoded 数据是一种常见的需求

  ASP.NET Web API 使用 MediaTypeFormatters HttpRequestMessage 表单中提取数据,并且,传输这些数据给相应选择的 action 来处理请求。第四章会详细介绍模型绑定和格式化,在这里,我们仅仅接触了直接与处理 HTML 表单相关的概念。

    两个现成的格式化程序能够处理的格式:

  •   FormUrlEncodedMediaTypeFormatter,用于绑定 使用     application/x-www-form-urlencoded 内容类型 FormDataCollection

  • JQueryMvcFormUrlEncodedFormatter,也是使用同样的内容类型,也可以绑定到 ModelDTO

从设计角度来看,后面的应该是前面的子类。

  使用 FormDataCollection 来代替我们 action 参数,不仅 给我们访问原始表单数据,还通知了 ASP.NET Web API 不执行任何验证。

  默认情况,Web API 仅仅读请求体一次,当使用模型绑定表单数据,这种模式应该封装了所有的表单域。换句话说,即用模式,不能在传输数据时,一些数据使用请求体传输,一些数据使用 URL 参数形式传输的情况下,还希望框架自动处理绑定到一个模型上。对于 MVC 开发者这是个非常危险的事情,因为这个正是开发人员的行为习惯。不过,可以强制 Web API 使用像 MVC 样式的参数绑定。这部分将在本书 4-4 部分讨论。

  如果的你的表单处理的二进制数据,例如,上传文件,这时候,表单将被替换为 multipart/form-data形式提交。ASP.NET Web API 没有提供任何内建的 MediaTypeFomatter 来处理它。不过,他还是很容易处理这种方式的表单提交。他是使用 MultipleFormDataStreamProvider 直接处理 HttpRequestMessage 的内容。这个技术如清单 1-7。尽管处理文件上传超出了本书的范围,还是会在本书 4-11  单独讨论。

清单1-7. 接收复杂请求的表单数据

public async Task Post()
{
    if (!Request.Content.IsMimeMultipartContent())
    {
        throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotAcceptable,
        "This request is not properly formatted"));
    }
    var streamProvider = new MultipartFormDataStreamProvider("d:/uploads/");
    await Request.Content.ReadAsMultipartAsync(streamProvider);
    //here you can access streamProvider.FormData which    //is an instance of FormDataCollection}

注意 在这一部分讨论的功能不是 ASP.NET 特有的,在 web 托管的 Web API 之外一样可以用。不过,作为 ASP.NET Web 应用程序的一部分来运行 Web API 的时候,我们通常还是要处理传统的网页表单。

 

代码演示

清单 1-8 展示了使用简单表单和JavaScript 提交到 ASP.NET Web API 的简单网页表单.

 

清单 1-8. 简单的网页表单

<form role="form" method="post" action="/api/form" enctype="application/x-www-form-urlencoded">    <div class="form-group">        <label for="name">Name</label>        <input type="text" class="form-control" name="name" placeholder="Enter name">    </div>    <div class="form-group">        <label for="email">Email</label>        <input type="email" class="form-control" name="email" placeholder="Enter email">    </div>    <div class="radio">        <label>            <input type="radio" name="gender" value="http://www.mamicode.com/female" checked>            Female
        </label>    </div>    <div class="radio">        <label>            <input type="radio" name="gender" value="http://www.mamicode.com/male">            Male
        </label>    </div>    <button type="submit" class="btn btn-default">Submit</button>    <button id="postJS" class="btn btn-default">Send with JS</button></form><script type="text/javascript">    $(function () {        $("#postJS").on("click", function () {            var data = {                name: $("input[name=‘name‘]").val(),                email: $("input[name=‘email‘]").val(),                gender: $("input[name=‘gender‘]:checked").val(),            };            $.ajax({                data: data,                datatype: "html",                type: "POST",                url: "/api/user"            }).done(function (res) {                //success handler            });        });    });</script>

  清单 1-9 展示了可以处理清单 1-8 表单的两个 ASP.NET Web API action。第一个是是使用相对传统的方式,使用 FormDataCollection 手动提取数据,然后在填充到服务器的模型里面。第二个依依赖与框架的自动模型绑定。

 

清单 1-9. Web API 控制器处理表单数据

public async Task Post()
{
    if (!Request.Content.IsMimeMultipartContent())
    {
        throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotAcceptable,
        "This request is not properly formatted"));
    }
    var streamProvider = new MultipartFormDataStreamProvider("d:/uploads/");
    await Request.Content.ReadAsMultipartAsync(streamProvider);
    //here you can access streamProvider.FormData which    //is an instance of FormDataCollection} 
public class UserModel{
    public string Name { get; set; }
    public string Email { get; set; }
    public string Gender { get; set; }
}public class FormController : ApiController{
    public HttpResponseMessage Post(FormDataCollection form)
    {
        var user = new UserModel        {
            Email = form["Email"],
            Name = form["Name"],
            Gender = form["Gender"]
        };
        //process user...        //rest omitted for brevity    }
}public class UserController : ApiController{
    public HttpResponseMessage Post(UserModel user)
    {
        //process user...        //rest omitted for brevity    }
}


本文出自 “3460483363” 博客,请务必保留此出处http://3460483363.blog.51cto.com/12234482/1869170

水煮 ASP.NET Web API(1-3)如何接收 HTML 表单请求