刚学习asp.net教材推荐,请推荐asp.net教材推荐论坛

页面导航:
→ 正文内容 ASP.NET MVC
ASP.NET MVC学习笔记
ASP.NET MVC 1.0发布有段儿时间了,刚发布不久的时候试用了一下,做了一个简单的BBS,现在总结一些经验和小技巧和大家分享。
网上关于ASP.NET MVC的系列教程有好几个,所以就不从头开始介绍了,结尾处给大家推荐了几个链接,需要的话可以从头系统的看看。1、ASP.NET MVC介绍及与ASP.NET WebForm的区别 刚开始为了搞清楚ASP.NET MVC到底值不值得用,翻来覆去想了一个多礼拜,看了好多资料和评论,最后决定还是值得一用。MVC不是一个简单的设计模式,更像一种架构模式,或者一种思想,刚开始一听MVC想到的就是模板引擎,NVelocity,StringTempleate等,但感觉如果只是为了用模板这种独立的前台设计方式,没必要用ASP.NET MVC,大多数情况用Repeaterk控件和自定义控件儿就能做到,而且ASPX页面上本来就可以写c#代码,一些比较复杂的界面表现逻辑用普通的WebForm也能实现,其实ASP.NET MVC的VIEW部分默认用的还是aspx的解析器。ASP.NET MVC的View部分让你写一些大型的,布局复杂的网站更方便,更底层,更直接,很受对css,js很熟悉的开发者的欢迎。 当你理解了MVC的思想后,会发现ASP.NET MVC的好处真正在于Controller和Action,你写一段代码能很明确的知道是在处理什么请求,毕竟web程序处理的是一个一个的http请求,不像windows桌面程序,基于事件驱动更直观。ASP.NET MVC的Controller让你写一些web api或者rest风格的接口很方便(以前可能要用HttpHandler来做),这些Controller只负责提供数据(具体的ActionResult类,如JsonResult,JavascriptResult等)给使用者,比如一个Ajax调用,或者View层。 至于Model层,我看网上大多数人是用LINQ TO SQL实现的,毕竟使用起来很简单,设计好表,用LINQ 设计器往vs.net里一拖就能用了。而且本身就是强类型的,再在自动生成的代码上加一些分部方法,就可以实现数据的有效性验证等。还有就是对LINQ做的Model进行数据持久化和查询的时候更方便,直接用DbContext一个类,增删改查全能搞定。 有得就有舍,ASP.NET MVC虽然提供了先进的思想和一些便利,但ASP.NET以前的一些东西不能用了,比如以前自己写的一些服务器控件儿不能用了,WebPart,皮肤,各种数据绑定控件等都不能用了,但Master页还能用,Asp.net Ajax control toolkit(服务端)也不能用了,但asp.net ajax library(客户端js库)还能继续使用,基于页面和目录的授权不能用了(因为现在没页面,只有view了),但MemberShip和Forms身份验证还是支持的。标准WebForm的生命周期变了,好些事件没了,现在你可以写一些拦截器(Action拦截器、Result拦截器和Exception拦截器)来影响请求的处理过程,还有一些区别,总之失去的东西,都有变通的方法能找吧回来。 2、linq to sql如何获取插入语句产生的标识列的值? 其实很简单,把对象插入数据库后,直接取值就行了,如下BBSPost是一个实体类,其中PostID在数据库里是自增列。
代码如下: var db = new BBSDbContext(connstr); BBSPost post = new BBSPost() post.PostUser = User.Identity.N post.PostTime = DateTime.N db.BBSPosts.InsertOnSubmit(post); db.SubmitChanges(); int postid = post.PostID; //这里就能取到标识列的值。
3、ASP.NET MVC里在请求提交后如何后维持滚动条位置? 在WebForm里再简单不过了,在web.config里配置MaintainScrollPositionOnPostBack=true就搞定了,但在MVC里就不行了。我们知道了原理后,可以自己实现,其实就是在提交表单或者滚动条滚动的事件里捕获当前滚动条的位置,把数值放在一个隐藏域里,提交给服务端,服务端应答后,从隐藏域里取出滚动条的位置,用js操纵滚动条滚动到上次的位置。 我们先在View里写一个隐藏域,如下 &%= Html.Hidden("scroll", ViewData["scrool"])%& 然后在处理客户端请求的action里给ViewData里存储一下提交上来的值(从FormCollection里取)。
代码如下: public ActionResult reply(BBSPost post, FormCollection coll) { ... ViewData["scroll"] = coll["scroll"]; ... return View("show_post",posts); }
这样页面提交后隐藏域里就会保存着提交前滚动条的位置,然后我们在用JQuery写一些逻辑实现最终的效果。
代码如下: &script type="text/javascript"& $(function() { $(document).scroll(function() { //在滚动条滚动的时候更新隐藏域里滚动条的位置值,经测试不支持IE8,汗 $("#scroll").val(document.documentElement.scrollTop); }); $("form").submit(function() { //在表单提交的时候更新隐藏域里滚动条的位置值 $("#scroll").val(document.documentElement.scrollTop);
}); //在document.load事件里取出隐藏域的值,并设置滚动条的位置 document.documentElement.scrollTop = $("#scroll").val(); }); &/script&
4、验证用户输入 数据有效性的验证基本上哪个程序都躲不了,LINQ 和ASP.NET MVC的配合,让数据验证的实现也很方便。 LINQ TO SQL设计器自动生成的类是一个分部类,就是半块儿的类,你可以写一个分步类,在自动生成的类上加一些扩展的方法,如下我们在LINQ实体类BBSPost上加了一个GetRuleViolations方法,一个IsValid属性,其中GetRuleViolations方法验证给实体类赋的值的有效性,用yield关键字返回一个枚举器,这里可以写你自己的数据有效性验证逻辑。 IsValid属性内部调用GetRuleViolations方法,如果返回的枚举器的Count不是0的话,表示数据有效性验证不通过。 另外为了方式LINQ TO SQL往数据库里写入无效数据,我们给OnValidate分布方法加了两行代码,在数据有效性验证不通过的情况下写数据库之前抛出异常。
代码如下: public partial class BBSPost { public bool IsValid { get { return (GetRuleViolations().Count() == 0); } } public IEnumerable&RuleViolation& GetRuleViolations() { if (String.IsNullOrEmpty(Title)) yield return new RuleViolation("标题必须输入", "Title"); if (String.IsNullOrEmpty(Content)) yield return new RuleViolation("内容必须输入", "Content");
} partial void OnValidate(ChangeAction action) { if (!IsValid) throw new ApplicationException("Rule violations prevent saving"); } }
RuleViolation是一个辅助类,很简单。
代码如下: public class RuleViolation { public string ErrorMessage { } public string PropertyName { } public RuleViolation(string errorMessage) { ErrorMessage = errorM } public RuleViolation(string errorMessage, string propertyName) { ErrorMessage = errorM PropertyName = propertyN } }
在写action的时候,捕获SubmitChanges操作的异常,然后给ModelState里添加自定义验证逻辑的异常,ModelState会把添加进去的异常传递给View层,供View层使用。
代码如下: try { var db = new BBSDbContext(GlobalHelper.Conn); post.PostUser = User.Identity.N //其它赋值操作 db.BBSPosts.InsertOnSubmit(post); db.SubmitChanges(); ModelState.Clear(); } catch (Exception ex) { ModelState.AddModelErrors(post.GetRuleViolations()); ModelState.AddModelError("exception", ex); } 默认的ModelState没有AddModelErrors方法,只有AddModelError方法,我们是后来给他加了一个扩展方法,如下 public static class ModelStateHelpers { public static void AddModelErrors(this ModelStateDictionary modelState, IEnumerable&RuleViolation& errors) { foreach (RuleViolation issue in errors) { modelState.AddModelError(issue.PropertyName, issue.ErrorMessage); } } }
在View层使用了Html.ValidationMessage方法在合适的位置输出错误描述,如果View呈现的时候ModelState里有错误的话,会自动显示相应的错误描述,代码示例如下。
代码如下: &p& &label for="Title"& 标题:&/label& &%= Html.TextBox("Title", null, new { style = "width:700" })%& &%= Html.ValidationMessage("Title") %& &/p& &p& &label for="Content"& 内容:&/label& &%= Html.TextArea("Content", null, new { style = "width:700height:100" })%& &%= Html.ValidationMessage("Content")%& &/p&
5、LINGQ TO SQL的分页 SQLSERVER 2005有很强悍的分页函数,LINQ TO SQL对其有很好的支持,IQueryable&T&的Skip和Take方法最终就生成分页的SQL,先写如下的一个帮助类(取自NerdDinner),这个类的属性很简单,见名知意,就不介绍了。
代码如下: public class PaginatedList&T& : List&T& { public int PageIndex { } public int PageSize { } public int TotalCount { } public int TotalPages { } public PaginatedList(IQueryable&T& source, int pageIndex, int pageSize) { PageIndex = pageI PageSize = pageS TotalCount = source.Count(); TotalPages = (int) Math.Ceiling(TotalCount / (double)PageSize); this.AddRange(source.Skip(PageIndex * PageSize).Take(PageSize)); //这句会停止延迟加载,把数据加载到内存里 } public bool HasPreviousPage { get { return (PageIndex & 0); } } public bool HasNextPage { get { return (PageIndex+1 & TotalPages); } } }
使用起来很简单,用LINQ TO SQL得到一个IQueryable后,再用其New一个PaginatedList就表示一个已分页的数据集了
代码如下: var posts = from post in db.BBSPosts where post.CategoryID == id && post.ParentID == 0 orderby post.PostID descending
const int pageSize = 10; var pagePosts = new PaginatedList&BBSPost&(posts, page ?? 0, pageSize); return View(pagePosts);
posts是用linq to sql生成的一个IQueryable&BBSPost&对象,这时候SQL语句并没有执行,会延迟执行,再new一个PaginatedList&BBSPost&的时候会对其生成的SQL语句进行修改,最后把pagePosts传递给view层用就行了,View层我们使用了强类型的View,如下 &%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage&SimpleBBS.Helpers.PaginatedList&SimpleBBS.Models.BBSPost&&" %& 页面上要显示上一页,下一页的链接,写起来也很简单
代码如下: &div class="pagination"& &% if (Model.HasPreviousPage) { %& &%= Html.RouteLink("上一页", "Default", new { page=(Model.PageIndex-1) }) %& &% } %& &% if (Model.HasNextPage) { %& &%= Html.RouteLink("下一页", "Default", new { page = (Model.PageIndex + 1) })%& &% } %& &/div&
6、查看LINQ TO SQL生成的SQL语句? 有人怀疑LINQ TO SQL的性能问题,认为它生成的语句不靠谱,其实它生成的语句都是参数化查询,一般的基于主键或者索引列的查询及大多数更新操作性能应该不会比手写SQL差,如果还是不放心的话,可以把LINQ TO SQL生成的SQL打印出来,以避免性能查的语句产生。 如下代码
代码如下: var db = new BBSDbContext(conn); var posts = from post in db.BBSPosts where post.CategoryID == 1 && post.ParentID == 0 orderby post.PostID descending select new {post.PostID, post.Title, post.Content}; db.Log = Response.O //跟踪自动生成的SQL语句 rpt1.DataSource = rpt1.DataBind(); //只有真正执行使用数据的语句时,SQL查询才会执行,在这之前语句只是语句,自动延迟执行的。
会在页面上看到LINQ TO SQL生成的SQL语句 SELECT [t0].[PostID], [t0].[Title], [t0].[Content] FROM [dbo].[bbs_Post] AS [t0] WHERE ([t0].[CategoryID] = @p0) AND ([t0].[ParentID] = @p1) ORDER BY [t0].[PostID] DESC -- @p0: Input Int (Size = 0; Prec = 0; Scale = 0) [1] -- @p1: Input Int (Size = 0; Prec = 0; Scale = 0) [0] -- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 3.5.30729.1 如果改成如下分页方式
代码如下: var db = new BBSDbContext(conn); var posts = from post in db.BBSPosts where post.CategoryID == 1 && post.ParentID == 0 orderby post.PostID descending
db.Log = Response.O rpt1.DataSource = posts.Skip(1 * 5).Take(5); rpt1.DataBind();
会输出如下SQL SELECT [t1].[CategoryID], [t1].[PostID], [t1].[ParentID], [t1].[Title], [t1].[Content], [t1].[PostUser], [t1].[PostTime] FROM ( SELECT ROW_NUMBER() OVER (ORDER BY [t0].[PostID] DESC) AS [ROW_NUMBER], [t0].[CategoryID], [t0].[PostID], [t0].[ParentID], [t0].[Title], [t0].[Content], [t0].[PostUser], [t0].[PostTime] FROM [dbo].[bbs_Post] AS [t0] WHERE ([t0].[CategoryID] = @p0) AND ([t0].[ParentID] = @p1) ) AS [t1] WHERE [t1].[ROW_NUMBER] BETWEEN @p2 + 1 AND @p2 + @p3 ORDER BY [t1].[ROW_NUMBER] -- @p0: Input Int (Size = 0; Prec = 0; Scale = 0) [1] -- @p1: Input Int (Size = 0; Prec = 0; Scale = 0) [0] -- @p2: Input Int (Size = 0; Prec = 0; Scale = 0) [5] -- @p3: Input Int (Size = 0; Prec = 0; Scale = 0) [5] -- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 3.5.30729.1 可以看到这些查询用的都是参数化查询,不是拼SQL,而且还用了ROW_NUMBER函数,LINQ TO SQL还是比较了解SQLSERVER的。 7、设置某个Action需要身份认证? 因为基于页面的授权不能使用了,我们只好对某个Action进行授权,比如要回复帖子的话需要进行登录,那么就在reply的action上加上需要身份验证的属性修饰,如下 [AcceptVerbs(HttpVerbs.Post), Authorize] ?public ActionResult reply(BBSPost post, FormCollection coll) { 这种方式是以AOP注入方式实现的,更多的拦截器示例,或者想写自己的拦截器可以google些资料看看。 8、如何把用户提交的表单数据转成强类型。 我们都知道网页上提交的数据包括Form里和QueryString,在服务端取出来都是string类型的,在asp时代,我们需要一个一个的处理参数,在ASP.NET MVC里就很方便了,比如你有一个BBSPost类,有Title和Content和CategoryId 3个属性,而表单上有两个文本框Title和Content,地址栏参数里有一个CategoryId,你可以直接在action里取到一个BBSPost类,而且属性都给你填充好了,不用你取出一个一个的string再new一个BBSPost类,再转类型赋值等一系列操作了,如下 public ActionResult reply(BBSPost post, FormCollection coll) {} 第一个参数会自动填充成强类型,第二个参数可以取出原始的表单提交的数据。如果你想了解更多的表单数据和强类型数据的绑定,细节,可以查查DefaultModelBinder是如何工作的。 9、给HTMLHelper加扩展方法。 ASP.NET MVC里的一个最佳实践就是给HTMLHelper加一些常用的扩展方法以供View层方便使用,不要到处写帮助类,比如在显示帖子的时候要格式化帖子成HTML格式,我们写了如下的扩展方法
代码如下: public static class HtmlHelperExtension { public static string Text2Html(this HtmlHelper helper, string input) { input = input.Replace(" ", "&"); input = input.Replace("\r\n", "&br /&"); input = input.Replace("\t", "&&&");
在view上先引用扩展方法所在的命名空间 &%@ Import Namespace="SimpleBBS.Helpers" %& 然后扩展方法就能使用了,如下 &%= Html.Text2Html(Html.Encode(item.Content)) %& 10、如何定位脚本和CSS的位置 如果我们目录级别特别多,把脚本,样式表等放在一个固定的目录后,在特定的子目录访问这些资源路径可能不一致,在WebForm的时候只有服务端控件才能使用~语法,无论是部署在站点根目录还是虚拟目录,~都能表示应用的根目录,在ASP.NET MVC里我们可以用Url.Content来使用~,如下 &script src="&%=Url.Content("~/Scripts/jquery-1.3.2.min.js")%&" type="text/javascript"&&/script&
上一篇:下一篇:
最 近 更 新
热 点 排 行
12345678910您当前的位置: -& 下载中心 -&
asp.net经典入门教程PDF电子书下载 ┆适合刚学asp.net的朋友下载
软件大小:3.71 MB
更新: 11:26:00
⊙v⊙找到您需要的资源啦?本站所有软件都可以高速免费下载!记的下次再来哦!
如感觉本站不错,请您互相转达!谢谢!感谢您的支持!
软件编号:#13627
& &[下载地址列表]==[版权原因部分软件停止下载]
& 提示1:不弹出下载地址请检查浏览器设置!
& 提示2:出现该页无法显示请重复尝试!
& 提示3:404错误,可能资源正在整理或者出错了!
& 提示4:如果更新日期为今天,可能还没有上传!&
本站所有软件解压缩密码:我们的网址就是密码(用英文小写输入)哦!
& 上一软件:
& 下一软件:
asp.net经典入门教程PDF电子书由浅入深,层层深入的讲解了ASP.NET技术,在本书中写作中,例子都使用了VB.NET的语法。
本书面向初、中、高级用户,全面系统地介绍了ASP.NET的特点、基础知识和具体的应用
如果您刚开始学习asp.net,并且对VB的语法或对ASP很熟悉的话,你将会发现很快就可以上手。如果你精通别的编程语言,通过对本书的阅读,也会让你跟上编程技术发展的前沿。
本站虽提供“asp.net经典入门教程PDF电子书下载 ┆适合刚学asp.net的朋友下载”绿色版免费下载,但是版权归原作者或公司所有。侵权问题,请联系我删除!
&一、“吃水不忘挖井人”请您将本次下载的软件转发到微博、论坛、空间等可发布的地方,并留下网址脚印,与更多的人分享这个网站吧?谢谢!
&二、本站是一个非赢利性公益网站,我们仅提供正规软件免费下载服务,例如提供“绿色版”“免费版”软件下载,但是本站绝不提供下载各种“破解版”或包含“注册码”以及“序列号”的软件,更不参与破解,写注册机等!
另外本站也一直在逐步全部正规化,而且一直在向正规化而努力。。免费+正规化是唯一出路。。
&三、为了达到最快的下载速度,推荐使用 网际快车 或 迅雷 下载本站软件。为确保正常使用请用最新版 WinRAR 来解压本站提供的软件!
&四、所有软件全部为网络搜集而来,提供下载属学习所用,请大家支持正版,下载试用后联系原作者购买!请在下载此软件后24小时内删除!谢谢合作!感谢您的支持!如对本站有建议或问题请发mail到:
Copyright &
偶要下载() All Rights Reserved
鲁ICP备号 - QQ:832469 mail:
中国提供的所有软件均来自互联网,下载个人纯属学习交流之用,如有侵犯您的版权请与我联系,我们会马上改正请在下载24小时内删除!本博客已经转移至,可能不会及时更新和关注留言记录,mvc请加群(已满),8781765
上一篇文章中()我们基础的了解了一下ASP.NET MVC4.0的一些比较简单的改变,主要是想对于MVC3.0来说的。因为这一些列主要是要给ASP.NET MVC初学者,或者还没有使用过MVC的ASP.NET开发者进行培训学习,当然也可以让我温习一下这种开发模式。所以本篇不得不讲解一下Razor的一些语法,以及在ASP.NET MVC开发中的一些技巧和开发方法。由于我在开发中不喜欢使用Entity Framework,所以这里我需要解释一下我认为的三层架构和MVC开发模式的应用。本人开发的三层架构中,数据库层和逻辑层基本不变,唯一改变的是UI层换成了MVC模式开发。当然,模型实例如果有需要会重新写,否则就会直接使用实体类进行替代,这只是我个人认识说不定是不正确的,希望各位大师能够多多指教。
首先我们来了解一下Razor的语法,在VS2010或者VS11中,添加一个试图就会让你选择使用Razor(cshtml)还是C#(ASPX)格式。Razor在语法上的美化是显而易见的,但是有时候会出现一些莫名其妙的错误,但是一般都可以得到解决,要么加HTML标签,要么是有“()”等等都可以得到解决,这个也许是在编写的Text Template对我们所写的文本解析有点问题而已。
在Razor中使用“@”来替代“&%%&”的编码格式,当然如果需要代码块,就需要用到“@{}”。在其中就可以编写C#代码,配合VS的只能解析,一般有过开发经验的人都可以很容易上手。如果你想了解更多的语法相关问题,可以参考,下面介绍一下在MVC中很重要的几个关键字,在编程过程中会经常使用到。
一、@model模型定义
&使用@model关键字可以定义一个Action里所对应的一个模型(经常可以叫他实体类),其实是对动态变量进行实例化,这样就可以直接在cshtml文件中调用“Model”变量。而这个模型的实例,需要通过Controller进行传输,如果没有则“Model”将为null。
&模型可以是一个实体类,也可以是一个列表实例,字典对象都可以进行定义,但是和Controller中的Action传回来的实例一定要一样,否则将会出现错误。例如我们获取用户实例,并且在页面上呈现用户的具体信息,这样就可以将用户实例返回给前台cshtml页面,具体代码如下。
&&1&///&&summary&
&2&&&&&&&&&///&获取用户信息。
&3&&&&&&&&&///&&/summary&
&4&&&&&&&&&///&&returns&返回行为结果。&/returns&
&5&&&&&&&&&public&ActionResult&UserInfo()
&6&&&&&&&&&{
&7&&&&&&&&&&&&&var&id&=&Convert.ToInt32(Request.QueryString["id"]&??&"0");
&8&&&&&&&&&&&&&var&user&=&Users.GetUser(id);
&9&&&&&&&&&&&&&return&View(user);
10&&&&&&&&&}
只要在cshtml页面上定义“@model User”这样这个页面的基本模型(Model)就是这个User类了,当然如果不为空的时候就可以直接调用了。&&二、@section节点关键字&这里首先需要了解一下布局页面,在ASP.NET MVC中约定,以“_”开头的文件在浏览器上面是不能访问的,而“Shared”文件夹是一个共享的文件夹,或者叫做通用文件夹。一般不可以定义一个SharedController,这个我没试过,有兴趣你可以试试。而“_viewstart.cshtml”里所指定的文件就是布局页面,相当于ASP.NET里的Master页面,这样讲应该会比较好了解。每一个布局页都必须调用一个方法“@RenderBody()”,而这个@section就有点像placeholder一样,所知名的块名称需要和布局页里面定义的名称一样。&&上面就可以很清楚的看到,其中required参数表示在子页面中是否一定要重写,一般不需要所以设置为false。如果是true表示所有布局页的字页面都必须要有这个节点重现的代码块,在子页面中调用可以从下面的图中看到。&&由于@section header设置了required:false,所以不重写没关系,忽略他。节点一般使用“{}”包裹,而下面部分没有指定的就是Body部分了,用好布局页可以减少很多代码,这个是值得推荐的。&三、@helper方法定义&使用@helper关键字可以定义一个方法,这样就可以在页面中调用这个方法了,和C#中的方法一样。在页面中定义的方法可以访问ViewBag,HttpContext等等页面的属性,返回的类型为“HelperResult”。其他的写法和普通的方法没有区别,主要用于列表等等需要重复写进行可重复调用。&这个关键字还可以在App_Code文件夹中定义很多个方法集,我最常用的就是定义分页,比如只需要传入记录数,每页显示的记录数,以及当前页码和URL格式化参数,就可以在页面中很简单的呈现分页内容。之所以推荐在App_Code这个文件夹中定义,是因为可以省略命名空间,文件名就是类名,而定义的方法就可以直接使用“FileName.MethodName”格式调用,即静态方法类。所以在这里定义的方法,不能够使用页面上面的ViewBag等等属性。&用好了以上三个关键字不仅对MVC有一个深刻的认识,也可以使得提高编码重用度。下面我再介绍一下ASP.NET MVC中文件夹结构和MVC中的对应关系,这个对于初学者来说是个很大的问题,因为我发现刚刚进行开发的人员找不到页面,找到页面又找不到控制器。借助VS11这种文件显示结构,会更好理解,如下图所示。&从上图就可以很好的理解,Models-Views-Controllers这就组成了MVC,在Models中一般定义一些模型实体,并且会添加一些验证,这些模型实体类供控制器Controllers中的方法调用。在Controllers中定义的类型和Views文件夹下的文件夹名称相对应,文件夹名加上“Controller”就是控制器名称,这是一种命名约定就像Attribute一样。而其中的方法当然对于的就是Views下文件夹下的文件名了,这些都是一一对应的。当然有些控制器返回的如果不是试图,可以不需要定义这些文件名,但是如果是返回试图,就会出现找不到cshtml页面的错误。&注:控制器的这种命名约定只是对于Internet Application,对于WebAPI这个就不一样了。&&昨天所写和今天所讲都是比较基础的,学习都需要通过循序渐进,这样才可以慢慢进入正题,我希望我所写的能够给他人带来一点收获。我没有整体规划一下写作的内容,经常都是想到什么写什么,所以可能会给初学者带来不好的感觉,敬请原谅。&
Views(...) Comments()

我要回帖

更多关于 asp.netweb教程推荐 的文章

 

随机推荐