zoukankan      html  css  js  c++  java
  • ASP.NET MVC中controller和view相互传值的方式

      ASP.NET MVC中Controller向view传值的方式

    1. ViewBag、ViewData、TempData
    2. 单个值的传递
    3. Json
    4. 匿名类型
    5. ExpandoObject
    6. Cookie
    7. ViewModel(向普通View页面传个Model对象、向强类型页面传一个Model对象、用一个ViewModel对象解决所有问题)

      ASP.NET MVC中view向Controller传值的方式

    1. QueryString
    2. RouteData
    3. Model Binding(form、使用和Action参数同名的变量进行传递)
    4. Cookie

      在MVC中ViewBag的作用是数据的传递。在MVC3开始,视图数据能够通过ViewBag属性访问。在MVC2中则是使用ViewData。MVC3中保留了ViewData的使用。ViewBag是动态类型的(dynamic),ViewData是一个字典型的(Dictionary)。

    MVC3中ViewBag和ViewData的差别:

    ViewBag不再是字典的键值对结构,而是dynamic动态类型的。 它会在程序执行的时候动态解析。

    所以在视图中获取它的数据时候不须要进行类型转换

    ViewData ViewBag
    它是Key/Value字典集合 它是dynamic类型对像
    从Asp.net MVC 1 就有了 ASP.NET MVC3 才有
    基于Asp.net 3.5 framework 基于Asp.net 4.0与.net framework
    ViewData比ViewBag快 ViewBag比ViewData慢
    在ViewPage中查询数据时须要转换合适的类型 在ViewPage中查询数据时不须要类型转换
    有一些类型转换代码 可读性更好

    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>
    复制代码
    程序执行结果如下:
  • 相关阅读:
    Json对象处理.将对象处理成dic数组.
    asp.net core 创建允许跨域请求的api, cors.
    (转载)dotnet core 中文乱码 codepages
    (转载)Memcached和Redis简介
    发送Json数据,WebApi查看时为Null的问题(已解决)
    Vs2017获取Git空仓库后创建解决方案及项目无法推送,推送失败的问题.
    前端:Jquery 处理同一Name的Radio组时,绑定checked属性异常的问题.(已解决)
    Vs2015 本地git获取的代码目录文件修改后,启动提示error:Unable to start program “C:Program Filesdotnetdotnet.exe” 已解决.
    .net core 发布后提示Start error
    .net core vs2015 vs2017打开后errpr
  • 原文地址:https://www.cnblogs.com/baojiao/p/8882566.html
Copyright © 2011-2022 走看看