仓酷云

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 652|回复: 7
打印 上一主题 下一主题

[学习教程] NET网页编程之详解ASP.NET MVC对表举行通用的增编削

[复制链接]
因胸联盟 该用户已被删除
跳转到指定楼层
楼主
发表于 2015-1-16 14:25:55 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
简单的说:.net只有微软一家在做的,微软也不允许别人跟他做相同的工具,所以他就把需要的工具全部封装在.net的平台上了;而java是公开了。作者的写下此文的背景是一些项目自己范围不年夜的情形下,也有其他网友忧虑功能方面的成绩。在这里我们先看一下ASP.NETMVC对表是怎样举行通用的增编削操纵的。
准备常识:
1、懂得反射手艺
2、懂得C#3.0中扩大办法,散布类,Linqtoobject,Linqtosql
3、懂得ASP.NETMVC
在项目中每增加一个表常常都要增加一套增编削代码,并且这些代码良多情形下都很类似,这里我们给出一个通用的办理计划供人人参考。
1、筹办事情:
这里我们先要在数据库中增加两个表News和User以下图:然后拖到dbml中天生实体类。

这里我们先筹办一个接口:ICommonTable
Code
publicinterfaceICommonTable
{
intid{get;set;}
}
然后让News和User实体都承继于此接口
Code
publicpartialclassNews:ICommonTable
{
}
publicpartialclassUser:ICommonTable
{
}
2、通用删除操纵
分离增加NewsList.aspx和UserList.aspx两个view,增加体例拜见ASP.NETMVC理论系列2-复杂使用
在这两个View中到场删除链接:
<%=Html.ActionLink("删除","Delete",new{key=item.id,partialName="News"})%>

<%=Html.ActionLink("删除","Delete",new{key=item.id,partialName="User"})%>
然后增加一个Controller:
publicActionResultDelete(stringpartialName,int?key)
{
RepositoryBaserepositoryBase=newRepositoryBase(partialName);
repositoryBase.Delete(key??0);
returnRedirectToAction(partialName+"List");//前往到list
}
接上去我们先容一下RepositoryBase:

publicclassRepositoryBase
{
publicTypeEntityType{get;privateset;}
publicRepositoryBase(stringentityType)
{
Typetype=GetBllTypeByName(entityType);
EntityType=type;
}
publicICommonTableCreateNew()
{
return(ICommonTable)Activator.CreateInstance(EntityType);
}
///<summary>
///经由过程字符串取得其Type
///</summary>
///<paramname="typeName"></param>
///<returns></returns>
privatestaticTypeGetBllTypeByName(stringtypeName)
{
Typetype=null;
varass=AppDomain.CurrentDomain.GetAssemblies()
.Where(p=>p.FullName.Contains("CommonCEDemo"));
foreach(varainass)
{
type=a.GetTypes().Where(p=>p.Name==typeName).FirstOrDefault();
if(type!=null)
break;
}

if(type==null)
{
thrownewException("范例不决义:"+typeName);
}
returntype;
}
publicRepositoryBase(TypeentityType)
{
EntityType=entityType;
}
publicICommonTableGet(intid)
{
DBDataContextdb=Context.GetContext();
returndb.GetTable(EntityType).Cast<ICommonTable>().FirstOrDefault(p=>p.id==id);
}
publicvoidDelete(intid)
{
ICommonTablebllTable=Get(id);
Context.GetContext().GetTable(EntityType).DeleteOnSubmit(bllTable);
Context.GetContext().SubmitChanges();
}
}
这里边重点要了解的就是GetBllTypeByName办法。有了这个办法我们就能够静态的经由过程名字取得响应的Type了。这里另有个成绩就是DataContext是从何而来的,我们这里为了复杂起见全程声了然一个DataContext没有思索多线程的情形
publicclassContext
{
staticDBDataContextcontext;
staticContext()
{
if(context==null)
{
context=newDBDataContext();
}
}
publicstaticDBDataContextGetContext()
{
returncontext;
}
}
有个这些当我们想要对一个表举行删除是只需增加响应的链接就能够了(如<%=Html.ActionLink("删除","Delete",new{key=item.id,partialName="News"})%>)
3、通用增添、修正
起首增加一个CreateEditView.aspx视图
<asp:ContentID="Content2"ContentPlaceHolderID="MainContent"runat="server">
<%Html.RenderPartial(ViewData["PartialName"].ToString());%>
</asp:Content>
然后增加两个Partial视图News.ascx和User.ascx,这两个视图是分离基于News和User类的强范例视图,详细内容列入源码。
接上去我们增加响应的Controller
publicActionResultCreateEditView(stringpartialName,int?key)
{
ViewData["PartialName"]=partialName;
RepositoryBaserepositoryBase=newRepositoryBase(partialName);
ICommonTabletable;
if(key==null)
{
table=repositoryBase.CreateNew();
}
else
{
table=repositoryBase.Get(key??0);
}

returnView("CreateEditView",table);
}
[AcceptVerbs(HttpVerbs.Post)]
publicActionResultCreateEditView(stringpartialName,int?key,FormCollectionformCollection)
{
RepositoryBaserepositoryBase=newRepositoryBase(partialName);
ICommonTablebllTable;
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();
returnRedirectToAction(partialName+"List");//前往到list
}
这里边人人大概有疑问的就是this.UpdateModel(bllTable,true);这个办法在mvc框架中其实不存在,这是我增加的扩大办法,这个中央假如利用UpdateModel(bllTable)固然编译不会报错,但也没有更新乐成,查了一下mvc的源码,成绩就出在以下源码中:
protectedinternalboolTryUpdateModel<TModel>(TModelmodel,stringprefix,string[]includeProperties,string[]excludeProperties,IDictionary<string,ValueProviderResult>valueProvider)whereTModel:class{
if(model==null){
thrownewArgumentNullException("model");
}
if(valueProvider==null){
thrownewArgumentNullException("valueProvider");
}

Predicate<string>propertyFilter=propertyName=>BindAttribute.IsPropertyAllowed(propertyName,includeProperties,excludeProperties);
IModelBinderbinder=Binders.GetBinder(typeof(TModel));

ModelBindingContextbindingContext=newModelBindingContext(){
Model=model,
ModelName=prefix,
ModelState=ModelState,
ModelType=typeof(TModel),
PropertyFilter=propertyFilter,
ValueProvider=valueProvider
};
binder.BindModel(ControllerContext,bindingContext);
returnModelState.IsValid;
}
这个typeof(TModel)形成了只会更新声明范例中有的属性,把它换成model.GetType()就能够办理成绩了,我扩这的这个办法以下
publicstaticclassControllerExtension
{
///<summary>
///更新时是不是依照以后范例举行更新
///</summary>
///<typeparamname="TModel"></typeparam>
///<paramname="controller"></param>
///<paramname="model"></param>
///<paramname="isEx"></param>
publicstaticvoidUpdateModel<TModel>(thisControllercontroller,TModelmodel,boolisExtension)whereTModel:class
{
if(isExtension)
{
Predicate<string>propertyFilter=propertyName=>IsPropertyAllowed(propertyName,null,null);
IModelBinderbinder=ModelBinders.Binders.GetBinder(model.GetType());

ModelBindingContextbindingContext=newModelBindingContext()
{
Model=model,
ModelName=null,
ModelState=controller.ModelState,
ModelType=model.GetType(),
PropertyFilter=propertyFilter,
ValueProvider=controller.ValueProvider
};
binder.BindModel(controller.ControllerContext,bindingContext);
}
else
{
thrownewException("isExtension不克不及选择false");
}
}
privatestaticboolIsPropertyAllowed(stringpropertyName,string[]includeProperties,string[]excludeProperties)
{
boolincludeProperty=(includeProperties==null)||(includeProperties.Length==0)||includeProperties.Contains(propertyName,StringComparer.OrdinalIgnoreCase);
boolexcludeProperty=(excludeProperties!=null)&&excludeProperties.Contains(propertyName,StringComparer.OrdinalIgnoreCase);
returnincludeProperty&&!excludeProperty;
}
}
有了这些,当我们想对新表举行编纂和增加时只必要增加响应的Partial编纂视图就能够了,简化了我们的编程事情。
4、弱点
1、必要依照划定规矩定名,例如说Partial视图必要以响应的类名来定名
2、页面援用是弱范例的
我觉得这个学习方法很重要。初学者应该跟我一样有同样一个毛病。那就是急于求成。很想就自己做出个小小的系统来。可真要动手,却又茫然而不知所措。为什么会这样呢?因为我们没有耐心去学习基础知识。写根本看不到什么效果的测试代码。
乐观 该用户已被删除
沙发
发表于 2015-1-18 14:33:23 | 只看该作者
但是java靠开源打出的一片天地,特别是在微软的垄断下能打开今天的局面还是有它的生命力的。
小魔女 该用户已被删除
板凳
发表于 2015-1-24 12:38:29 | 只看该作者
以上是语言本身的弱点,在功能方面ASP同样存在问题,第一是功能太弱,一些底层操作只能通过组件来完成,在这点上是远远比不上PHP/JSP,其次就是缺乏完善的纠错/调试功能,这点上ASP/PHP/JSP差不多。
柔情似水 该用户已被删除
地板
发表于 2015-2-1 14:51:23 | 只看该作者
使用普通的文本编辑器编写,如记事本就可以完成。由脚本在服务器上而不是客户端运行,ASP所使用的脚本语言都在服务端上运行,用户端的浏览器不需要提供任何别的支持,这样大提高了用户与服务器之间的交互的速度。
愤怒的大鸟 该用户已被删除
5#
发表于 2015-2-21 06:18:32 | 只看该作者
大哥拜托,Java在95年就出来了,微软垄断个妹啊,服务器市场微软完全是后后来者,当年都是Unix的市场,现在被WindowsServer和Linux抢下大片,包括数据库也一样。
透明 该用户已被删除
6#
发表于 2015-3-6 19:56:23 | 只看该作者
使用普通的文本编辑器编写,如记事本就可以完成。由脚本在服务器上而不是客户端运行,ASP所使用的脚本语言都在服务端上运行,用户端的浏览器不需要提供任何别的支持,这样大提高了用户与服务器之间的交互的速度。
山那边是海 该用户已被删除
7#
发表于 2015-3-13 08:52:49 | 只看该作者
是目前ASP在UNIX/Linux上的应用可以说几乎为0)。所以平台的局限性和ASP自身的安全性限制了ASP的广泛应用。
只想知道 该用户已被删除
8#
发表于 2015-3-20 17:55:11 | 只看该作者
逐步缩小出错代码段的范围,最终确定错误代码的位置。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|仓酷云 鄂ICP备14007578号-2

GMT+8, 2025-2-23 22:19

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表