asp.net webMVC OutputCache 不想把母版页的数据也缓存

Creating an ASP.NET MVC OutputCache ActionFilterAttribute
In every web application, there are situations where you want to cache the HTML output of a specific page for a certain amount of time, because underlying data and processing isn't really subject to changes a lot. This cached response is stored in the web server's memory and offers very fast responses because no additional processing is required.
Using "classic" ASP.NET, one can use the OutputCache directive on a .aspx page to tell the ASP.NET runtime to cache the response data for a specific amount of time. Optionally, caching may vary by parameter, which results in different cached responses depending on the parameters that were passed in the URL.
As an extra feature, one can also send some HTTP headers to the client and tell him to load the page from& the web browser's cache until a specific amount of time has passed. Big advantage of this is that your web server will receive less requests from clients because they simply use their own caching.
Using the ASP.NET MVC framework (preview 3, that is), output caching is still quite hard to do. Simply specifying the OutputCache directive in a view does not do the trick. Luckily, there's this thing called an ActionFilterAttribute, which lets you run code before and after a controller action executes. This ActionFilterAttribute class provides 4 extensibility points:
OnActionExecuting occurs just before the action method is called
OnActionExecuted occurs after the action method is called, but before the result is executed (before the view is rendered)
OnResultExecuting occurs just before the result is executed (before the view is rendered)
OnResultExecuted occurs after the result is executed (after the view is rendered)
Let's use this approach to create an OutputCache ActionFilterAttribute which allows you to decorate any controller and controller action, i.e.:
[OutputCache(Duration = 60, VaryByParam = "*", CachePolicy = CachePolicy.Server)] public ActionResult Index() { &&& // ... }
We'll be using an enumeration called CachePolicy to tell the OutputCache attribute how and where to cache:
public enum CachePolicy { &&& NoCache = 0, &&& Client = 1, &&& Server = 2, &&& ClientAndServer = 3 }
1. Implementing client-side caching
Actually, this one's really easy. Right before the view is rendered, we'll add some HTTP headers to the response stream. The web browser will receive these headers and respond to them by using the correct caching settings. If we pass in a duration of 60, the browser will cache this page for one minute.
public class OutputCache : ActionFilterAttribute { &&& public int Duration { } &&& public CachePolicy CachePolicy { }
&&& public override void OnActionExecuted(ActionExecutedContext filterContext) &&& { &&&&&&& // Client-side caching? &&&&&&& if (CachePolicy == CachePolicy.Client || CachePolicy == CachePolicy.ClientAndServer) &&&&&&& { &&&&&&&&&&& if (Duration &= 0)
&&&&&&&&&&& HttpCachePolicyBase cache = filterContext.HttpContext.Response.C &&&&&&&&&&& TimeSpan cacheDuration = TimeSpan.FromSeconds(Duration);
&&&&&&&&&&& cache.SetCacheability(HttpCacheability.Public); &&&&&&&&&&& cache.SetExpires(DateTime.Now.Add(cacheDuration)); &&&&&&&&&&& cache.SetMaxAge(cacheDuration); &&&&&&&&&&& cache.AppendCacheExtension("must-revalidate, proxy-revalidate"); &&&&&&& } &&& } }
2. Implementing server-side caching
Server-side caching is a little more difficult, because there's some "dirty" tricks to use. First of all, we'll have to prepare the HTTP response to be readable for our OutputCache system. To do this, we first save the current HTTP context in a class variable. Afterwards, we set up a new one which writes its data to a StringWriter that allows reading to occur:
existingContext = System.Web.HttpContext.C writer = new StringWriter(); HttpResponse response = new HttpResponse(writer); HttpContext context = new HttpContext(existingContext.Request, response) { &&& User = existingContext.User }; System.Web.HttpContext.Current =
Using this in a OnResultExecuting override, the code would look like this:
public override void OnResultExecuting(ResultExecutingContext filterContext) { &&& // Server-side caching? &&& if (CachePolicy == CachePolicy.Server || CachePolicy == CachePolicy.ClientAndServer) &&& { &&&&&&& // Fetch Cache instance &&&&&&& cache = filterContext.HttpContext.C
&&&&&&& // Fetch cached data &&&&&&& object cachedData = cache.Get(GenerateKey(filterContext)); &&&&&&& if (cachedData != null) &&&&&&& { &&&&&&&&&&& // Cache hit! Return cached data &&&&&&&&&&& cacheHit = &&&&&&&&&&& filterContext.HttpContext.Response.Write(cachedData); &&&&&&&&&&& filterContext.Cancel = &&&&&&& } &&&&&&& else &&&&&&& { &&&&&&&&&&& // Cache not hit. &&&&&&&&&&& // Replace the current context with a new context that writes to a string writer &&&&&&&&&&& existingContext = System.Web.HttpContext.C &&&&&&&&&&& writer = new StringWriter(); &&&&&&&&&&& HttpResponse response = new HttpResponse(writer); &&&&&&&&&&& HttpContext context = new HttpContext(existingContext.Request, response) &&&&&&&&&&& { &&&&&&&&&&&&&&& User = existingContext.User &&&&&&&&&&& };
&&&&&&&&&&&&// Copy all items in the context (especially done for session availability in the component) &&&&&&&&&&&&foreach (var key in existingContext.Items.Keys) &&&&&&&&&&&&{ &&&&&&&&&&&&&&&&context.Items[key] = existingContext.Items[key]; &&&&&&&&&&&&}
&&&&&&&&&&& System.Web.HttpContext.Current = &&&&&&& } &&& } }
By using this code, we can retrieve an existing item from cache and set up the HTTP response to be read from. But what about storing data in the cache? This will have to occur after the view has rendered:
public override void OnResultExecuted(ResultExecutedContext filterContext) { &&& // Server-side caching? &&& if (CachePolicy == CachePolicy.Server || CachePolicy == CachePolicy.ClientAndServer) &&& { &&&&&&& if (!cacheHit) &&&&&&& { &&&&&&&&&&& // Restore the old context &&&&&&&&&&& System.Web.HttpContext.Current = existingC
&&&&&&&&&&& // Return rendererd data &&&&&&&&&&& existingContext.Response.Write(writer.ToString());
&&&&&&&&&&& // Add data to cache &&&&&&&&&&& cache.Add( &&&&&&&&&&&&&&& GenerateKey(filterContext), &&&&&&&&&&&&&&& writer.ToString(), &&&&&&&&&&&&&&& null, &&&&&&&&&&&&&&& DateTime.Now.AddSeconds(Duration), &&&&&&&&&&&&&&& Cache.NoSlidingExpiration, &&&&&&&&&&&&&&& CacheItemPriority.Normal, &&&&&&&&&&&&&&&& null); &&&&&&& } &&& } }
Now you noticed I added a VaryByParam property to the OutputCache ActionFilterAttribute. When caching server-side, I can use this to vary cache storage by the parameters that are passed in. The GenerateKey method will actually generate a key depending on controller, action and the VaryByParam value:
private string GenerateKey(ControllerContext filterContext) { &&& StringBuilder cacheKey = new StringBuilder();
&&& // Controller + action &&& cacheKey.Append(filterContext.Controller.GetType().FullName); &&& if (filterContext.RouteData.Values.ContainsKey("action")) &&& { &&&&&&& cacheKey.Append("_"); &&&&&&& cacheKey.Append(filterContext.RouteData.Values["action"].ToString()); &&& }
&&& // Variation by parameters &&& List&string& varyByParam = VaryByParam.Split(';').ToList();
&&& if (!string.IsNullOrEmpty(VaryByParam)) &&& { &&&&&&& foreach (KeyValuePair&string, object& pair in filterContext.RouteData.Values) &&&&&&& { &&&&&&&&&&& if (VaryByParam == "*" || varyByParam.Contains(pair.Key)) &&&&&&&&&&& { &&&&&&&&&&&&&&& cacheKey.Append("_"); &&&&&&&&&&&&&&& cacheKey.Append(pair.Key); &&&&&&&&&&&&&&& cacheKey.Append("="); &&&&&&&&&&&&&&& cacheKey.Append(pair.Value.ToString()); &&&&&&&&&&& } &&&&&&& } &&& }
&&& return cacheKey.ToString(); }
There you go! Now note that you can add this OutputCache attribute to any controller and any controller action you& have in your application. The full source code is available for download here: &(full sample) or &(only attribute).
UPDATE: Make sure to read&part 2, available .
e2c671b6-b-bb18-45def|4.3|96d5b379-7e1d-4dac-a6ba-1e50db561b04
Related postsI&m very proud to announce the release of the ASP.NET MVC MvcSiteMapProvider 2.0! I&m al...As I stated in a previous blog post: ASP.NET MVC 3 preview 1 has been released! I talked about some ...In my previous blog post on ASP.NET MVC OutputCache, not all aspects of &classic& ASP.NET ...
Please enable JavaScript to view the
Maarten Balliauw works at . His interests are mainly web applications developed in ASP.NET (C#) or PHP and the Microsoft Azure cloud platform. Maarten also co-founded , hosting private NuGet, npm and Bower feeds for teams.
(11) (5) (4) (3) (2)
(5) (4) (4) (5) (3) (9) (4) (7) (2) (4) (4) (6)
(5) (4) (7) (5) (6) (3) (4) (2) (3) (4) (5) (12)
(9) (6) (5) (7) (7) (6) (13) (7) (4) (6) (6) (4)
(6) (6) (2) (4) (5) (2) (4) (3) (6) (6) (2) (1)
(6) (4) (4) (5) (8) (6) (6) (2) (4) (1) (4) (2)
(4) (1) (5) (1) (3) (5) (4) (3) (3) (3) (4)
(5) (3) (4) (1) (2) (4) (2) (2) (1) (1) (1)
(2) (1) (1) (1) (2) (2) (2) (1) (1) (2)
(1) (1) (1)
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.
& Maarten BalliauwAspNet MVC 缓存
时间: 14:32:54
&&&& 阅读:335
&&&& 评论:
&&&& 收藏:0
标签:&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&服务端缓存技术
请求域内的缓存
  每个Asp.Net请求都会在Asp.Net框架中创建一个新的System.Web.HttpContext对象(HttpContext对象封装有关个别
HTTP 请求的所有 HTTP
特定的信息)。在HttpContext对象的一个属性就是HttpContext.Items,这个属性也会存在于请求的整个周期,以HttpContext.Items为媒介可以解除各个组件之间的耦合。Items是一个IDictionary的类型可以直接通过HttpContext.Item["key"]=value的形式获取。Items可以用户获取Asp.Net请求过程中IHttpModule和IHttpHandler之间组织和共享数据的键值对。
用户域内的缓存
  用户域的缓存
也就是平常使用的HttpContext.Session,仅仅是当前用户的缓存,不能实现跨用户共享数据。Aspnet的会话状态可以再多个请求之间共享数据,记得这个只能是当前用户可以得到共享数据。会话状态空闲一段时间后会过期,当然可以通过Web.config的&system.web&节点下修改&seesionState
timeout="30" /&进行设置,当然还有其他参数可以进行设置。
应用程序域内的缓存
  平常使用的HttpContext.Application,<SPAN id="mt1" class="sentence SentenceHover"
data-source=‘Gets the
object for the current HTTP request.‘
data-guid="bc4af7dcf0e9a86f776ccfd02ed7849f">为当前 HTTP 请求获取
对象。那么就是HttpApplicationState管理这应用程序级别的数据。微软官方的解释:“”,一样也是一个键值对类型。存储在HttpApplicationState的数据生命空间域托管网站的IIS工作进程一样长,因为IIS不是Asp.NET管理着工作线程的生命周期。HttpApplicationState也是不是可靠地数据存储方式。
Asp.Net缓存
  平常比较经常用的HttpContext.Cache进行访问,与Application一样也是应用程序域的数据。Cache存储的数据不好限制在单个请求或者用户会话范围内。HttpContext.Cache与Application还是有区别的,Application可以扩工作进程的访问。HttpContext.Cache以HttpRuntime.Cache的实现。我们知道HttpContext是通过封装个别的Http请求信息所得到的只能应用于Web应用上,而HttpRuntime.Cache是获取当前应用程序的Cache对象,可以非web应用。
使用Cache对象的时候可以设置过期时间(有两种方式其一设置间隔时间,用于指定缓存数据在最后一次访问之后多长过期,其二指定固定时间设置失效。对于Cache添加数据的时候还有一个缓存依赖数据,我们可以通过指定依赖项,来决定其生命周期缓存依赖策略
依赖类型  
Aggregate(聚合)
提供多个依赖(通过System.Web.Caching.AggregateCache)。只有删除所有依赖项才能删除该缓存记录
Custom(自定义)   
缓存数据依赖一个继承自System.Web.Caching.Cache的自定义类,例如,可以创建一个web服务缓存依赖,当查询某个值时,就删除缓存数据
File(文件)  
缓存数据依赖某个外部的文件,删除文件就会删除该数据
Key(键) 
缓存数据依赖应用程序缓存里另外一个缓存数据(通过缓存的key关联),删除依赖的缓存数据就会删除该数据。
缓存数据依赖MicrosoftSQLServer某个表的数据变化,当表更新时,缓存数据就会删除。
  平常用于输出缓存主要是OutputCache属性,当使用属性缓存页面,用户访问到页面时,首先会查看服务器的是否有该页面的缓存,若有则直接获取显示出来,而不会执行数据操作生成页面。我们可以对属性进行参数的设置比如Duration可以设置缓存的时间等。具体可以查看微软的Msdn。具体的使用如下所示:
[OutputCache(Duration=60,VaryByParam="none"]
ActionResult Contact()
&&&&&ViewBag.Message=DateTime.Now.ToString();
&&&&&return
View()&&&&&
&这里列出OutputCacheAttribute定义的属性
CacheProfile
使用的输出缓存策略的名字
缓存内容的生命周期
是否启用缓存
缓存地址默认设置为Any,这以为这内容可以缓存到三个地方Web 服务器、任何代理服务器和用户浏览器。
NoStore  
是否启用Http Cache-Control
SqlDependency
缓存依赖的数据库和表名称
VaryByContentEncoding
都好分割的字符编码列表,用来区分输入缓存
VaryByCustom
自动以字符串用来区分输出缓存
VaryByHeader
都好分割的HTTP消息头,区分缓存
VaryByParam
通过分割的Post表单或者查询字符串来区分缓存,比如查看某个id下的页面的页面,可以设置该属性为"id"
甜圈圈缓存(donut caching)
甜圈圈缓存是指只是缓存页面的外围内容,允许部分内容动态变化;与之相反的是甜圈圈洞的缓存(donut hole caching)(也就是缓存内部部分内容,而
允许外围内容的更新)。可以通过调用HttpResponse中的一个WriteSubstitution()方法实现甜圈圈缓存。具体的使用如下所示:
delegate string CacheCallback(HttpContextBase context);
static object Substitution(this
HtmlHelper html, CacheCallback ccb)
&&&&&&html.ViewContext.HttpContext.Response.WriteSubstitution(
&&&&&&&&&&&&&c=&HttpUtility.HtmlEncode(
&&&&&&&&&&&&&&&&&&&&ccb(new
HttpContextWrapper(c)&&&&&
&&&&&&&&&&&&&));&&&&&
@Html.Substitution(context=&context.User.Identity.Name)
&当然也可以引入MvcDonutCachingNuGet包提供几种高级的缓存扩展方法,也提供了操作方法使用DonutOutputCacheAttribute标记属性。
&甜圈圈洞缓存
缓存只是页面中的一小部分,针对某些类别信息是不会变化可以进行缓存。具体的使用如下:
[ChildActionOnly]
[OutputCache(Duration=60)]
ActionResult CategoriesAction()
&&&&ViewBag.Categories=Model.GetCategories();
&&&&return
@foreach(var
ViewBag.Categories as
IEnumerable&Category&)
&&&&&&@Html.ActionLink(item.Name,"category","categories",new{categoryId=category.Id})
@Html.Action("CategoriesAction");
客户端缓存技术
&浏览器缓存
浏览器在本地的资源通过三个机制控制:新的(freshness
)验证(validation)和失效的(invalidation)这三者属于Http的一部分,并且定在Http消息头里。
新的允许应答消息直接使用,而不需要经过服务器检查,额可以同被服务器和客户端控制。例如Expires过期的消息头设置了资源过期的时间,而Cache-Control:maxage则停工的是应答消息需要经过多久才刷新。
验证:用来检查陈旧的缓存数据是否依赖有效。如果缓存的应答数据包含Last-Modified消息头,则缓存就可以使用If-Modified-Since消息头来检查内容是否更新过。也可以通过ETag进行更强的控制。
失效:通常是指另一个缓存请求的错误请求
AppCache缓存和本地缓存(Html5新特性)【暂不介绍】
&参考:Asp.Net Mvc 4 WEeb 编程
&标签:&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&& &&&&&&
&& && && &&&&
版权所有 鲁ICP备号-4
打开技术之扣,分享程序人生!ASP.NET MVC: OutputCache action filter - 推酷
ASP.NET MVC: OutputCache action filter
OutputCache action filter attribute is used to control the output cache of action method result. We can also apply this attribute at controller level, once we apply this attribute at controller level, all action method result will be cached. Once action result are cached any subsequent request will be served from cache instead of processing it again.
Attribute Usage:
Controller & method
Sample Code:
[OutputCache(Duration=60)]
public ActionResult About()
ViewBag.date = DateTime.Now.ToString();
return View();
In above example, action method result will be cached for 60 seconds. Right usage of OutputCache attribute can help us to boost ASP.NET MVC application performance.
Apart from Duration, we can cache action result based on following criteria.
CacheProfile
SqlDependency
VaryByContentEncoding
VaryByCustom
VaryByHeader
VaryByParam
post to read about other available action filters.
You can follow me on
for latest link and update on
已发表评论数()
&&登&&&陆&&
已收藏到推刊!
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见今天看啥 热点:
微冷的雨ASP.NET MVC之葵花宝典(MVC),asp.netmvc微冷的雨ASP.NET&MVC之葵花宝典
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&By:微冷的雨
第一章&ASP.NET&MVC的请求和处理机制.
&&&&在MVC中:
01.所有的请求都要归结到控制器(Controller)上.
02.约定优于配置
*:所有的控制器放到Controllers文件夹中
*:所有的视图放到Views文件夹对应的Controller类名的文件夹中
03.如何通过Session保存用户登录信息,以及通过Cookie记录用户名
Session和Cookie都属于系统对象
设置Cookie(jsp还是cshtml&cookie都不是内置对象)
HttpCookie&hcCookie&=&new&HttpCookie(Cookie的名称,&变量值);
&hcCookie.Expires&=&过期时间;
&Response.Cookies.Add(hcCookie);
读取Cookie
string&变量名&=&Request.Cookies[Cookie的名称].V
如何从一个Action跳转到另外一个Action&RedirectToAction(&action名称&,&Controller&)
04.GPR原则:用户先发一个get请求让客户看到登录界面,然后用户录入数据,通过表单的post提交方式提交.登录成功后要进行跳转
05.内嵌语法
&srcipt&runat="server"&&&&在aspx页面中定义方法
&ContentPlaceHolder
&第二章&&基于三层架构搭建MVC系统
&&&01.可选参数
&&Public&void&Test(string&name,int&age=20)
&&Var:隐式.类型推断&&第一个=不能给null值,必须给一个确定的值,这样才能推断出=左侧变量的类型
&&Dynamic:动态类型&&可以凭空的点出一个自身不存在方法,编译时不进行类型检查,在运行时会报错.
&&匿名.类中的属性是只读的.
&&Int?&num=5;
&&&&&Int&result=Num??0;
BLL&Model&和DAL
UI&BLL&和Model
&06.会搭建分区项目,会在Areas文件夹下,创建出自己的一套MVC
&&解析:路由的定义规则,URL规则
Routes.MapRoute(
&&&Name:&Default&,&
&&&Url:blogs/{Controller}/{action}/{id},
&&&Defaults:new{&Controller=&Home&,action=&Index&,id=&UrlParameter.Optional&},
&&&Constraints:new{&id=@&\d{4}&},
&&&Namespaces:new&String[]{&BookShop.Controllers&}
&&*****引入了RouteDebug工具,通过在App_Start文件中的RouteConfig类中,添加一行代码
,&//RouteDebug.RouteDebugger.RewriteRoutesForTesting(routes);
02.如何在Controller和View中共享数据
&&&方案二:5种
&&&&&&&ViewData
&&&&&&&&ViewBag
&&&&&&&TempData
上面三种的场景简单数据类型
&&&&&&&ViewData.Model&&4
&&&&&View(Model)&&&5
强类型的复杂类型需要传递model使用方式4和5
&&3.通过看MVC源码剖析了一下为什么ViewData这个容器可以实现从Controller到View的数据共享.
&解析:Controller&&&有一个Action&&&返回值类型ViewResult&继承自ViewResultBase
&&里面有ViewData,和一个ExecuteResult()&ExecuteResult()参数是一个控制器对象,更精彩的是在ExecuteResult()方法中new出一个视图上下文,并且在构造中携带了控制器对象,和ViewData数据.&&调用View.Render(viewContext)方法渲染视图,&&由于View是一个接口类型,WebFormVIew视图引擎是View的一个实现类,WebFormView重写的Render方法又调用了RenderVIewPage方法,
&00.自动绑定
&&&路由数据,URL数据,表单数据
&01.表单数据&URL数据以及路由数据都可以实现自动装配.如果是表单数据的简单类型要想实现自动装配,那么只需要保证表单元素的name名字必须和参数的名字相同.
&02.通过EF来完成应用程序和数据库之间的数据传递.
&&BookShopEnties:DBContext(EF5.0)
&&&EF4.0继承自ObjectContext
03.Business&Model&&ViewModel
&业务Model:10个字段
视图Model:3个字段
04.由于我们的验证标签直接打在生成的实体类的属性上可能造成验证特性标签的丢失(重新生成实体类)
&考虑一下如何解决???
&解析:助手类
[MetaDataType(typeof(UserViewModel))]
Public&partial&class&User
解析:在Edmx模型中,有一个名称为BookShopPlusEntities的类,这个类中会自动根据数据库中的表名生成一个DBSet&User&&&Users{}集合,然后在Controller中就可以通过db.Users.Add(entity)
&&.master不再有,推出了_Layout.cshtml
Bundle技术:牛X在可以将1000个css样式表文件合成一次
&&结论:如果您选取了Razor视图引擎,那么无论是否启用Layout视图,都要从_ViewStart.cshtml执行.
其实上前端校验还是交给了jquery-validate完成的.如果在页面中没有引入对应的js库,那么不会自动形成前端校验.
&script&src="~/Scripts/jquery-1.7.1.min.js"&&/script&
&&&&&script&src="~/Scripts/jquery.validate.min.js"&&/script&
&script&src="~/Scripts/jquery.validate.unobtrusive.min.js"&&/script&
Required();必填项
Compare()比较:确认密码
&&&&&StringLength();限定字符格式
&&&&&Range(这里课本上是错误的,不能通过它来验证日期范围)
&&&&&RegularExpression(@&^$&)
ModelState.IsValid:true,表明后台所有的实体校验均通过
&&如何将错误信息扔到ValidationSummary中
&&&ModelState.AddModelError(&和Index.chhtml中的表单元素name保持&,&用户名存在&)
补充远端校验:[Remote]&&System.web.MVC;
补充:通过隐式的ajax请求来实时校验用户名是否存在
核心就是每次产生校验的时候,调用Controller中的一个方法,只不过该方法返回的是
&扩展方法三要素:
&&静态类&&静态方法&&this关键字
&Controller中内容:
public&ActionResult&PageData(int?&pageSize,&int?&pageIndex)
&&&&&&&&&&&&pageSize&=&pageSize&??&2;
&&&&&&&&&&&&pageIndex&=&pageIndex&??&1;
&&&&&&&&&&&&ViewData["CurrentPage"]&=&pageIndex.V
&&&&&&&&&&&&ViewData["PageSize"]&=&pageSize.V
&&&&&&&&&&&&ViewData["TotalCount"]&=&db.Subjects.Count();
&&&&&&&&&&&&ViewData["PageNum"]&=&Math.Max((db.Subjects.Count()&+&pageSize.Value&-&1)&/&pageSize.Value,&1);
&&&&&&&&&&&&var&temp&=&db.Subjects
&&&&&&&&&&&&&&&&.OrderBy(c&=&&c.SubjectId)
&&&&&&&&&&&&&&&&.Skip&Subject&(pageSize.Value&*&(pageIndex.Value&-&1))
&&&&&&&&&&&&&&&&.Take&Subject&(pageSize.Value);
&&&&&&&&&&&&return&View("Index",temp);
View中生成页码条
&div&class="paginator"&
&&&&&&&&@Html.ShowPageNavigate((int)ViewData["CurrentPage"],(int)ViewData["PageSize"],(int)ViewData["TotalCount"])
&&&&&/div&
Day06次课程
01.日历控件引入
&&&&01.直接在项目中添加下发的calendar文件夹,然后依次引入
&script&src="~/Scripts/jquery-1.7.1.min.js"&&/script&
&link&href="~/calendar/Css/calendar.css"&rel="stylesheet"&/&
&script&src="~/calendar/dt.js"&&/script&
&&&&script&type="text/javascript"&
&&&&$(function&()&{
&&&&&&&&$("#tName").click(function&()&{
&&&&&&&&&&&&ShowCalendar(this);
&&&&&&&&});
02.可以手动修正dt.js文件,可以让日历控件同时显示日期和时间,要看业务场景,
如果只需要显示日期,那么可以将dt.js中第982行代码做一个修正,如下
function&ShowCalendar(txt)&{
&&&&displayCalendar(txt,&'yyyy-mm-dd&hh:ii',&txt,true);
&&&&同时显示日期和时间,如果仅仅显示日期,配置如下:
function&ShowCalendar(txt)&{
&&&&displayCalendar(txt&08:00,&'yyyy-mm-dd',&txt,false);
02.文件上传
&步骤:01.构造上传文件的表单
&&@using(Html.BeginForm("Upload",&"FileTest",&FormMethod.Post,&new&{&enctype&=&"multipart/form-data"&}))
&&&&&&&&&&&{
&&&&&&&&&&&&
&&&&&&&&&&&&&input&type="file"&name="file"&/&
&&&&&&&&&&&&&input&type="submit"&name="upload"&value="提交"&/&
&&&&&&&&}&
02.在控制器中进行文件上传代码的处理
&public&ActionResult&Upload()&
&&&&&&&&&&&&return&View();
&&&&&&&&[HttpPost]
&&&&&&&&public&ActionResult&Upload(HttpPostedFileBase&file)
&&&&&&&&&&&&if&(file!=null)//证明用户选择了一个文件
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&//在服务器上找一个文件夹来保存用户上传的文件
&&&&&&&&&&&&&&&string&path=&Server.MapPath("~/files/"&+&file.FileName);
&&&&&&&&&&&&&&&&//就是将客户端用户上传的文件保存到该目录中.
&&&&&&&&&&&&&&&file.SaveAs(path);
&&&&&&&&&&&&&&&return&RedirectToAction("Index");
&&&&&&&&&&&&}
&&&&&&&&&&&&return&View();
5.通过jquery-ui进行文件上传
&&步骤1:01.构造上传文件的表单
&&@using(Html.BeginForm("Upload",&"FileTest",&FormMethod.Post,&new&{&enctype&=&"multipart/form-data"&}))
&&&&&&&&&&&{
&&&&&&&&&&&&
&&&&&&&&&&&&&input&type="file"&name="file"&/&
&&&&&&&&&&&&&input&type="submit"&name="upload"&value="提交"&/&
&&&&&&&&}&
&&&&*步骤一补充:在视图文件中,引入3个文件,顺序不能变&
&&&&01.jquery文件
02.jquery-ui的样式文件
03.jquery-ui.js插件
&!--引入Jquery文件--&
&script&src="~/Scripts/jquery-1.7.1.js"&&/script&
&!--引入Jquery-ui-css文件--&
&link&href="~/Content/themes/base/jquery.ui.all.css"&rel="stylesheet"&/&
&!--引入Jquery-ui文件--&
&script&src="~/Scripts/jquery-ui-1.8.20.js"&&/script&
04.要将Views文件夹下的_Layout.cshtml文件中的&@*&&@Scripts.Render("~/bundles/jquery")*@
注释,否则在Chrome中监视的时候,会发现以后一个错误,就是找不到jquery-ui插件的
dialog方法。
&&&步骤2:&*02.&在视图中用一个div将表单包裹起来,并且在div外定义一个a标签。达到的效果
&&&就是默认情况下div隐藏的,只有a标签显示。起到作用的就是autoOpen属性。设置为false,就是
&&&默认隐藏div。
&&&&&script&type="text/javascript"&
&&&&$(function&()&{
&&&&&&&&$("#dialog").dialog({
&&&&&&&&&&&&autoOpen:&false,
&&&&&&&&&&&&show:&"blind",
&&&&&&&&&&&&hide:"explode"
&&&&&&&&})
&&&&&&&&//写在此处的代码已经完成了当前页面中所有标签都加载(不包含图片和css),
&&&&&&&&//但是和Window.onload方法不同,保证所有的标签和图片都加载完成后再执行
&&&&&&&&$("#myupload").click(function&()&{
&&&&&&&&&&&&$("#dialog").dialog("open");
&&&&&&&&&&&&//原来a标签起到一个链接到另外一个目标页面的作用,通过return&false可以取消标签的默认行为
&&&&&&&&&&&&return&
&&&&&&&&})
&&&&div&id="dialog"&title="文件上传"&
&&&&&&@using&(Html.BeginForm("Upload",&"File",&FormMethod.Post,&new&{&enctype&=&"multipart/form-data"&}))
&&&&&&&&&&&{
&&&&&&&&&input&type="file"&name="file"&id="file1"&/&
&&&&&&&&&input&type="submit"&name="upload"&value="提交"&/&
&a&href="#"&id="myupload"&文件上传&/a&
03.&富文本编辑器
补充下拉框双向绑定
04.综合案例
1.EF体系结构
&&&01.ORM的优势
方便移植数据库
&&&02.流行的ORM框架
&&&03..NET&世界的ORM框架
NHibernate&
MyBatis.NET
LINQ&to&SQL
ADO.NET&Entity&Framework
&&&&04.在EF中,对数据对象的操作,实际是在操作EDM。在EDM抽象化的结构之下,&
则是概念层(CSDL)、存储层(SSDL)和对应层(MSL)
&&&CSDL定义了EDM的灵魂部分---概念模型。概念模型对应的是实体类,用实体类
&&&表示数据库中的对象。
&&&SSDL负责与数据库管理系统中的数据表做实体对应,描述了表、列、关系、主键
&&&及索引等数据库中存在的概念。
&&&05.关于Object&Services:
&&&&from&c&in&db.Student
where&c.id&0
&&&&参见msdn:/en-us/library/bb386871.aspx
&&&&&Object&Services&is&a&component&of&the&Entity&Framework&that&enables&you&to&query,
&insert,&update,&and&delete&data,&expressed&as&strongly&typed&CLR&objects&
&that&are&instances&of&entity&types.&Object&Services&supports&both&
&Language-Integrated&Query&(LINQ)&and&Entity&SQL&queries&against&types
&that&are&defined&in&the&conceptual&model.&Object&Services&materializes(成为现实)
&returned&data&as&objects,&and&propagates(传递)&object&changes&back&to&
&the&data&source.&It&also&
&&&1.T4模板下载地址
/t4-editor/download.html
DbSet&表示上下文中给定类型的所有实体的集合或可从数据库中查询的给定类型的所有实体的集合。
&可以使用&DbContext.Set&方法从&DbContext&中创建&DbSet&对象。
&2。延迟加载的本质
&&是IQueryable接口成就了延迟加载
&&解析:通过扩展IQueryable接口类型,在Queryable类中定义了一个名称为Where的扩展方法。
&&最本质的是通过DbQuery子类来进行延迟加载的。
&3.延迟加载的目的不是为了延迟使用数据,而是为了延迟生成SQL语句,满足业务需求。
&4.查询出来的对象都是以包装类的形式存在的。
&5.Conceptual&schema&definition&language&(CSDL)&
概念架构定义语言&(CSDL)&支持一组抽象基元数据类型(称为&EDMSimpleTypes),
这些类型在概念模型中定义属性。
Store&schema&definition&language&(SSDL)&is&an&XML-based&language
&that&describes&the&storage&model&of&an&Entity&Framework&application.
/zh-cn/library/cc982042.aspx
Mapping&specification&language&(MSL)&is&an&XML-based&language&
that&describes&the&mapping&between&the&conceptual&model&and&
storage&model&of&an&Entity&Framework&application.
In&an&Entity&Framework&application,&mapping&metadata&is&loaded&from
&an&.msl&file&(written&in&MSL)&at&build&time.&
&The&Entity&Framework&uses&mapping&metadata&at&runtime
&to&translate&queries&against&the&conceptual&model&to&store-specific&commands.
The&Entity&Framework&Designer&(EF&Designer)&stores&mapping&information&
in&an&.edmx&file&at&design&time.&At&build&time,&the&Entity&Designer
&uses&information&in&an&.edmx&file&to&create&the&.msl&file&
&that&is&needed&by&the&Entity&Framework&at&runtime
&Names&of&all&conceptual&or&storage&model&types&that&are&referenced&in&MSL
&must&be&qualified&by&their&respective&namespace&names.&
&For&information&about&the&conceptual&model&namespace&name,&
&see&CSDL&Specification.&For&information&about&the&storage&model&namespace&name,
&see&SSDL&Specification.&provides&facilities(工具)&for&tracking(路线)&changes,
&binding&objects&to&controls,&and&handling&concurrency(并发性).
&Object&Services&is&implemented&by&classes&in&the&System.Data.Objects
&and&System.Data.Objects.DataClasses&namespaces.
&&&&Object&Context
The&ObjectContext&class&is&the&primary&class&for&interacting&with&data&in&the&form&of&objects&that&are&instances&of&entity&types&that&are&defined&in&a&conceptual&model.&An&instance&of&the&ObjectContext&class&encapsulates(囊括)&the&following:
A&connection&to&the&database,&in&the&form&of&an&EntityConnection&object.
Metadata&that&describes&the&model,&in&the&form&of&a&MetadataWorkspace&object.
An&ObjectStateManager&object&that&tracks&objects&during&create,&update,&and&delete&operations.
&&&06.白话理解Object&Services&&,Entity&Client&&,ADO.NET&Provider&和EDM&MetaData(CSDL,MSL和SSDL)
&&&&Object&Services:就相当于封装增删改查的高级类。例如调用AddObject就可以实现新增操作。
&&&&Entity&Client:相当于ADO.NET中的SqlClient&&Connection,Command
&&&&ADO.NET&Provider:相当于数据库的驱动程序
&&&EDM&MetaData(CSDL,MSL和SSDL):XML文档,映射程序中对象和表中对象关系
&&&07.IQueryable接口继承自IEnumerable接口
&&&下次课程:
&&&&&&01.模型绑定特性
&&&&&&02.定制视图模板
&&03.Razor视图引擎&@
&&&&&***重点一:webform&:aspx
&&%&using&(Html.BeginForm())&{&%&
Razor&:cshtml
@using&(Html.BeginForm("提交到的action","提交的Controller",FormMethod.Post))&{
&&&//仅仅进行内存级别的操作,并不将结果打印到页面上
***重点二:母版页的概念存在于webform视图引擎下,在Razor视图引擎下,
没有母版页,只有布局页面(视图),_Layout.cshtml
ViewStart.cshtml&&:视图在渲染的时候第一个执行的页面。
LogIn.cshtml:
_Layout.cshtml:对页面的&html&&title&以及样式和js都做了设置。
并且预留了子页面需要填补的内容RenderBody()
***重点三:http协议
关于HTTP协议:之前的http协议版本是1.0,短连接。也即是当客户端
向服务器发出一个请求后,服务器返回给客户端响应后,连接立即断开,
后来出现了长连接,也就是现在通用的1.1,将间隔时间很短的多次请求
合并,这样提升网站的性能。
&&&&&&&&***重点四:状态码
&& & 状态码:
200:OK&,服务器已经正确做出响应。
302:暂时重定向。
303:永久重定向
304:&Not&Modified(未修改)客户的缓存资源是最新的,&要客户端使用缓存
404:404&Not&Found&未找到资源
500:服务器内部错误!
&&&&***重点五:压缩文件技术:Bundle技术:
问题:请求一个页面Index,页面上引用了10个外部CSS,需要发几次请求?
解析:发送11次请求,请求页面的文本一次请求。请求10个CSS需要10次请求。所以
总共是11次请求。
手动配置自己的Bundle。
&//自己的css压缩名称
&&&&&&&&&&&&bundles.Add(new&StyleBundle("~/Content/mine").Include("~/Content/mycolor.css","~/Content/myfont.css"));
&&&&***重点六:ModelState:
功能一:是拦截程序跨过验证的一种有效手段
--ASP.NET&Page.IsValid
--ASP.NET MVC ModelState.IsValid:本质上可以对应用的前后台同时进行验证。
哪怕前端禁用了js,也无法跨过后台我们给对应标签设置的特性。
功能二:当action中某个分支语句有错误,需要从Controller传递到View视图的时候,
我们可以使用ModelState.AddModelError("key","错误信息字符串")
&&&&&&&&&&&&&&&&ModelState.AddModelError("key&,Exception对象)
在前台VIew中有一个ValidationSummary(true);
第九章&&EF高级应用
&&&01.如何从委托进化到Lambda
&&&&&委托&
&&&&&匿名函数
&&&&&&Lambda
&&&&&&&&&&1.LINQ
&&LINQ(Language&Integrated&Query)语言集成查询
&&LINQ&to&E主流,后台可以是任意数据库。
&&EF这个ORM矿建性能比较优良。!@
&&LINQ&to&Objects:(string,数组和集合)
&&Linq&to&xml
&&Linq&to&SQL:后台数据库只能是SQL&server数据库,微软停止更新
&&01.查询&北京大学出版社&
&最早出版的3本书籍
&&var&query=&(from&c&in&Books
where&c.Publisher.Name.Equals("北京大学出版社")
orderby&c.PublishDate&descending&
select&c.Title).Take(3)
&编译后,和如下SQL语句等价
&select&top&&3&*&from&books,publishers
&where&books.publiserid=publishers.id
&and&publisers.name='北京大学出版社'
&order&by&publisherdate
查询分类为&C#&&、2003
年前出版的书籍,
&包括书名、出版社名称&&
from&c&in&Books
where&c.Category.Name.Equals("C#")&&&&
c.PublishDate&Convert.ToDateTime("")
select&new&{c.Title,c.Publisher.Name}&
03.查询出版书籍超过100本的出版社名称
&var&list&=&from&c&in&db.Publishers
&&&&&&&&&&&&&&&&&&&&&&&where&c.Books.Count&&&100
&&&&&&&&&&&&&&&&&&&&&&&select&c.N
重点:所有LINQ查询语句都可转换成查询方法
&&&&&&有的查询方法不能用LINQ查询表达式表示
3.FirstOrDefault()和SingleOrDefault()区别
&解析:这里以First、FirstOrDefault进行说明,其他类似。&
1、First:取序列中满足条件的第一个元素,如果没有元素满足条件,则抛出异常&
2、FirstOrDefault:取序列中满足条件的第一个元素,如果没有元素满足条件,
则返回默认值(对于可以为null的对象,默认值为null,对于不能为null的对象,
如int,默认值为0)&
&&区别:First,返回序列中的第一条记录,如果没有记录,则引发异常
&&FirstOrDefault,返回序列中的第一条记录,如果序列中不包含任何记录,则返回默认值。
&&Single,返回序列中的唯一一条记录,如果没有或返回多条,则引发异常。
&&SingleOrDefault,返回序列中的唯一一条记录,如果序列中不包含任何记录,则返回默认值,如果返回多条,则引发异常。
4.从LINQ&to&Objects到LINQ&to&Entities
&&&解析:查询语法上LINQ&to&Objects是一致的。但是他们在执行上却存在本质的区别。Objects始终是一个CLR对象,LINQ&to&Objects始终
是在CLR中进行的运算和操作;而LINQ&to&Entities虽然在编码上操作集合对象,但最终会被框架转换为对具体数据库表的操作。简单的说,
在LINQ&to&Entities中,查询表达式最终会被转化成相应的SQL语句。在这个转化过程中,from,where,order&by,select等部分会相应地
转化成SQL子句,用到的函数会转换成相应的SQL函数或运算符,如StartsWith("张"),在SQL&Server数据库中会转换成Like&N'张%'
5.查询多表数据
&&方式一:使用导航属性
&&方式二:join连接查询
&&方式三:嵌套查询子查询
6.上机练习一(获取好友分组信息)
&&&(1)当前用户的所有分组信息
&&&&&from&c&in&PrivateGroups
&&&&where&c.OwnerId==6
&&&&select&c
&&PrivateGroups
&&&.Where&(c&=&&(c.OwnerId&==&6))
&&(2)当前用户的未分组好友总个数
&&&&&(from&c&in&FriendRelations
&&&&&where&c.UserId==6&&&&c.GroupId.HasValue==false
&&&select&c).Count()
&&&FriendRelations
&&&.Where&(c&=&&((c.UserId&==&6)&&&&(c.GroupId.HasValue&==&&&&false))).Count()
&&&(3)当前用户的好友总个数
&&&(from&c&in&FriendRelations
&&&&where&c.UserId==1
&&&&select&c).Count()
&&FriendRelations
&&&.Where&(c&=&&(c.UserId&==&1)).Count()
上机练习二(获取分组下的好友)
01.分组编号对应的分组信息
(from&c&in&PrivateGroups
where&c.GroupId==4
PrivateGroups
&&&.Where&(c&=&&(c.GroupId&==&4))
02.分组编号下的所有好友信息
from&c&in&FriendRelations
where&c.UserId==6
&&&c.GroupId==20
&&FriendRelations
&&&.Where&(c&=&&((c.UserId&==&6)&&&&(c.GroupId&==&(Int32?)20)))
上机练习3(按组合条件搜索好友)
实现动作方法,按姓名、性别、城市和家乡组合条件搜索青鸟朋友网所有用户,要求
获取到姓名、编号、是否和当前用户是好友关系、所属分组等信息
,支持分页查询
第十章&Ajax
1.无刷新删除分组信息数据
&核心:01.先通过EF给用户展现出一个列表页面
&&&&&&02.修改对应的View使用,将原有的超链接
&&&&&&改成一个&img&标签,并且img标签设置两个属性,
&&&&&&如下&img&src=""&class="del"&delid="@item.GroupId"&
&&&&&&03.通过$.post(请求的目标页面,{id:id},回调函数function(data){
&&&&&&04.db.PrivateGroup.Where().SingleOrDefault();
2.根据分组编号获取当前登录用户某个分组下所有的好友信息以及
未分组信息(PartialView实现)
&实现步骤:01.我们都知道,MVC模式最终把所有的请求都归结到到控制的
&某个Action上.这里我们点击页面左侧的一个table中某一个分组的名称时,
&需要在右侧的div中展示该分组下的所有好友名称.
&&&&&&&&&&02.首先,在HomeController中书写一个GetFriendsByGroupId(int?&id)
&&&&&&&&&&返回的视图类型不再是View(),而变成了PartialView().
&&&&&&&&&&03.再Index页面中,将分组名称从原来的默认形式设置成一个无刷新
&&&&&&&&&&超链接,@Ajax.ActionLink("热点文字","Action名称","Controller名称",
&&&&&&&&&&路由参数(new{id=@item.GroupId},new&AjaxOptions(){
&&&&&&&&&&&&OnScuccess="服务器执行成功后要执行的Js函数",
&&&&&&&&&&&&HttpMethod="请求提交方式",
&&&&&&&&&&&&Confirm="提示是否进行操作的对话框",
&&&&&&&&&&&&UpdateTargetId="要更新的目标区域的id",
&&&&&&&&&&&&LoadingElementId="当网速慢的时候,或者并发量大的时候,用户
&&&&&&&&&&&&看到的正在加载./...图片效果.",
&&&&&&&&&&}))
&&&&&&&&&&
&&&&&&&&&&LoadingElementId参数注意事项:设定的显示图片加载的标签如下:
&&&&&&&&&&div&id="load"&
&&&&&&&&&&&&&img&src="~/images/01.jpg"/&
&&&&&&&&&&/div&
&&&&&&&&&&01.先在样式表中让id="load"的div隐藏
&&&&&&&&&&display:&&&
&&&&&&&&&&02.当图标在指定的时间内将数据加载完成后,会自动将div再次自动隐藏.&&&&&&&&&
&&&&&&&&&&
&&&&&&&&&&
&&&&&&&&&&最后一项目:目标区域的代码
&&&&&&&&&&&div&id="mytarget"&
&&&&&&&&&&&&&//如何调用分布视图
&&&&&&&&&&&&&@Html.Partial("分布视图的名称",model数据)
&&&&&&&&&&&/div&
&&&&&&&&&&
&&&&&&&&&&
&&&&&&&&&&如何加载未分组数据呢?
&&&&&&&&&&解析:其实上就是在table最后一个tr后面手动构造一个tr对象.
&&&&&&&&&&并且也使用无刷新超链接来进行分组名称的显示.其他内容同上.
3.Json实现某个分组下的好友信息
核心01:什么是Json?
解析:JSON(JavaScript&Object&Notation)&是一种轻量级的数据交换格式。
它相对于xml格式解析起来更加简便,比Serialize序列化的数据有更好的
核心02.JSON&名称/值对(hash&&,字典)
解析:JSON&数据的书写格式是:名称/值对。
名称/值对组合中的名称写在前面(在双引号中),值对写在后面(同样在双引号中),中间用冒号隔开:
例如:"firstName":"John"
核心03.JSON&值
JSON&值可以是:
数字(整数或浮点数)
字符串(在双引号中)
逻辑值(true&或&false)
数组(在方括号中)
对象(在花括号中)
核心04.Json的各种形式
最简单的形式:{"name":"张靓颖"}&
如果想让服务器打给浏览器Json数据,&那么返回类型要写成Json(携带数据,JsonRequestBehavior.AllowGet)
在使用Json方法的过程中,会出现循环引用的异常信息,我们可以通过
db.Configuration.ProxyCreationEnabled=false解决,或者是通过
db.Configuration.LazyLoadingEnabled=false解决,微软官方解决可以通过
blog上的方案,原理是重写了Json方法的执行流程.
[{"UserId":5,"Mail":"","RealName":"唐燕",
"Password":"123456","Gender":"女","Birthday":"\/Date()\/","City":null,"HomeCity":null,"Situation":"教员","HeaderImage":"5.jpg","BloodStyle":null,"RegisterTime":"\/Date(0)\/","GenderPrivate":0,"BirthdayPrivate":0,"CityPrivate":0,"HomeCityPrivate":0,"SituationPrivate":0,"BloodStylePrivate":0,"InitialPrize":2345,"FriendRelation":[],"GroupFriend":[],"EntityState":2,"EntityKey":{"EntitySetName":"UserInfo","EntityContainerName":"FriendsEntities1","EntityKeyValues":[{"Key":"UserId","Value":5}],"IsTemporary":false}}]
解析服务器打到浏览器上的Json格式数据
$.each(data,&function&(i,&object)&{
&&&&&&&&&&&&$("#FriendList").text("");
&&&&&&&&&&&&$("#FriendList").append(
&&&&&&&&&&&&&&&&"&div&"&+&object.RealName&+&"&/div&"&+&"&br/&");
&&&&&&&&});
注意点:当我们从GetFriendByGroupId转型成GetFriendByGroupIdJson的时候,一定
要注意AjaxOptions中不能再有UpdateTargetId的值.因为在OnSuccess中已经
指定了要更新的区域信息.
第11章&&Forms身份校验&&&过滤器()&&&&缓存&&&错误页
关于Session的配置
什么是进程内Session
解析:淘宝登陆:StateServer:
&sessionState&mode="InProc"&customProvider="DefaultSessionProvider"&timeout="20"&
&&&&&&&providers&
&&&&&&&&&add&name="DefaultSessionProvider"&type="System.Web.Providers.DefaultSessionStateProvider,&System.Web.Providers,&Version=1.0.0.0,&Culture=neutral,&PublicKeyToken=31bf"&connectionStringName="DefaultConnection"&/&
&&&&&&&/providers&
&/sessionState&
1.Forms验证方式
配置步骤:
&01.在程序的web.config文件中,
配置如下节点
&authentication&mode="Forms"&
&&&&&&&forms&loginUrl="~/Account/Login"&timeout="2880"&/&--注意这里超时的单位为分钟
&/authentication&
&02.登陆成功后向用户发放身份票据
&&&通过用户名和密码判定
&&FormsAuthentication.SetAuthCookie(user.UserId.ToString(),false);
&03.获取身份票据进行验证
&&if&(this.User.Identity.IsAuthenticated)
&&&//验证通过
&&&&&&&//获取写入的userName
&&&&&&&&int&userId&=&Convert.ToInt32(&this.User.Identity.Name&);
&&&&&&&&//具备权限后的操作代码...
&&Win7下Cookie的位置
C:\Users\Administrator\AppData\Local\Microsoft\Windows\Temporary&Internet&Files&&
&&Authorize&特性-方便的实现授权
&&其实Authorize内部也是通过03的步骤实现的
&Authorize过滤器
&&AOP+面向接口编程
&&service&&service.impl
&&dao&&&dao.impl
&&过滤器的本质:本质就是一个实现了特定接口或者是父类的特殊类。
&&咱们自定义的过滤器必须满足两个条件:01.继承FilterAttribute抽象类
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&02.必须实现四个接口中的任何一个。
&&&在ASP.NET&MVC中,过滤器就是一个继承自FilterAttribute的类,并且实现了
IActionFilter、IResultFilter、IException或者是IAuthorizationFilter接口
中的任何一个接口。
&&&两个Demo:如何记录网站的错误日志(不能记录404错误)。
&&&&&&&&&&&&&如何记录网站的访问日志(浏览器,IP)&。
&&&在FilterConfig文件中,注册全局过滤器。
&&&注意FilterAttribute命名空间为mvc下
&public&class&MYExceptionFilter:FilterAttribute,IExceptionFilter
&&&&&&&&public&void&OnException(ExceptionContext&filterContext)
&&&&&&&&&&&&//记录错误日志
&&&&&&&&&&&&//01.得讲错误日志记录到当前项目的某个文件中(erroglog.txt)
&&&&&&&&&&&&//02.在服务器上指定该文件的位置
&&&&&&&&&&&&string&realpath=filterContext.HttpContext.Server.MapPath(@"~\errorlog.txt");
&&&&&&&&&&&&//03.通过IO流的方式写入错误信息
&&&&&&&&&&&&using&(StreamWriter&sw&=&File.AppendText(realpath))
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&sw.WriteLine("时间:{0}",DateTime.Now);
&&&&&&&&&&&&&&&&sw.WriteLine("ip地址:{0}",filterContext.HttpContext.Request.UserHostAddress);
&&&&&&&&&&&&&&&&sw.WriteLine("控制器:{0}",filterContext.RouteData.Values["Controller"]);
&&&&&&&&&&&&&&&&sw.WriteLine("动作方法:{0}",filterContext.RouteData.Values["Action"]);
&&&&&&&&&&&&&&&&sw.WriteLine("错误信息:{0}",filterContext.Exception.StackTrace);
&&&&&&&&&&&&&&&&sw.WriteLine("**********************************************************");
&&&&&&&&&&&&}
&&&&&&public&class&SystemOperationListFilter:FilterAttribute,IActionFilter,IResultFilter{
&&&&&&&&public&void&OnActionExecuted(ActionExecutedContext&filterContext)
&&&&&&&&&&&&//当action执行完后执行该方法
&&&&&&&&&&&&string&realpath&=&filterContext.HttpContext.Server.MapPath(@"~\pageList.txt");
&&&&&&&&&&&&//写入IO流
&&&&&&&&&&&&using&(StreamWriter&sw=File.AppendText(realpath))
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&sw.WriteLine("时间:{0}",DateTime.Now);
&&&&&&&&&&&&&&&&sw.WriteLine("地址:{0}",filterContext.HttpContext.Request.Url);
&&&&&&&&&&&&&&&&sw.WriteLine("浏览器引擎:{0}",&filterContext.HttpContext.Request.UserAgent);
&&&&&&&&&&&&&&&&sw.WriteLine("计算机名:{0}",filterContext.HttpContext.Request.UserHostName);
&&&&&&&&&&&&}
&&&&&自定义过滤器特性可以打在三个地方
&&&&&01.Action
&&&&&02.控制器
&&&&&03.路由中配置
&&&&第三方,api
&&&&咱们自己的接口
&&&&我们现在努力的学习英文,就是为了有一天所有外国人都学习中文。考试&
&&&&&IActionFilter,IResultFilter,IExceptionFilter,IAuthorizeFilter
3.谈一下设计模式(常见的总共有23种设计模式)&AOP&IOC
&&单例模式
&&简单工厂模式(不属于)&
&&工厂模式
&&抽象工厂
&&门面模式
&&适配器模式:可以使系统本来存在的两个毫不相干的类型可以协同工作。
&&GOF(设计模式的权威书籍)
&&大话设计模式
&&设计模式之禅(Java)
&&AOP(面向切面编程)
&&面向切面(AOP)编程,Adapter适配器模式
********************************************06.缓存********************************************
使用缓存的目的就是加快对某种资源的访问。
并发量比较大的时候:分布式
&&&&&&&&&&&&&本质:SOA+集群
&&&&作用:缓存是一把双刃剑,优点:加快网站的访问速度。因为缓存的数据存在于
&应用服务器的内存中,当缓存对象形成后,第二次访问的时候,不需要再从数据库
&中将数据取到APP服务器上&。这样速度自然块。
&&&缺点:01.占用了服务器的内存,服务器内存是很稀缺的资源。如果对页面的大量数据
&&&启用缓存,那么可能造成服务器崩溃。
&&&&&&&&&&02.有一些网站不适合使用缓存技术,&例如股票,天气等需要实时更新数据的
&&&&&&&&&&网站,如果启用缓存,可能造成网站的数据有延迟不准确。
&&&&&&&&&&哪些网站适合缓存,比如当当网首页???
&&&&&&&&&缓存分两种:
&&&&01.对集合的缓存
&&&&02.对整个页面的缓存
&&&&&&&&&&缓存一般有两种方式,如果我们需要进行更细粒度的控制,比如控制缓存数据(
&&例如,某个泛型集合,可以使用通过在Controller中定义一个属性来设置缓存数据。
&&&可以通过如下方式,设置缓存。HttpContext.Cache["key"]=值;
&&&上述方式无法进行缓存过期设置,所以我们引入了Add方法和Insert()方法。
&&&Insert方法中可以设置缓存过期时间,真实开发中,一般使用绝对过期时间。
&&&用法如下:
&&&&&HttpContext.Cache.Insert(CACHEDUSERS,&items,&null,System.Web.Caching.Cache.NoAbsoluteExpiration,TimeSpan.FromSeconds(10));
&&&HttpContext.Cache.Insert(CACHEDUSERS,&items,&null,&DateTime.Now.AddSeconds(15),System.Web.Caching.Cache.NoSlidingExpiration);
&&&参数一:key
&&&参数二;value
&&&参数三:缓存依赖,没有为null
&&&参数四:过期时间
&&&参数五:设置是绝对过去还是滑动过期。取值:如果是NoSlidingExpiration,证明是绝对过期,如果是
&&&NoAbsoluteExpiration&:滑动过期时间
//缓存登陆数据
&&&&&&&&public&const&string&CHACHEDUSERS&=&"FriendsUsers";
&&&&&&&&public&List&User&&UserList
&&&&&&&&&&&&get&
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&List&User&&list=&HttpContext.Cache[CHACHEDUSERS]&as&List&User&;
&&&&&&&&&&&&&&&if&(list==null)
&&&&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&&&&list&=&db.Users.ToList();
&&&&&&&&&&&&&&&&&&&HttpContext.Cache.Insert(CHACHEDUSERS,&list,&null,&System.Web.Caching.Cache.NoAbsoluteExpiration,&TimeSpan.FromSeconds(10));
&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&return&
&&&&&&&&&&&&}
&&&&&&&&&&&
&&缓存页面:
[OutputCache(Duration=15)] 设置的也是绝对过期时间&&
&&绝对过期时间和滑动过期时间:
&&刚才我们设置了15s后过期,那么从用户第一次开始访问,往后数15秒,
&&就会在15s之后过期
&&滑动过期时间:从用户最后一次访问页面的时间开始往后推15s。
&&08.Forms进行网站验证
&&09.安全相关
&&10.过滤器
&&&&在ASP.NET&MVC中,过滤器就是一个继承自FilterAttribute的类,或者实现了
IActionFilter、IResultFilter、IException或者是IAuthorizationFilter。
&&11.单元测试
****************************************错误页定制************************************************
&&&12.错误页定制
&&第一种方式:
&&步骤一:就是在网站的web.config配置文件中,找到
&&&system.web&节点,在该节点中添加如下代码。
&&&customErrors&defaultRedirect="~/ErrorPage.htm"&mode="On"&
&&&&&&&&&&&error&statusCode="404"&redirect="~/FileNotFound.htm"/&
&&&&&&&/customErrors&
&&步骤二:在网站的根目录下创建对应的静态错误页
&&步骤三:重点,一定要对Views/Shared/Error.cshtml文件重新命名,否则自定义的错误页不会显示。
&&方式二:针对控制器或者控制器下的某个Action来构建错误页。
&&&在Web.config文件中进行如下配置
&&&&&&customErrors&&&mode="On"&
&&&&&&&&&&&&&/customErrors&
&&&&**&mode的取值:
&&&&&&&On表示启用自定义错误
&&&&&&&Off表示禁用自定义错误
&&&&&&&RemoteOnly向远程客户端显示自定义错误,并且向本地主机显示&ASP.NET&错误
&&[HandleError(ExceptionType=Exception,View="Error")]
&&//默认ExceptionType取值为Exception,View取值为Error
&&&public&ActionResult&Index()
&&&&&&&&&&&&//查询所有的出版社信息
&&&&&&&&&&&&var&query&=&db.Publishers.Select(c=&c);
&&&&&&&&&&&&return&View(query);
创建一个静态页面,位于对应的Controller所在的View文件夹中
************************************************************************************************
&&&&&&&指定Order属性
&&&&&&&&&&**:01.如果某个Action设置了多个HandleErrorAttribute,Order属性可以用来确定使用哪个过滤器.
&&其值可以设置为从-1(最高优先级)到任何正整数之间的整数来标识其优先级,值越大,
&&优先级别越低.Order属性遵循以下规则:
&&&&&&&&&&&&&&&&*:01.应用到Controller上的过滤器将会自动应用到该Controller的所有Action上.
&&&&&&&&&&&&&&&&*:02.如果Controller和Action都应用了HandleErrorAttribute,那么只要Order属性值相同,
将会先执行Controller上的过滤器,而后才会执行Action上的过滤器.
*:03.对于相同Order属性的过滤器,其执行先后次序不定.
*:04.如果没有指定Order属性,则默认为-1,这意味着该过滤器将比其他的过滤器优先执行,
除非其他过滤器指定了Order为-1.
*:05.如果有多个过滤器可适用,那么第一个可以处理该异常的过滤器会被首先调用,
然后针对该异常的处理将会终结.
***********************************************************************************************
********************************在View中获取异常信息***************************************************************
&&&&ASP.NET&MVC框架将异常信息存储在ViewDataDictionary中来传递给Error视图,
&&&&该ViewDataDictionary的Model属性即是ExceptionContext类的一个实例,
&&&&这个ViewData有下面几个键:
ActionName:目标Action方法的名称
ControllerName:目标Controller的名称
Exception:异常对象.
&&&船停在港湾是很安全的,但那不是造船的目的!
IAuthorizeFilter
IActionFilter
IExceptionFilter
IResultFilter
系统默认过滤器:
[Authorize]
[HandleError]
[OutputCache]
同一个动作方法应用过滤器时,决定执行顺序的因素?
解析:01.类过滤器优先于Action
&&&&&&02.同一个Action上的多个过滤器有Order时,Order值越小,执行优先级越高,默认为-1最高&。
&&&&&&03.在当前的Controller重写OnActionExecuting时,优先级高于其他任何通过特性过滤的内容
***************************01.XSS,CSRF攻击************************************************************
问题一:ASP.NET&MVC中常用的过滤器有哪些?
解析:Authorization&&&Action&&Result&&Exception
问题二:应用程序缓存和输出缓存有什么区别?
解析:应用程序缓存是对集合数据的缓存,输出缓存是对整个页面的缓存。
问题三:同一个动作方法应用过滤器时,决定执行顺序的因素?
解析:按Order属性值从小到达执行。
问题五:解释CSRF的概念?
解析:CSRF全称是Cross&Site&Request&&Forgery,即跨站请求伪造。简单地说,就是假冒正常的http请求。
问题六:Moq&在单元测试中有什么用?
解析:模拟
1.XSS漏洞和防御
&&XSS攻击原理:XSS英文全称Cross-site&scripting,即跨站脚本。
&&首先是恶意用户向某个网站的页面植入破坏性代码,植入的方式,一般是通过表单提交。
&&授课步骤:通过一个评论Demo来用普通的文本框提交数据,这时候会出现&检测到存在危险的Request.Form&值。然后我们不检查输入,在Action中进行如下设置。
[ValidateInput(false)],然后我们换成了eckeditor,
登录页面的攻击例子
假设登录页面有个输入用户名和密码的输入框,可以有很多Xss/csrf/注入钓鱼网站/SQL&
&输入用户名&:&&&&&"'&&script&alert(1779)&/script&&输入用户名:&&&&&usera&"'&&img&src="javascript:alert(23664)"&&输入用户名:&&&&&"'&&IMG&SRC="/WF_XSRF.html--end_hig--begin_highlight_tag--hlight_tag--"&&输入用户名:&&&&&usera'"&&iframe&src=http://demo.testfire.net--en--begin_highlight_tag--d_highlight_tag--&
2.CSRF漏洞和防御
你在光大银行:可有可无
&[TestMethod]
&&&&&&&&public&void&TestListFriends_UnGrouped()
&&&&&&&&&&&&FriendController&friendController&=&new&FriendController();
&&&&&&&&&&&&var&mock&=&new&Mock&ControllerContext&();
&&&&&&&&&&&&mock.Setup(p&=&&p.HttpContext.User.Identity.Name).Returns("1");
&&&&&&&&&&&&friendController.ControllerContext&=&mock.O
&&&&&&&&&&&&//执行
&&&&&&&&&&&&PartialViewResult&result&=&(PartialViewResult)friendController.ListFriends(-1);
&&&&&&&&&&&&//断言
&&&&&&&&&&&&Assert.IsNotNull(result);
&&&&&&&&&&&&Assert.IsNotNull(result.ViewBag.Friends);
//单元测试
&单元测试是由开发人员来测试,主要是对业务方法的测试。测试的核心就是断言类Assert,
他提供了一堆静态方法供程序员使用。
不需要提供上下文的:直接创建出一个单元测试项目,添加对被测项目Book的引用。
需要提供上下文的:利用第三方的Moq.dll框架实现
&&*01.引入被测项目
&&&*02.在测试工程中,创建一个lib文件夹,放入Moq.dll文件,并且添加引用
&&&*03.一定要在测试工程的App.config文件的ConnectionString节点中,添加连接字符串
(从被测项目的根目录的Web.config获取)
&&&*04.在打有[TestMethod]
CSRF:必须在用户正常登陆网站的前提下实施的。
本质上是在需要提交表单的页码隐藏了令牌XXXToken,在控制器的Post方法中,对令牌进行校验。
在IIS中发布MVC应用,和之前的ASP.NET方式一样
相关搜索:
相关阅读:
相关频道:
&&&&&&&&&&&&&&&&
Asp.Net教程最近更新

我要回帖

更多关于 asp.net 的文章

 

随机推荐