MVC进阶学习--View和Controller之间的数据传递(一)

1.使用ViewData

  ViewData 的是ControllerBase 的一个属性,是一个数据字典类型的,其实现代码如(这段代码来自asp.net MVC开源项目中源码)下:

Code
  1 public class ViewDataDictionary : IDictionary<string, object> {
  2 
  3         private readonly Dictionary<string, object> _innerDictionary = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
  4         private object _model;
  5         private readonly ModelStateDictionary _modelState = new ModelStateDictionary();
  6 
  7         public ViewDataDictionary()
  8             : this((object)null) {
  9         }
 10 
 11         [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors",
 12             Justification = "See note on SetModel() method.")]
 13         public ViewDataDictionary(object model) {
 14             Model = model;
 15         }
 16 
 17         [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors",
 18             Justification = "See note on SetModel() method.")]
 19         public ViewDataDictionary(ViewDataDictionary dictionary) {
 20             if (dictionary == null) {
 21                 throw new ArgumentNullException("dictionary");
 22             }
 23 
 24             foreach (var entry in dictionary) {
 25                 _innerDictionary.Add(entry.Key, entry.Value);
 26             }
 27             foreach (var entry in dictionary.ModelState) {
 28                 ModelState.Add(entry.Key, entry.Value);
 29             }
 30             Model = dictionary.Model;
 31         }
 32 
 33         [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]
 34         public int Count {
 35             get {
 36                 return _innerDictionary.Count;
 37             }
 38         }
 39 
 40         [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]
 41         public bool IsReadOnly {
 42             get {
 43                 return ((IDictionary<string, object>)_innerDictionary).IsReadOnly;
 44             }
 45         }
 46 
 47         [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]
 48         public ICollection<string> Keys {
 49             get {
 50                 return _innerDictionary.Keys;
 51             }
 52         }
 53 
 54         public object Model {
 55             get {
 56                 return _model;
 57             }
 58             set {
 59                 SetModel(value);
 60             }
 61         }
 62 
 63         public ModelStateDictionary ModelState {
 64             get {
 65                 return _modelState;
 66             }
 67         }
 68 
 69         [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]
 70         public object this[string key] {
 71             get {
 72                 object value;
 73                 _innerDictionary.TryGetValue(key, out value);
 74                 return value;
 75             }
 76             set {
 77                 _innerDictionary[key] = value;
 78             }
 79         }
 80 
 81         [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]
 82         public ICollection<object> Values {
 83             get {
 84                 return _innerDictionary.Values;
 85             }
 86         }
 87 
 88         [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]
 89         public void Add(KeyValuePair<string, object> item) {
 90             ((IDictionary<string, object>)_innerDictionary).Add(item);
 91         }
 92 
 93         [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]
 94         public void Add(string key, object value) {
 95             _innerDictionary.Add(key, value);
 96         }
 97 
 98         [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]
 99         public void Clear() {
100             _innerDictionary.Clear();
101         }
102 
103         [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]
104         public bool Contains(KeyValuePair<string, object> item) {
105             return ((IDictionary<string, object>)_innerDictionary).Contains(item);
106         }
107 
108         [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]
109         public bool ContainsKey(string key) {
110             return _innerDictionary.ContainsKey(key);
111         }
112 
113         [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]
114         public void CopyTo(KeyValuePair<string, object>[] array, int arrayIndex) {
115             ((IDictionary<string, object>)_innerDictionary).CopyTo(array, arrayIndex);
116         }
117 
118         [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Eval",
119             Justification = "Commonly used shorthand for Evaluate.")]
120         public object Eval(string expression) {
121             if (String.IsNullOrEmpty(expression)) {
122                 throw new ArgumentException(MvcResources.Common_NullOrEmpty, "expression");
123             }
124 
125             return ViewDataEvaluator.Eval(this, expression);
126         }
127 
128         [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Eval",
129             Justification = "Commonly used shorthand for Evaluate.")]
130         public string Eval(string expression, string format) {
131             object value = Eval(expression);
132 
133             if (value == null) {
134                 return String.Empty;
135             }
136 
137             if (String.IsNullOrEmpty(format)) {
138                 return Convert.ToString(value, CultureInfo.CurrentCulture);
139             }
140             else {
141                 return String.Format(CultureInfo.CurrentCulture, format, value);
142             }
143         }
144 
145         [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]
146         public IEnumerator<KeyValuePair<string, object>> GetEnumerator() {
147             return _innerDictionary.GetEnumerator();
148         }
149 
150         [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]
151         public bool Remove(KeyValuePair<string, object> item) {
152             return ((IDictionary<string, object>)_innerDictionary).Remove(item);
153         }
154 
155         [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]
156         public bool Remove(string key) {
157             return _innerDictionary.Remove(key);
158         }
159 
160         // This method will execute before the derived type's instance constructor executes. Derived types must
161         // be aware of this and should plan accordingly. For example, the logic in SetModel() should be simple
162         // enough so as not to depend on the "this" pointer referencing a fully constructed object.
163         protected virtual void SetModel(object value) {
164             _model = value;
165         }
166 
167         [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]
168         public bool TryGetValue(string key, out object value) {
169             return _innerDictionary.TryGetValue(key, out value);
170         }
171 
172         internal static class ViewDataEvaluator {
173             public static object Eval(ViewDataDictionary vdd, string expression) {
174                 //Given an expression "foo.bar.baz" we look up the following (pseudocode):
175                 //  this["foo.bar.baz.quux"]
176                 //  this["foo.bar.baz"]["quux"]
177                 //  this["foo.bar"]["baz.quux]
178                 //  this["foo.bar"]["baz"]["quux"]
179                 //  this["foo"]["bar.baz.quux"]
180                 //  this["foo"]["bar.baz"]["quux"]
181                 //  this["foo"]["bar"]["baz.quux"]
182                 //  this["foo"]["bar"]["baz"]["quux"]
183 
184                 object evaluated = EvalComplexExpression(vdd, expression);
185                 return evaluated;
186             }
187 
188             private static object EvalComplexExpression(object indexableObject, string expression) {
189                 foreach (ExpressionPair expressionPair in GetRightToLeftExpressions(expression)) {
190                     string subExpression = expressionPair.Left;
191                     string postExpression = expressionPair.Right;
192 
193                     object subtarget = GetPropertyValue(indexableObject, subExpression);
194                     if (subtarget != null) {
195                         if (String.IsNullOrEmpty(postExpression))
196                             return subtarget;
197 
198                         object potential = EvalComplexExpression(subtarget, postExpression);
199                         if (potential != null) {
200                             return potential;
201                         }
202                     }
203                 }
204                 return null;
205             }
206 
207             private static IEnumerable<ExpressionPair> GetRightToLeftExpressions(string expression) {
208                 // Produces an enumeration of all the combinations of complex property names
209                 // given a complex expression. See the list above for an example of the result
210                 // of the enumeration.
211 
212                 yield return new ExpressionPair(expression, String.Empty);
213 
214                 int lastDot = expression.LastIndexOf('.');
215 
216                 string subExpression = expression;
217                 string postExpression = string.Empty;
218 
219                 while (lastDot > -1) {
220                     subExpression = expression.Substring(0, lastDot);
221                     postExpression = expression.Substring(lastDot + 1);
222                     yield return new ExpressionPair(subExpression, postExpression);
223 
224                     lastDot = subExpression.LastIndexOf('.');
225                 }
226             }
227 
228             private static object GetIndexedPropertyValue(object indexableObject, string key) {
229                 Type indexableType = indexableObject.GetType();
230 
231                 ViewDataDictionary vdd = indexableObject as ViewDataDictionary;
232                 if (vdd != null) {
233                     return vdd[key];
234                 }
235 
236                 MethodInfo containsKeyMethod = indexableType.GetMethod("ContainsKey", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(string) }, null);
237                 if (containsKeyMethod != null) {
238                     if (!(bool)containsKeyMethod.Invoke(indexableObject, new object[] { key })) {
239                         return null;
240                     }
241                 }
242 
243                 PropertyInfo info = indexableType.GetProperty("Item", BindingFlags.Public | BindingFlags.Instance, null, null, new Type[] { typeof(string) }, null);
244                 if (info != null) {
245                     return info.GetValue(indexableObject, new object[] { key });
246                 }
247 
248                 PropertyInfo objectInfo = indexableType.GetProperty("Item", BindingFlags.Public | BindingFlags.Instance, null, null, new Type[] { typeof(object) }, null);
249                 if (objectInfo != null) {
250                     return objectInfo.GetValue(indexableObject, new object[] { key });
251                 }
252                 return null;
253             }
254 
255             private static object GetPropertyValue(object container, string propertyName) {
256                 // This method handles one "segment" of a complex property expression
257 
258                 // First, we try to evaluate the property based on its indexer
259                 object value = GetIndexedPropertyValue(container, propertyName);
260                 if (value != null) {
261                     return value;
262                 }
263 
264                 // If the indexer didn't return anything useful, continue
265 
266                 // If the container is a ViewDataDictionary then treat its Model property
267                 // as the container instead of the ViewDataDictionary itself.
268                 ViewDataDictionary vdd = container as ViewDataDictionary;
269                 if (vdd != null) {
270                     container = vdd.Model;
271                 }
272 
273                 // Second, we try to use PropertyDescriptors and treat the expression as a property name
274                 PropertyDescriptor descriptor = TypeDescriptor.GetProperties(container).Find(propertyName, true);
275                 if (descriptor == null) {
276                     return null;
277                 }
278 
279                 return descriptor.GetValue(container);
280             }
281 
282             private struct ExpressionPair {
283                 public readonly string Left;
284                 public readonly string Right;
285 
286                 public ExpressionPair(string left, string right) {
287                     Left = left;
288                     Right = right;
289                 }
290             }
291         }
292 
293         #region IEnumerable Members
294         [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]
295         IEnumerator IEnumerable.GetEnumerator() {
296             return ((IEnumerable)_innerDictionary).GetEnumerator();
297         }
298         #endregion
299 
300     }

  ViewData的用法如下:ViewData["user"] = LoginUser;  页面的代码<%=(ViewData["user"] as Users).UserName%>

  ViewData的作用域从控制器设置值到页面值显示。

2.使用TempData

  TempData同样属于ControllerBase 的属性 用法和ViewData 基本相同,但是他们的实质是不同的,ViewData 是数据字典类型而TempData是Session存储的值,TempData数据只能在控制器中传递一次,每个元素也只能被访问一次,然后Session中的值就会被自动删除,它的生命周期要比ViewData的要长.

 

3.使用Model

  使用Model 顾名思义就是将一个实体对象绑定在页面上,上面两种都是放在作用域中。这里只讲用法。

  public ActionResult Student()

  {

    DbContext context=new DbContext();

    Student stu=context.Single(s=>s.ID==1);

    return View(stu);

  }

  页面代码的使用:<%=(Model as MVCTest.Models.Student).Name %>  Model 是ViewPage d的一个属性值,用于         接收控制器中返回的值

  Model 传输数据还可以这样用:

  <%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<MVCTest.Models.Student>" %>

  <%=Model.Name %>

  使用泛型的ViewPage,将Model中的值指定特定类型不用强制性转换

4.传递多个对象类型

  其实传递多个对象类型,最简单的办法就是将这些对象封装成另外一个类的属性,然后将这个对象传递到页面。不在做介绍

   

时间: 2024-09-22 12:59:08

MVC进阶学习--View和Controller之间的数据传递(一)的相关文章

MVC进阶学习--View和Controller之间的数据传递(二)

1. 使用Request.Form MVC 将页面简单化,与WebForm中的事件机制完全不同,就和普通的html标签表单提交没有任何区别(当然WebForm中的事件机制其实也是表单提交).在表单提交之后,在Controller action中可以以Request.Form["key"] 的方式获取到值. Code1 <%Html.BeginForm("Index", "Home", FormMethod.Post); %>2   &

MVC进阶学习--个性化目录结构(二)

(一)  浅谈MVC目录结构 在上一篇(<MVC进阶学习--个性化目录结构(一)>)中了解到了MVC 的基本目录结构,以及各个目录的作用.我们只是说到了表面的目录结构,没有了解到它运行的原理.是不是MVC的目录结构只能有那种固定的模式呢,我们能否根据自己的需要扩展这些目录结构呢.答案是肯定的.因为asp.net MVC中引用了WebFromViewEngine 这个视图引擎 (二) WebFormViewEngine视图引擎 1.IView接口    IView接口是对MVC结构中View对象

Android实现Activities之间进行数据传递的方法

  Android实现Activities之间进行数据传递的方法 本文实例讲述了Android实现Activities之间进行数据传递的方法.分享给大家供大家参考.具体分析如下: 首先,先说明一下Activity的启动及关闭: 1. startActivity(Intent intent); 启动Activity finish(); 结束当前Activity 2. startActivityForResult(Intent intent, int requestCode); 以指定的请求码req

【iOS7的一些总结】2、视图控制器ViewControllers之间的数据传递(1)

这里我们用一个demo来说明ios是如何在视图控制器之间传递重要的参数的.本文先从手写UI来讨论,在下一篇文章中讨论在storyboard中传递数据. 首先新建一个空工程,并添加一个根视图控制器类,如下图所示: # 在函数didFinishLunchingWithOption中添加几行代码,完成后如下: - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)la

Android实现Activities之间进行数据传递的方法_Android

本文实例讲述了Android实现Activities之间进行数据传递的方法.分享给大家供大家参考.具体分析如下: 首先,先说明一下Activity的启动及关闭: 1. startActivity(Intent intent);  启动Activity        finish();  结束当前Activity 2. startActivityForResult(Intent intent, int requestCode);  以指定的请求码requestCode启动Activity fini

javascript表单之间的数据传递

javascript|数据  今天有朋友问我关于用javascript来进行页面各表单之间的数据传递的问题,我以前也写过,不过从来没有注意,今天总结了一下,希望能够给大家一些帮助,也帮助我总结以前学过,用过的知识.    一,最简单的就是同一个网页里的表单的数据传递.      举个实例,一个网页上有两个表单,每个表单里一个文本框,一个按钮.点按钮互相对操作对方的文本框的值.我们举的例子是把一个文本框付给另一个文本框.具体的HTML代码如下:  <html><head><ti

&amp;#106avascript表单之间的数据传递

数据     今天有朋友问我关于用javascript来进行页面各表单之间的数据传递的问题,我以前也写过,不过从来没有注意,今天总结了一下,希望能够给大家一些帮助,也帮助我总结以前学过,用过的知识.     一,最简单的就是同一个网页里的表单的数据传递.      举个实例,一个网页上有两个表单,每个表单里一个文本框,一个按钮.点按钮互相对操作对方的文本框的值.我们举的例子是把一个文本框付给另一个文本框.具体的HTML代码如下:  <html><head><title>

&amp;#106avascript表单之间的数据传递(1)

数据     今天有朋友问我关于用JAVASCRIPT来进行页面各表单之间的数据传递的问题,我以前也写过,不过从来没有注意,今天总结了一下,希望能够给大家一些帮助,也帮助我总结以前学过,用过的知识.     一,最简单的就是同一个网页里的表单的数据传递.      举个实例,一个网页上有两个表单,每个表单里一个文本框,一个按钮.点按钮互相对操作对方的文本框的值.我们举的例子是把一个文本框付给另一个文本框.具体的HTML代码如下: <html><head><title>U

【iOS7的一些总结】3、视图控制器ViewControllers之间的数据传递(2)

上文中记录了在手写代码实现UI的情况下,界面切换时不同视图控制器之间数据传递的机制.显示和消除界面使用的函数时presentViewController和dismissViewController函数,数据传递则可以采用代理.通知等机制.本文记录的是使用storyboard实现界面的情况下,采用segue相关的方法实现与上文中相同的功能. 首先要做的是新建一个单视图工程,建立完成后会生成一组(一个头文件和一个源文件称为一组)AppDelegate类,一组ViewController类,一个sto