zoukankan      html  css  js  c++  java
  • [水煮 ASP.NET Web API2 方法论](1-3)如何接收 HTML 表单请求

    问题

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

    解决方案

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

    1
    2
    3
    4
    public HttpResponseMessage Post(RegistrationModel model)
    {
        //忽略
    }

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

    1
    2
    3
    4
    public HttpResponseMessage Post(FormDataCollection form)
    {
        //忽略
    }

    工作原理

      当使用 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. 接收复杂请求的表单数据

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public async Task Post()
    {
        if (!Request.Content.IsMimeMultipartContent())
        {
            throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotAcceptable,
            "请求格式化失败"));
        }
        var streamProvider = new MultipartFormDataStreamProvider("d:/uploads/");
        await Request.Content.ReadAsMultipartAsync(streamProvider);
        //访问 FormDataCollection 的 实例 streamProvider.FormData
     }

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

    代码演示

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

     

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    <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="female" checked>Female
            </label>
        </div>
        <div class="radio">
            <label>            
                <input type="radio" name="gender" value="male">Male
            </label>
        </div>
        <button type="submit" class="btn btn-default">提交</button>
        <button id="postJS" class="btn btn-default">使用 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) {
                //处理 handler
            }); 
        });
    });
    </script>

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

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    public async Task Post()
    {
        if (!Request.Content.IsMimeMultipartContent())
        {
            throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotAcceptable,
            "请求格式化失败"));
        }
        var streamProvider = new MultipartFormDataStreamProvider("d:/uploads/");
        await Request.Content.ReadAsMultipartAsync(streamProvider);
        //访问 FormDataCollection 的 实例 streamProvider.FormData
    }
     
    public class UserModel{
        public string Name { getset; }
        public string Email { getset; }
        public string Gender { getset; }
    }
     
    public class FormController : ApiController{
        public HttpResponseMessage Post(FormDataCollection form)
        {
            var user = new UserModel        {
                Email = form["Email"],
                Name = form["Name"],
                Gender = form["Gender"]
            };
            //  处理用户...       
            //  忽略    
         }
    }
     
    public class UserController : ApiController{
        public HttpResponseMessage Post(UserModel user)
        {
                    //process user...        
                    //rest omitted for brevity    
         }
    }
  • 相关阅读:
    如何突破单库性能瓶颈?
    高性能数据库表该如何设计?
    高性能索引该如何设计?(下)
    高性能索引该如何设计?(上)
    MySQL体系结构与存储引擎
    动态ViewPager导航页面
    ViewPager图片轮转带点的
    手动图片横向轮播
    安卓布局中下拉列表框的实现
    安卓中adapter的应用
  • 原文地址:https://www.cnblogs.com/shuizhucode/p/6049522.html
Copyright © 2011-2022 走看看