MVC编程之ASP.NET MVC中对表记录通用的增删改操作方案(2)
这里边重点要理解的就是GetBllTypeByName方法。有了这个方法我们就可以动态的通过名字获得相应的Type了。这里还有个问题就是DataContext是从何而来的,我们
这里边重点要理解的就是GetBllTypeByName方法。有了这个方法我们就可以动态的通过名字获得相应的Type了。这里还有个问题就是DataContext是从何而来的,我们这里为了简单起见全程声明了一个DataContext没有考虑多线程的情况
public class Context
{
static DBDataContext context;
static Context()
{
if (context==null)
{
context = new DBDataContext();
}
}
public static DBDataContext GetContext()
{
return context;
}
} 有个这些当我们想要对一个表进行删除是只要添加相应的链接就可以了(如<%= Html.ActionLink("删除", "Delete", new { key = item.id, partialName="News" })%>) 三、通用增加、修改 首先添加一个CreateEditView.aspx视图
{
static DBDataContext context;
static Context()
{
if (context==null)
{
context = new DBDataContext();
}
}
public static DBDataContext GetContext()
{
return context;
}
} 有个这些当我们想要对一个表进行删除是只要添加相应的链接就可以了(如<%= Html.ActionLink("删除", "Delete", new { key = item.id, partialName="News" })%>) 三、通用增加、修改 首先添加一个CreateEditView.aspx视图
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<%Html.RenderPartial(ViewData["PartialName"].ToString()); %>
</asp:Content> 然后添加两个Partial视图News.ascx和User.ascx,这两个视图是分别基于News和User类的强类型视图,具体内容参加源码。 接下来我们添加相应的Controller
<%Html.RenderPartial(ViewData["PartialName"].ToString()); %>
</asp:Content> 然后添加两个Partial视图News.ascx和User.ascx,这两个视图是分别基于News和User类的强类型视图,具体内容参加源码。 接下来我们添加相应的Controller
public ActionResult CreateEditView(string partialName, int? key)
{
ViewData["PartialName"] = partialName;
RepositoryBase repositoryBase = new RepositoryBase(partialName);
ICommonTable table;
if (key == null)
{
table = repositoryBase.CreateNew();
}
else
{
table = repositoryBase.Get(key ?? 0);
}
return View("CreateEditView", table);
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult CreateEditView(string partialName, int? key, FormCollection formCollection)
{
RepositoryBase repositoryBase = new RepositoryBase(partialName);
ICommonTable bllTable;
if (key == null)
{
bllTable = repositoryBase.CreateNew();
}
else
{
bllTable = repositoryBase.Get(key ?? 0);
}
this.UpdateModel(bllTable, true);
if (key == null)
{
Context.GetContext().GetTable(repositoryBase.EntityType).InsertOnSubmit(bllTable);
}
Context.GetContext().SubmitChanges();
return RedirectToAction(partialName+"List");//返回到list
}
这里边大家可能有疑问的就是this.UpdateModel(bllTable, true);这个方法在mvc框架中并不存在,这是我添加的扩展方法,这个地方如果使用UpdateModel(bllTable)虽然编译不会报错,但也没有更新成功,查了一下mvc的源码,问题就出在如下源码中:
{
ViewData["PartialName"] = partialName;
RepositoryBase repositoryBase = new RepositoryBase(partialName);
ICommonTable table;
if (key == null)
{
table = repositoryBase.CreateNew();
}
else
{
table = repositoryBase.Get(key ?? 0);
}
return View("CreateEditView", table);
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult CreateEditView(string partialName, int? key, FormCollection formCollection)
{
RepositoryBase repositoryBase = new RepositoryBase(partialName);
ICommonTable bllTable;
if (key == null)
{
bllTable = repositoryBase.CreateNew();
}
else
{
bllTable = repositoryBase.Get(key ?? 0);
}
this.UpdateModel(bllTable, true);
if (key == null)
{
Context.GetContext().GetTable(repositoryBase.EntityType).InsertOnSubmit(bllTable);
}
Context.GetContext().SubmitChanges();
return RedirectToAction(partialName+"List");//返回到list
}
这里边大家可能有疑问的就是this.UpdateModel(bllTable, true);这个方法在mvc框架中并不存在,这是我添加的扩展方法,这个地方如果使用UpdateModel(bllTable)虽然编译不会报错,但也没有更新成功,查了一下mvc的源码,问题就出在如下源码中:
protected internal bool TryUpdateModel<TModel>(TModel model, string prefix, string[] includeProperties, string[] excludeProperties, IDictionary<string, ValueProviderResult> valueProvider) where TModel : class {
if (model == null) {
throw new ArgumentNullException("model");
}
if (valueProvider == null) {
throw new ArgumentNullException("valueProvider");
}
Predicate<string> propertyFilter = propertyName => BindAttribute.IsPropertyAllowed(propertyName, includeProperties, excludeProperties);
IModelBinder binder = Binders.GetBinder(typeof(TModel));
ModelBindingContext bindingContext = new ModelBindingContext() {
Model = model,
ModelName = prefix,
ModelState = ModelState,
ModelType = typeof(TModel),
PropertyFilter = propertyFilter,
ValueProvider = valueProvider
};
binder.BindModel(ControllerContext, bindingContext);
return ModelState.IsValid;
} 这个typeof(TModel)造成了只会更新声明类型中有的属性,把它换成model.GetType()就可以解决问题了,我扩这的这个方法如下
if (model == null) {
throw new ArgumentNullException("model");
}
if (valueProvider == null) {
throw new ArgumentNullException("valueProvider");
}
Predicate<string> propertyFilter = propertyName => BindAttribute.IsPropertyAllowed(propertyName, includeProperties, excludeProperties);
IModelBinder binder = Binders.GetBinder(typeof(TModel));
ModelBindingContext bindingContext = new ModelBindingContext() {
Model = model,
ModelName = prefix,
ModelState = ModelState,
ModelType = typeof(TModel),
PropertyFilter = propertyFilter,
ValueProvider = valueProvider
};
binder.BindModel(ControllerContext, bindingContext);
return ModelState.IsValid;
} 这个typeof(TModel)造成了只会更新声明类型中有的属性,把它换成model.GetType()就可以解决问题了,我扩这的这个方法如下
public static class ControllerExtension
{
/// <summary>
/// 更新时是否按照当前类型进行更新
/// </summary>
/// <typeparam name="TModel"></typeparam>
/// <param name="controller"></param>
/// <param name="model"></param>
/// <param name="isEx"></param>
public static void UpdateModel<TModel>(this Controller controller, TModel model, bool isExtension) where TModel : class
{
if (isExtension)
{
Predicate<string> propertyFilter = propertyName => IsPropertyAllowed(propertyName, null, null);
IModelBinder binder = ModelBinders.Binders.GetBinder(model.GetType());
ModelBindingContext bindingContext = new ModelBindingContext()
{
Model = model,
ModelName = null,
ModelState = controller.ModelState,
ModelType = model.GetType(),
PropertyFilter = propertyFilter,
ValueProvider = controller.ValueProvider
};
binder.BindModel(controller.ControllerContext, bindingContext);
}
else
{
throw new Exception("isExtension不能选择false");
}
}
private static bool IsPropertyAllowed(string propertyName, string[] includeProperties, string[] excludeProperties)
{
bool includeProperty = (includeProperties == null) || (includeProperties.Length == 0) || includeProperties.Contains(propertyName, StringComparer.OrdinalIgnoreCase);
bool excludeProperty = (excludeProperties != null) && excludeProperties.Contains(propertyName, StringComparer.OrdinalIgnoreCase);
return includeProperty && !excludeProperty;
}
} 有了这些,当我们想对新表进行编辑和添加时只需要添加相应的Partial编辑视图就可以了,简化了我们的编程工作。 四、缺点 1、须要按照规则命名,比方说Partial视图需要以相应的类名来命名 2、页面引用是弱类型的 五、源码下载
{
/// <summary>
/// 更新时是否按照当前类型进行更新
/// </summary>
/// <typeparam name="TModel"></typeparam>
/// <param name="controller"></param>
/// <param name="model"></param>
/// <param name="isEx"></param>
public static void UpdateModel<TModel>(this Controller controller, TModel model, bool isExtension) where TModel : class
{
if (isExtension)
{
Predicate<string> propertyFilter = propertyName => IsPropertyAllowed(propertyName, null, null);
IModelBinder binder = ModelBinders.Binders.GetBinder(model.GetType());
ModelBindingContext bindingContext = new ModelBindingContext()
{
Model = model,
ModelName = null,
ModelState = controller.ModelState,
ModelType = model.GetType(),
PropertyFilter = propertyFilter,
ValueProvider = controller.ValueProvider
};
binder.BindModel(controller.ControllerContext, bindingContext);
}
else
{
throw new Exception("isExtension不能选择false");
}
}
private static bool IsPropertyAllowed(string propertyName, string[] includeProperties, string[] excludeProperties)
{
bool includeProperty = (includeProperties == null) || (includeProperties.Length == 0) || includeProperties.Contains(propertyName, StringComparer.OrdinalIgnoreCase);
bool excludeProperty = (excludeProperties != null) && excludeProperties.Contains(propertyName, StringComparer.OrdinalIgnoreCase);
return includeProperty && !excludeProperty;
}
} 有了这些,当我们想对新表进行编辑和添加时只需要添加相应的Partial编辑视图就可以了,简化了我们的编程工作。 四、缺点 1、须要按照规则命名,比方说Partial视图需要以相应的类名来命名 2、页面引用是弱类型的 五、源码下载
精彩图集
精彩文章