• ASP.NET MVC5中View-Controller间数据的传递


    使用ASP.NET MVC做开发时,经常需要在页面(View)和控制器(Controller)之间传递数据,那么都有哪些数据传递的方式呢?

    本文对于View向Controller中传值共列举了以下几种方式:

    对于Controller向View中传值则列举了以下几种方式:

    View向Controller中传递数据的方式

    QueryString

    View中代码:

    复制代码
    <div>
        <button id="btn">提交</button>
    </div>
    <script>
        $(function () {
            $('#btn').click(function () {
                //url不区分大小写
                location.href = "/home/getvalue?method=querystring";
            });
        });
    </script>
    复制代码

    Controller中代码:

    public void GetValue()
    {
        //Request属性可用来获取querystring,form表单以及cookie中的值
        var querystring = Request["method"];
    }

    使用querystring向后台传递属于http协议中的get方式,即数据会暴露在url中,安全性不高(可通过浏览器历史记录看到发送的数据)且传递的数据量有大小限制。 点击提交按钮后浏览器地址栏中的地址:http://localhost:57625/home/getvalue?method=querystring。程序执行结果如下:

    RouteData

    路由可以让我们写出可读性较高的url,使用路由传递数据,首先要配置合适的路由:

    routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}"
    );

    前端代码只需要将location.href的值改为和路由匹配的url即可,本示例中为"/home/getvalue/100" Controller中的代码:

    public void GetValue()
    {
        var value = RouteData.Values["id"];
    }

    获取的值是object类型:

     

    获取路由参数的另外一种方式是给Action设置一个和路由模板中指定的参数名一致(不区分大小写)的参数即可,代码如下:

    public void GetValue(int id)
    {
    
    }

    注意,这里不仅获取了路由数据,而且自动将数据类型转换为int类型:

    querystring和路由均是通过url进行数据的传递,若数据中包含中文应进行Encode操作。此外,url的长度是有限制的,使用url不可传递过多的数据。url传递参数属于Http协议中的Get请求,若要发送大量数据可以使用Post请求。

    ModelBinding

    1. Form

    form表单形式是常见的向后端发送数据的方式,但是在提交数据是只会提交form表单内部具有name属性input,textarea,select标签的value值。 View中的代码:

    <form action="/home/getvalue" method="post">
        <input type="text" name="username" />
        <input type="text" name="age" />
        <input type="submit" name="button" value="提交" />
    </form>

    Controller中的代码:

    复制代码
    public void GetValue()
    {
        var name = Request["username"];
        var age = Request["age"];
        var btn = Request["button"];
    }
    复制代码

    获取到的数据均为string类型:

    现在我们创建一个和form表单对应的类:

    public class User
    {
        public string UserName { set; get; }
        public int Age { set; get; }
    }

    修改Action的代码如下:

    public void GetValue(User user)
    {
    
    }

    然后运行程序,可以看到MVC以将表单中的数据映射为User类实例的属性值,且进行了相应的数据类型的转换。

    2. 使用和Action参数同名的变量进行传递

    View中的代码:

    复制代码
    <button id="btn">传递数据</button>
    <script>
        $(function () {
            $('#btn').click(function () {
                $.ajax({
                    'type': 'post', 'url': '/home/getdata',
                     //传递的数据也可以是序列化之后的json格式数据
                     //如,上面使用form表单提交数据就可以使用jquery中的serialize()方法将表单进行序列化之后在提交
                     //data:$('#form').serialize()
                    'data': { username: '雪飞鸿', age: '24' },
                    error: function (message) {
                        alert('error!');
                    }
                });
            })
        })
    </script>
    复制代码

    Controller中的代码:

    public void GetData(string username, int age)
    {
    
    }

    在Action中成功获取到了对应的参数值,且数据类型也根据Action中参数的类型进行了相应的转换。

     
    Model绑定体现在从当前请求提取相应的数据绑定到目标Action方法的同名参数中。对于这样的一个Action,如果是Post请求,MVC会尝试将Form(注意,这里的Form不是指html中的<form>表单,而是Post方法发送数据的方式,若我们使用开发者工具查看Post方式发送的请求信息,会看到Form Data一栏)中的值赋值到Action参数中,如果是get请求,MVC会尝试将QueryString的值赋值到Action参数中。
     

    Cookie

    这里引用jquery.cookie插件来进行cookie的操作

    复制代码
    <body>
        <button id="btn">提交</button>
        <script>
            $(function () {
                //向cookie中写入值
                $.cookie('key', 'jscookie');
    
                $('#btn').click(function () {
                    location.href = "/home/getvalue";
                });
            })
        </script>
    </body>
    复制代码
    public void GetValue()
    {
        var cookie = Request["key"];
    }
     

    Controller向View中传值

    单个值的传递

    public ActionResult Index()
    {
        //注意,传递的值不能是string类型,否则会执行View(string viewName)方法而导致得不到正确结果
        return View(100);
    }
    <body>
     <p>@Model</p>
    </body>
    程序执行结果如下:

    Json

    复制代码
    public ActionResult Index()
    {
        return View();
    }
    
    public JsonResult SendData()
    {
        return Json(new { UserName = "雪飞鸿", Age = 24 });
    }
    复制代码
    复制代码
    <!DOCTYPE html>
    <html>
    <head>
        <meta name="viewport" content="width=device-width" />
        <script src="~/scripts/jquery-1.10.2.min.js"></script>
    </head>
    <body>
        <p id="message"></p>
        <button id="btn">获取数据</button>
        <script>
            $(function () {
                $('#btn').click(function () {
                    $.ajax({
                        'url': '/home/senddata', 'type': 'post',
                        success: function (data) {
                            $('#message').html('用户名:' + data.UserName + "<br/>年龄:" + data.Age);
                        },
                        error: function (message) {
                            alert('error:' + message.statusText);
                        }
                    });
                });
            });
        </script>
    </body>
    </html>
    复制代码
    程序执行结果如下:

    匿名类型

    public ActionResult Index()
    {
        //使用匿名类向View中传递数据
        return View(new { UserName = "雪飞鸿", Age = 24 });
    }
    复制代码
    <!DOCTYPE html>
    <html>
    <head>
        <meta name="viewport" content="width=device-width" />
    </head>
    <body>
        <p>用户名:@Model.UserName</p>
        <p>年龄:@Model.Age</p>
    </body>
    </html>
    复制代码

    因为匿名类型的类型名由编译器生成,并且不能在源代码级使用。所以,直接使用匿名类型向View中传递数据,在前台页面是无法访问到匿名类型中的属性的。执行上面代码程序会出现错误:

    针对上述问题,使用Newtonsoft将匿名类型转换为json格式即可解决该问题。 使用NuGet引入Newtonsoft.Json包,然后修改代码如下:

    复制代码
    public ActionResult Index()
    {
        string json = JsonConvert.SerializeObject(new { UserName = "雪飞鸿", Age = 24 });
        //也可以直接序列化JSON格式的字符串
        //dynamic jsonObj = JsonConvert.DeserializeObject("{ UserName : "雪飞鸿", Age : 24 }");
        dynamic jsonObj = JsonConvert.DeserializeObject(json);
        return View(jsonObj);
    }
    复制代码
    程序执行结果如下:

    ExpandoObject

    上面提到,直接使用匿名类型向View中传递数据是行不通的,可以使用ExpandoObject类型对象来替代匿名类型

    复制代码
    public ActionResult Index()
    {
        dynamic user = new ExpandoObject();
        user.UserName = "雪飞鸿";
        user.Age = 24;
        return View(user);
    }
    复制代码
    程序执行结果如下:

    ViewBag、ViewData、TempData

    复制代码
    public ActionResult Index()
    {
        ViewBag.Title = "数据传递";
        ViewData["key"] = "传递数据";
        //默认情况下TempData中的数据只能使用一次
        TempData["temp"] = "tempdata";
        return View();
    }
    复制代码
    复制代码
    <!DOCTYPE html>
    <html>
    <head>
        <meta name="viewport" content="width=device-width" />
        <title>@ViewBag.Title</title>
    </head>
    <body>
        <p>@ViewData["key"]</p>
        <p>@TempData["temp"]</p>
    </body>
    </html>
    复制代码
    程序执行结果如下:

    ViewModel

    通过视图模型将数据传递到前端

    复制代码
    //视图模型
    public class User
    {
        public string UserName { set; get; }
        public int Age { set; get; }
    }
    //Action
    public ActionResult Index()
    {
        User user = new User() { UserName = "雪飞鸿", Age = 24 };
        return View(user);
    }
    复制代码
    复制代码
    @* 设置页面为强类型页面 *@
    @model DataTransfer.Controllers.User
    @{
        Layout = null;
    }
    
    <!DOCTYPE html>
    <html>
    <head>
        <meta name="viewport" content="width=device-width" />
    
    </head>
    <body>
        <p>用户名:@Model.UserName</p>
        <p>年龄:@Model.Age</p>
    </body>
    </html>
    复制代码
    程序执行结果如下:

    Cookie

    public ActionResult Index()
    {
        Response.SetCookie(new HttpCookie("key", "cookie"));
        return View();
    }
    复制代码
    <body>
        <p id="message"></p>
        <script>
            $(function () {
                var message = $.cookie('key');
                $('#message').text(message);
            })
        </script>
    </body>
    复制代码
    程序执行结果如下:

    参考文章:

    玩转Asp.net MVC 的八个扩展点

    http://www.cnblogs.com/Cwj-XFH/p/5877204.html

  • 相关阅读:
    iOS 10 的一个重要更新-用 UIViewPropertyAnimator 编写动画
    iOS 10 的一个重要更新-线程竞态检测工具 Thread Sanitizer
    iOS 10 的一个重要更新-开发 iMessage 的第三方插件
    状态栏白色
    iOS 对 HTTPS 证书链的验证
    Xcode8 带来的新特性和坑
    升级cocoapods1.1.1版本
    (这也不是,那也不是,怎么办?)无论何时坚持自己的原则,当选准了目标,就不放弃,做最好的自己。我们必须要有一定的看法,正确的做法;有时,我们无法避免他人在旁的批评或劝告,但我们是无法取悦每个人的,否则将失去了方向,迷失了自己。
    笑话集锦(1)
    最感动的一首现代诗(转)(修正了一点翻译)
  • 原文地址:https://www.cnblogs.com/chuancheng/p/7650097.html
Copyright © 2020-2023  润新知