ASP.NET MVC Beta版中,在UpdataModel方法中提供了一个带有IValueProvider参数的重载。那么这个IValueProvider有什么用呢?
我们先来看一个简单的场景,例如我们的blog系统有一个Post的对象,Post对象有一个Tags属性和Categories属性,他们的类型分别是:
- Post.Tags : StateList<string> (BlogEngine.NET 中的一个List<T>的扩展类型)
- Post.Categories : StateList<Category>
假如我们要在ASP.NET MVC中使用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
- publicclassPostValueProvider:IValueProvider
- {
- privateControllerContextcontext;
- //privateDefaultValueProviderdProvider;
- publicPostValueProvider(ControllerContextcontext)
- {
- this.context=context;
- //dProvider=newDefaultValueProvider(context);
- }
- #regionIValueProvider成员
- publicValueProviderResultGetValue(stringname)
- {
- if(string.IsNullOrEmpty(name))
- {
- thrownewArgumentException("参数不能为空","name");
- }
- switch(name)
- {
- case"Tags":
- returnGetTagsValue();
- case"Categories":
- returnGetCategoriesValue();
- default:
- returnnewDefaultValueProvider(context).GetValue(name);
- }
- }
- #endregion
- privateValueProviderResultGetTagsValue()
- {
- stringstrTags=GetValueFromRequest("Tags");
- if(string.IsNullOrEmpty(strTags))
- {
- returnnull;
- }
- string[]tags=strTags.Split(newstring[]{","},StringSplitOptions.
RemoveEmptyEntries);- StateList<string>tagsList=newStateList<string>();
- foreach(stringtagintags)
- {
- tagsList.Add(tag.Trim().ToLowerInvariant());
- }
- returnnewValueProviderResult(tagsList,strTags,CultureInfo.
InvariantCulture);- }
- privateValueProviderResultGetCategoriesValue()
- {
- stringstrCategories=GetValueFromRequest("Categories");
- if(string.IsNullOrEmpty(strCategories))
- {
- returnnull;
- }
- string[]categories=strCategories.Split(newstring[]{","},
StringSplitOptions.RemoveEmptyEntries);- StateList<Category>list=newStateList<Category>();
- foreach(stringcincategories)
- {
- list.Add(Category.GetCategory(newGuid(c)));
- }
- returnnewValueProviderResult(list,strCategories,CultureInfo.InvariantCulture);
- }
- privatestringGetValueFromRequest(stringname)
- {
- stringvalue=null;
- HttpRequestBaserequest=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];
- }
- }
- returnvalue;
- }
- }
然后我们就可以在UpdateModel方法中使用我们的PostValueProvider了:
- ///<summary>
- ///将提交过来的新随笔表单内容保存到数据库
- ///</summary>
- [AcceptVerbs("POST"),ActionName("NewPost")]
- publicActionResultSaveNewPost(FormCollectionform)
- {
- Postpost=newPost();
- try
- {
- UpdateModel(post,new[]{"Title","Content","Slug","Tags","Categories"},
newPostValueProvider(ControllerContext));- }
- catch
- {
- returnView(post);
- }
- ..
- }
以上介绍ASP.NET MVC中使用UpdataModel方法。
【编辑推荐】