ASP.NET MVC Beta 新特性之 IValueProvider

我们先来看一个简单的场景,例如我们的blog系统有一个Post的对象,Post对象有一个Tags属性和Categories属性,他们的类型分别是:

Post.Tags : StateList<string> (BlogEngine.NET 中的一个List<T>的扩展类型)
Post.Categories : StateList<Category>


假如我们要使用UpdataModel方法来对我们Post过来的Form表单数据更新到我们的Post对象中,可能会有如下的代码:

  1. /// <summary>
  2. /// 将提交过来的新随笔表单内容保存到数据库
  3. /// </summary>
  4. [AcceptVerbs("POST"), ActionName("NewPost")]
  5. public ActionResult SaveNewPost(FormCollection form)
  6. {
  7.     Post post = new Post();
  8.     try
  9.     {
  10.         UpdateModel(post, new[] { "Title", "Content", "Slug", "Tags", "Categories" });
  11.     }
  12.     catch
  13.     {
  14.         return View(post);
  15.     } 
  16.     ..
  17. }
复制代码

很明显,在上面的代码中,我们用UpdateModel来更新Tags和Categories属性的时候,是不可能成功的,因为UpdateModel方法不知道怎样将Form提交过来的"Tags"和"Categories"数据转换为StateList<string>类型和StateList<Category>类型。这时候就需要我们提供一个ValueProvider,来进行这个转换。 

要实现一个ValueProvider,我们只需要实现IValueProvider接口的GetValue方法,并且返回一个ValueProviderResult的结果就可以了。下面我们就写一个PostValueProvider来实现上面我们提出的情况。代码如下:

PostValueProvider

  1. public class PostValueProvider : IValueProvider
  2. {
  3.     private ControllerContext context;
  4.     //private DefaultValueProvider dProvider; 
  5.     public PostValueProvider(ControllerContext context)
  6.     {
  7.         this.context = context;
  8.         //dProvider = new DefaultValueProvider(context);
  9.     } 
  10.     #region IValueProvider 成员 
  11.     public ValueProviderResult GetValue(string name)
  12.     {
  13.         if (string.IsNullOrEmpty(name))
  14.         {
  15.             throw new ArgumentException("参数不能为空", "name");
  16.         }
  17.         switch (name)
  18.         {
  19.             case "Tags":
  20.                 return GetTagsValue();
  21.             case "Categories":
  22.                 return GetCategoriesValue();
  23.             default:
  24.                 return new DefaultValueProvider(context).GetValue(name);
  25.         }
  26.     } 
  27.     #endregion 
  28.     private ValueProviderResult GetTagsValue()
  29.     {
  30.         string strTags = GetValueFromRequest("Tags");
  31.         if (string.IsNullOrEmpty(strTags))
  32.         {
  33.             return null;
  34.         } 
  35.         string[] tags = strTags.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
  36.         StateList<string> tagsList = new StateList<string>();
  37.         foreach (string tag in tags)
  38.         {
  39.             tagsList.Add(tag.Trim().ToLowerInvariant());
  40.         } 
  41.         return new ValueProviderResult(tagsList, strTags, CultureInfo.InvariantCulture);
  42.     } 
  43.     private ValueProviderResult GetCategoriesValue()
  44.     {
  45.         string strCategories = GetValueFromRequest("Categories");
  46.         if (string.IsNullOrEmpty(strCategories))
  47.         {
  48.             return null;
  49.         } 
  50.         string[] categories = strCategories.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
  51.         StateList<Category> list = new StateList<Category>();
  52.         foreach (string c in categories)
  53.         {
  54.             list.Add(Category.GetCategory(new Guid(c)));
  55.         } 
  56.         return new ValueProviderResult(list, strCategories, CultureInfo.InvariantCulture);
  57.     } 
  58.     private string GetValueFromRequest(string name)
  59.     {
  60.         string value = null;
  61.         HttpRequestBase request = context.HttpContext.Request;
  62.         if (request != null)
  63.         {
  64.             if (request.QueryString != null)
  65.             {
  66.                 value = request.QueryString[name];
  67.             }
  68.             if (string.IsNullOrEmpty(value) && (request.Form != null))
  69.             {
  70.                 value = request.Form[name];
  71.             }
  72.         } 
  73.         return value;
  74.     }
  75. }
复制代码

然后我们就可以在UpdateModel方法中使用我们的PostValueProvider了:

  1. /// <summary>
  2. /// 将提交过来的新随笔表单内容保存到数据库
  3. /// </summary>
  4. [AcceptVerbs("POST"), ActionName("NewPost")]
  5. public ActionResult SaveNewPost(FormCollection form)
  6. {
  7.     Post post = new Post();
  8.     try
  9.     {
  10.         UpdateModel(post, new[] { "Title", "Content", "Slug", "Tags", "Categories" }, new PostValueProvider(ControllerContext));
  11.     }
  12.     catch
  13.     {
  14.         return View(post);
  15.     } 
  16.   ..
  17. }
复制代码
posted @ 2012-02-09 10:58  左轮death029  阅读(190)  评论(0编辑  收藏  举报