ASP.NET MVC Beta 新特性之 IValueProvider


在刚发布的ASP.NET MVC Beta版中,在UpdataModel方法中提供了一个带有IValueProvider参数的重载。那么这个IValueProvider有什么用呢?

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

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

  Post.Categories : StateList<Category>

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

/// <summary>
/// 将提交过来的新随笔表单内容保存到数据库
/// </summary>
[AcceptVerbs("POST"), ActionName("NewPost")]
public ActionResult SaveNewPost(FormCollection form)
{
  Post post = new Post();
  try
  {
    UpdateModel(post, new[] { "Title", "Content", "Slug", "Tags", "Categories" });
  }
  catch
  {
    return View(post);
  }
  ..
}
很明显,在上面的代码中,我们用UpdateModel来更新Tags和Categories属性的时候,是不可能成功的,因为UpdateModel方法不知道怎样将Form提交过来的"Tags"和"Categories"数据转换为StateList<string>类型和StateList<Category>类型。这时候就需要我们提供一个ValueProvider,来进行这个转换。

  要实现一个ValueProvider,我们只需要实现IValueProvider接口的GetValue方法,并且返回一个ValueProviderResult的结果就可以了。下面我们就写一个PostValueProvider来实现上面我们提出的情况。代码如下:
PostValueProvider
public class PostValueProvider : IValueProvider
{
  private ControllerContext context;
  //private DefaultValueProvider dProvider;
  public PostValueProvider(ControllerContext context)
  {
    this.context = context;
    //dProvider = new DefaultValueProvider(context);
  }
  #region IValueProvider 成员
  public ValueProviderResult GetValue(string name)
  {
    if (string.IsNullOrEmpty(name))
    {
      throw new ArgumentException("参数不能为空", "name");
    }
    switch (name)
    {
      case "Tags":
        return GetTagsValue();
      case "Categories":
        return GetCategoriesValue();
      default:
        return new DefaultValueProvider(context).GetValue(name);
    }
  }
  #endregion
  private ValueProviderResult GetTagsValue()
  {
    string strTags = GetValueFromRequest("Tags");
    if (string.IsNullOrEmpty(strTags))
    {
      return null;
    }
    string[] tags = strTags.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
    StateList<string> tagsList = new StateList<string>();
    foreach (string tag in tags)
    {
      tagsList.Add(tag.Trim().ToLowerInvariant());
    }
    return new ValueProviderResult(tagsList, strTags, CultureInfo.InvariantCulture);
  }
  private ValueProviderResult GetCategoriesValue()
  {
    string strCategories = GetValueFromRequest("Categories");
    if (string.IsNullOrEmpty(strCategories))
    {
      return null;
    }
    string[] categories = strCategories.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
    StateList<Category> list = new StateList<Category>();
    foreach (string c in categories)
    {
      list.Add(Category.GetCategory(new Guid(c)));
    }
    return new ValueProviderResult(list, strCategories, CultureInfo.InvariantCulture);
  }
  private string GetValueFromRequest(string name)
  {
    string value = null;
    HttpRequestBase request = context.HttpContext.Request;
    if (request != null)
    {
      if (request.QueryString != null)
      {
        value = request.QueryString[name];
      }
      if (string.IsNullOrEmpty(value) && (request.Form != null))
      {
        value = request.Form[name];
      }
    }
    return value;
  }
}
然后我们就可以在UpdateModel方法中使用我们的PostValueProvider了:


/// <summary>
/// 将提交过来的新随笔表单内容保存到数据库
/// </summary>
[AcceptVerbs("POST"), ActionName("NewPost")]
public ActionResult SaveNewPost(FormCollection form)
{
  Post post = new Post();
  try
  {
    UpdateModel(post, new[] { "Title", "Content", "Slug", "Tags", "Categories" }, new PostValueProvider(ControllerContext));
  }
  catch
  {
    return View(post);
  }
  ..
}

  如果你想了解更多关于ASP.NET MVC的内容,可以参考ASP.NET MVC 入门系列

本文作者:
« 
» 
快速导航

Copyright © 2016 phpStudy | 豫ICP备2021030365号-3