lASP.NET MVC系列文章
【02】浅谈Google Chrome浏览器(操作篇)(上)
【03】浅谈Google Chrome浏览器(操作篇)(下)
【04】浅谈ASP.NET框架
【07】浅谈ASP.NET MVC 路由
【08】浅谈ASP.NET MVC 视图
【10】浅谈jqGrid 在ASP.NET MVC中增删改查
【13】浅谈NuGet在VS中的运用
【14】浅谈ASP.NET 程序发布过程
一 引入背景
我们知道,MVC基架为我们提供了很多基础类,当需要使用时,只需调用即可,以ActionResult为例,其有很多子类,如ContentResult,EmptyResult,FileResult,HttpStatusCodeResult,JavaScriptResult,JsonResult,RedirectResult,RedirectToRouteResult,ViewResultBase,FileContentResult,FilePathResult,FileStreamResult,ViewResult,PartialResult,
然而,尽管MVC基架提供了众多类供我们调用,但却并不是包括所有功能的类,比如,我需要返回XML格式的数据,或下载CSV格式的数据,此时,MVC基架就没提供相应的类。因此,MVC类的扩展就迫在眉睫了。
在本篇文章中,主要讲解MVC比较核心的八大扩展类,一共分为两篇,即浅谈ASP.NET MVC八大类扩展(上篇)和浅谈ASP.NET MVC八大类扩展(下篇)。
其中,本篇文章主要讲解MVC基架提供的ActionResult及其子孙类,自定义扩展XMLResult和CsvResult,下篇文章将讲解剩下的七大类自定义扩展:Filter扩展,RazorViewEngine扩展,HtmlHelper扩展,Validator扩展,ModelBinder扩展,ControllerFactory注入扩展,Lambda 树扩展。
二 ASP.NET MVC扩展概述
但凡涉及到架构,我们首先都会关心安全性,稳定性,可扩展性等特征,当然,ASO.NET MVC也不例外,MVC之所以比WebForm流行,不仅仅在于其实现前后端的松耦合,而且其也支持强大的自定义扩展,在本篇文章中,我们就是运用MVC支持自定义扩展这一特性来进行自定义扩展,从而实现个性化项目需求。
三 代码实例
(一) ActionResult扩展
1 AtionResult内置扩展
ASP.NET MVC提供了如下内置扩展类.
1.1 上图简要概述
(1)ActionResult类继承Object类;
(2)ContentResult,EmptyResult,FileResult,HttpStatusCodeResult,JavaScriptResult,JsonResult,ViewResultBase,RedirectToRouteResult,RedirectResult 九大类继承类ActionResult;
(3)FileContentResult,FilePathResult,FileStreamResult 三大类继承类FileResult;
(4)ViewResult,PartialViewResult两大类继承类ViewResultBase;
1.2 ActionResult讲解
功能:封装一个操作方法的结果并用于代表该操作方法执行框架级操作。
在Mvc中,我们对如下代码再熟悉不过了。
public ActionResult Index()
{
return View();
}
F12查看ActionResult定义
namespace System.Web.Mvc
{
//
// 摘要:
// 表示操作方法的结果。
public abstract class ActionResult
{
//
// 摘要:
// 初始化 System.Web.Mvc.ActionResult 类的新实例。
protected ActionResult(); //
// 摘要:
// 通过从 System.Web.Mvc.ActionResult 类继承的自定义类型,启用对操作方法结果的处理。
//
// 参数:
// context:
// 用于执行结果的上下文。上下文信息包括控制器、HTTP 内容、请求上下文和路由数据。
public abstract void ExecuteResult(ControllerContext context);
}
}
不难看出,ActionResult具有如下特征:
(1)抽象类;
(2)一个只可继承的构造函数;
(3)一个未实现的抽象方法;
1.2.1 ContentResult讲解
功能:表示用户定义的内容类型,该类型是操作方法的结果。
定义:查看定义
不难看出,ContentResult具有如下特征:
(1)继承自类ActionResult
(2)包含一个构造方法,一个重写ActionResultl类的抽象方法ExecuteResult(ControllerContext context),和三个属性;
(3)完整定义
public class ContentResult : ActionResult
{
// Methods
public override void ExecuteResult(ControllerContext context)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
HttpResponseBase response = context.HttpContext.Response;
if (!string.IsNullOrEmpty(this.ContentType))
{
response.ContentType = this.ContentType;
}
if (this.ContentEncoding != null)
{
response.ContentEncoding = this.ContentEncoding;
}
if (this.Content != null)
{
response.Write(this.Content);
}
} // Properties
public string Content { get; set; } public Encoding ContentEncoding { get; set; } public string ContentType { get; set; }
}
(4)我们来看看具体例子:
如我们向页面输出“Alan_beijing”,可采取如下两种方式。
方式一:
public ContentResult ContextResultTest()
{
return Content("Alan_beijing");
}
测试结果
方式二
public ContentResult ContextResultTest()
{
//string str = "<html>" + "<head></head>" + "<body>" + "Alan_beijing" + "</body>" + "</html>";
string str = "<html><head></head></body>Alan_beijing</body></html>";
return Content(str);
}
测试结果
总之,大家在使用时,可以把ContentResult当作Responce.Write()使用。
1.2.2 EmptyResult
功能:表示一个不执行任何操作的结果,如不返回任何内容的控制器操作方法。
(1)查看定义
(2)完整定义
public class EmptyResult : ActionResult
{
// Fields
private static readonly EmptyResult _singleton = new EmptyResult(); // Methods
public override void ExecuteResult(ControllerContext context)
{
} // Properties
internal static EmptyResult Instance =>
_singleton;
}
(3)总结
EmptyResult不执行任何操作,相当于如下功能。
public ContentResult ContextResultTest()
{
return Content("");
}
1.2.3 FileResult
功能:表示一个用于将二进制文件内容发送到响应的基类。
(1)查看定义
(2)完整定义
public abstract class FileResult : ActionResult
{
// Fields
private string _fileDownloadName; // Methods
protected FileResult(string contentType)
{
if (string.IsNullOrEmpty(contentType))
{
throw new ArgumentException(MvcResources.Common_NullOrEmpty, "contentType");
}
this.ContentType = contentType;
} public override void ExecuteResult(ControllerContext context)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
HttpResponseBase response = context.HttpContext.Response;
response.ContentType = this.ContentType;
if (!string.IsNullOrEmpty(this.FileDownloadName))
{
string headerValue = ContentDispositionUtil.GetHeaderValue(this.FileDownloadName);
context.HttpContext.Response.AddHeader("Content-Disposition", headerValue);
}
this.WriteFile(response);
} protected abstract void WriteFile(HttpResponseBase response); // Properties
public string ContentType { get; private set; } public string FileDownloadName
{
get =>
(this._fileDownloadName ?? string.Empty);
set
{
this._fileDownloadName = value;
}
} // Nested Types
internal static class ContentDispositionUtil
{
// Fields
private const string HexDigits = "0123456789ABCDEF"; // Methods
private static void AddByteToStringBuilder(byte b, StringBuilder builder)
{
builder.Append('%');
int num = b;
AddHexDigitToStringBuilder(num >> , builder);
AddHexDigitToStringBuilder(num % 0x10, builder);
} private static void AddHexDigitToStringBuilder(int digit, StringBuilder builder)
{
builder.Append("0123456789ABCDEF"[digit]);
} private static string CreateRfc2231HeaderValue(string filename)
{
StringBuilder builder = new StringBuilder("attachment; filename*=UTF-8''");
foreach (byte num in Encoding.UTF8.GetBytes(filename))
{
if (IsByteValidHeaderValueCharacter(num))
{
builder.Append((char) num);
}
else
{
AddByteToStringBuilder(num, builder);
}
}
return builder.ToString();
} public static string GetHeaderValue(string fileName)
{
foreach (char ch in fileName)
{
if (ch > '\x007f')
{
return CreateRfc2231HeaderValue(fileName);
}
}
ContentDisposition disposition = new ContentDisposition {
FileName = fileName
};
return disposition.ToString();
} private static bool IsByteValidHeaderValueCharacter(byte b)
{
if ((0x30 <= b) && (b <= 0x39))
{
return true;
}
if ((0x61 <= b) && (b <= 0x7a))
{
return true;
}
if ((0x41 <= b) && (b <= ))
{
return true;
}
switch (b)
{
case 0x3a:
case 0x5f:
case 0x7e:
case 0x24:
case 0x26:
case 0x21:
case 0x2b:
case 0x2d:
case 0x2e:
return true;
}
return false;
}
}
}
1.2.4 HttpStatusCodeResult
功能:提供一种用于返回带特定 HTTP 响应状态代码和说明的操作结果的方法。
(1)定义
(2)完整定义
public class HttpStatusCodeResult : ActionResult
{
// Methods
public HttpStatusCodeResult(int statusCode) : this(statusCode, null)
{
} public HttpStatusCodeResult(HttpStatusCode statusCode) : this(statusCode, null)
{
} public HttpStatusCodeResult(int statusCode, string statusDescription)
{
this.StatusCode = statusCode;
this.StatusDescription = statusDescription;
} public HttpStatusCodeResult(HttpStatusCode statusCode, string statusDescription) : this((int) statusCode, statusDescription)
{
} public override void ExecuteResult(ControllerContext context)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
context.HttpContext.Response.StatusCode = this.StatusCode;
if (this.StatusDescription != null)
{
context.HttpContext.Response.StatusDescription = this.StatusDescription;
}
} // Properties
public int StatusCode { get; private set; } public string StatusDescription { get; private set; }
}
1.2.5 JavaScriptResult
功能:将 JavaScript 内容发送到响应。
(1)定义
(2)完整定义
public class JavaScriptResult : ActionResult
{
// Methods
public override void ExecuteResult(ControllerContext context)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
HttpResponseBase response = context.HttpContext.Response;
response.ContentType = "application/x-javascript";
if (this.Script != null)
{
response.Write(this.Script);
}
} // Properties
public string Script { get; set; }
}
1.2.6 JsonResult
功能:表示一个类,该类用于将 JSON 格式的内容发送到响应。
(1)定义
(2)完整定义
public class JsonResult : ActionResult
{
// Methods
public JsonResult()
{
this.JsonRequestBehavior = JsonRequestBehavior.DenyGet;
} public override void ExecuteResult(ControllerContext context)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
if ((this.JsonRequestBehavior == JsonRequestBehavior.DenyGet) && string.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase))
{
throw new InvalidOperationException(MvcResources.JsonRequest_GetNotAllowed);
}
HttpResponseBase response = context.HttpContext.Response;
if (!string.IsNullOrEmpty(this.ContentType))
{
response.ContentType = this.ContentType;
}
else
{
response.ContentType = "application/json";
}
if (this.ContentEncoding != null)
{
response.ContentEncoding = this.ContentEncoding;
}
if (this.Data != null)
{
JavaScriptSerializer serializer = new JavaScriptSerializer();
if (this.MaxJsonLength.HasValue)
{
serializer.MaxJsonLength = this.MaxJsonLength.Value;
}
if (this.RecursionLimit.HasValue)
{
serializer.RecursionLimit = this.RecursionLimit.Value;
}
response.Write(serializer.Serialize(this.Data));
}
} // Properties
public Encoding ContentEncoding { get; set; } public string ContentType { get; set; } public object Data { get; set; } public JsonRequestBehavior JsonRequestBehavior { get; set; } public int? MaxJsonLength { get; set; } public int? RecursionLimit { get; set; }
}
(3)总结
JsonResult首先将指定的对象序列化为Json字符串,然后将字符串写入到HTTP输出流。
1.2.7 RedirectResult
功能:通过重定向到指定的 URI 来控制对应用程序操作的处理。
(1)定义
(2)完整定义
public class RedirectResult : ActionResult
{
// Methods
public RedirectResult(string url) : this(url, false)
{
} public RedirectResult(string url, bool permanent)
{
if (string.IsNullOrEmpty(url))
{
throw new ArgumentException(MvcResources.Common_NullOrEmpty, "url");
}
this.Permanent = permanent;
this.Url = url;
} public override void ExecuteResult(ControllerContext context)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
if (context.IsChildAction)
{
throw new InvalidOperationException(MvcResources.RedirectAction_CannotRedirectInChildAction);
}
string url = UrlHelper.GenerateContentUrl(this.Url, context.HttpContext);
context.Controller.TempData.Keep();
if (this.Permanent)
{
context.HttpContext.Response.RedirectPermanent(url, false);
}
else
{
context.HttpContext.Response.Redirect(url, false);
}
} // Properties
public bool Permanent { get; private set; } public string Url { get; private set; }
}
1.2.8 RedirectToRouteResult
功能:表示使用指定的路由值字典来执行重定向的结果。
(1)定义
(2)完整定义
public class RedirectToRouteResult : ActionResult
{
// Fields
private RouteCollection _routes; // Methods
public RedirectToRouteResult(RouteValueDictionary routeValues) : this(null, routeValues)
{
} public RedirectToRouteResult(string routeName, RouteValueDictionary routeValues) : this(routeName, routeValues, false)
{
} public RedirectToRouteResult(string routeName, RouteValueDictionary routeValues, bool permanent)
{
this.Permanent = permanent;
this.RouteName = routeName ?? string.Empty;
this.RouteValues = routeValues ?? new RouteValueDictionary();
} public override void ExecuteResult(ControllerContext context)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
if (context.IsChildAction)
{
throw new InvalidOperationException(MvcResources.RedirectAction_CannotRedirectInChildAction);
}
string str = UrlHelper.GenerateUrl(this.RouteName, null, null, this.RouteValues, this.Routes, context.RequestContext, false);
if (string.IsNullOrEmpty(str))
{
throw new InvalidOperationException(MvcResources.Common_NoRouteMatched);
}
context.Controller.TempData.Keep();
if (this.Permanent)
{
context.HttpContext.Response.RedirectPermanent(str, false);
}
else
{
context.HttpContext.Response.Redirect(str, false);
}
} // Properties
public bool Permanent { get; private set; } public string RouteName { get; private set; } internal RouteCollection Routes
{
get
{
if (this._routes == null)
{
this._routes = RouteTable.Routes;
}
return this._routes;
}
set
{
this._routes = value;
}
} public RouteValueDictionary RouteValues { get; private set; }
}
1.2.9 ViewResultBase
功能:表示一个用于为视图提供模型并向响应呈现视图的基类。
(1)定义
(2)完整定义
public abstract class ViewResultBase : ActionResult
{
// Fields
private DynamicViewDataDictionary _dynamicViewData;
private TempDataDictionary _tempData;
private ViewDataDictionary _viewData;
private ViewEngineCollection _viewEngineCollection;
private string _viewName; // Methods
protected ViewResultBase()
{
} public override void ExecuteResult(ControllerContext context)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
if (string.IsNullOrEmpty(this.ViewName))
{
this.ViewName = context.RouteData.GetRequiredString("action");
}
ViewEngineResult result = null;
if (this.View == null)
{
result = this.FindView(context);
this.View = result.View;
}
TextWriter output = context.HttpContext.Response.Output;
ViewContext viewContext = new ViewContext(context, this.View, this.ViewData, this.TempData, output);
this.View.Render(viewContext, output);
if (result != null)
{
result.ViewEngine.ReleaseView(context, this.View);
}
} protected abstract ViewEngineResult FindView(ControllerContext context); // Properties
public object Model =>
this.ViewData.Model; public TempDataDictionary TempData
{
get
{
if (this._tempData == null)
{
this._tempData = new TempDataDictionary();
}
return this._tempData;
}
set
{
this._tempData = value;
}
} public IView View { get; set; } [Dynamic]
public object ViewBag
{
[return: Dynamic]
get
{
Func<ViewDataDictionary> viewDataThunk = null;
if (this._dynamicViewData == null)
{
if (viewDataThunk == null)
{
viewDataThunk = () => this.ViewData;
}
this._dynamicViewData = new DynamicViewDataDictionary(viewDataThunk);
}
return this._dynamicViewData;
}
} public ViewDataDictionary ViewData
{
get
{
if (this._viewData == null)
{
this._viewData = new ViewDataDictionary();
}
return this._viewData;
}
set
{
this._viewData = value;
}
} public ViewEngineCollection ViewEngineCollection
{
get =>
(this._viewEngineCollection ?? ViewEngines.Engines);
set
{
this._viewEngineCollection = value;
}
} public string ViewName
{
get =>
(this._viewName ?? string.Empty);
set
{
this._viewName = value;
}
}
}
1.2.10 FileContentResult
功能:将二进制文件的内容发送到响应
定义:
public class FileContentResult : FileResult
{
// Methods
public FileContentResult(byte[] fileContents, string contentType) : base(contentType)
{
if (fileContents == null)
{
throw new ArgumentNullException("fileContents");
}
this.FileContents = fileContents;
} protected override void WriteFile(HttpResponseBase response)
{
response.OutputStream.Write(this.FileContents, , this.FileContents.Length);
} // Properties
public byte[] FileContents { get; private set; }
}
1.2.11 FilePathResult
功能:将文件的内容发送到响应。
定义:
public class FilePathResult : FileResult
{
// Methods
public FilePathResult(string fileName, string contentType) : base(contentType)
{
if (string.IsNullOrEmpty(fileName))
{
throw new ArgumentException(MvcResources.Common_NullOrEmpty, "fileName");
}
this.FileName = fileName;
} protected override void WriteFile(HttpResponseBase response)
{
response.TransmitFile(this.FileName);
} // Properties
public string FileName { get; private set; }
}
1.2.12 FilestreamResult
功能:使用Stream实例将二进制内容发送到响应。
定义:
public class FileStreamResult : FileResult
{
// Fields
private const int BufferSize = 0x1000; // Methods
public FileStreamResult(Stream fileStream, string contentType) : base(contentType)
{
if (fileStream == null)
{
throw new ArgumentNullException("fileStream");
}
this.FileStream = fileStream;
} protected override void WriteFile(HttpResponseBase response)
{
Stream outputStream = response.OutputStream;
using (this.FileStream)
{
byte[] buffer = new byte[0x1000];
while (true)
{
int count = this.FileStream.Read(buffer, , 0x1000);
if (count == )
{
return;
}
outputStream.Write(buffer, , count);
}
}
} // Properties
public Stream FileStream { get; private set; }
}
1.2.13 ViewResult
功能:表示一个类,该类用于使用由IViewEngine对象返回的IView实例来呈现视图。
(1)定义:
public class ViewResult : ViewResultBase
{
// Fields
private string _masterName; // Methods
protected override ViewEngineResult FindView(ControllerContext context)
{
ViewEngineResult result = base.ViewEngineCollection.FindView(context, base.ViewName, this.MasterName);
if (result.View != null)
{
return result;
}
StringBuilder builder = new StringBuilder();
foreach (string str in result.SearchedLocations)
{
builder.AppendLine();
builder.Append(str);
}
throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, MvcResources.Common_ViewNotFound, new object[] { base.ViewName, builder }));
} // Properties
public string MasterName
{
get =>
(this._masterName ?? string.Empty);
set
{
this._masterName = value;
}
}
}
1.2.14 PartialResult
功能:表示一个用于将分部视图发送到响应的基类。
(1)定义:
public class PartialViewResult : ViewResultBase
{
// Methods
protected override ViewEngineResult FindView(ControllerContext context)
{
ViewEngineResult result = base.ViewEngineCollection.FindPartialView(context, base.ViewName);
if (result.View != null)
{
return result;
}
StringBuilder builder = new StringBuilder();
foreach (string str in result.SearchedLocations)
{
builder.AppendLine();
builder.Append(str);
}
throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, MvcResources.Common_PartialViewNotFound, new object[] { base.ViewName, builder }));
}
}
2 ActionResult自定义扩展
关于ActionResult的自定义扩展,满足两个条件
(1)继承ActionResult
(2)重写ExecuteResult()方法
2.1 XMLResult
public class XmlResult : ActionResult
{
private object _data; public XmlResult(object data)
{
_data = data;
} public override void ExecuteResult(ControllerContext context)
{
var serializer = new XmlSerializer(_data.GetType());
var response = context.HttpContext.Response;
response.ContentType = "text/xml";
serializer.Serialize(response.Output, _data);
}
}
Controller
public XmlResult GetEmpInfo()
{
EmpInfo empInfo = new EmpInfo()
{
Name = "Alan_beijing",
Address = "China-ShangHai",
Age=
};
return new XmlResult(empInfo);
}
Test Result
2.2 CsvResult
public class CsvResult : FileResult
{
private IEnumerable _data; public CsvResult(IEnumerable data, string fileName) : base("text/csv")
{
_data = data;
FileDownloadName = fileName;
} protected override void WriteFile(HttpResponseBase response)
{
var builder = new StringBuilder();
var strWriter = new StringWriter(builder); foreach (var item in _data)
{
var properties = item.GetType().GetProperties();
foreach (var prop in properties)
{
strWriter.Write(GetValue(item, prop.Name));
strWriter.Write(", ");
}
strWriter.WriteLine();
} response.Write(builder);
} public static string GetValue(object item, string propName)
{
return item.GetType().GetProperty(propName).GetValue(item, null).ToString() ?? "";
}
}
Controller
public CsvResult DownCsvEmpInfo()
{
EmpInfo empInfo = new EmpInfo()
{
Name = "Alan_beijing",
Address = "China-ShangHai",
Age = 40
};
return new CsvResult(new List<EmpInfo>() { empInfo }, "empInfo");
}
测试结果
四 推荐网址
【01】https://msdn.microsoft.com/zh-cn/library/system.web.mvc.actionresult(v=vs.118).aspx
五 后续
敬请等待下一篇......
六 服务区
有喜欢的朋友,可以看一下,不喜欢的的朋友,勿喷,谢谢!!
【ASP.NET MVC系列】浅谈ASP.NET MVC八大类扩展(上篇)的更多相关文章
-
MVC模式浅谈
MVC模式浅谈 一.MVC模式概述 模型-视图-控制器(MVC模式)是一种非常经典的软件架构模式,在UI框架和UI设计思路中扮演着非常重要的角色.从设计模式的角度来看,MVC模式是 一种复合模式,它将 ...
-
【ASP.NET MVC系列】浅谈ASP.NET 页面之间传值的几种方式
ASP.NET MVC系列文章 [01]浅谈Google Chrome浏览器(理论篇) [02]浅谈Google Chrome浏览器(操作篇)(上) [03]浅谈Google Chrome浏览器(操作 ...
-
【ASP.NET MVC系列】浅谈ASP.NET MVC运行过程
ASP.NET MVC系列文章 [01]浅谈Google Chrome浏览器(理论篇) [02]浅谈Google Chrome浏览器(操作篇)(上) [03]浅谈Google Chrome浏览器(操作 ...
-
【ASP.NET MVC系列】浅谈ASP.NET MVC 视图
ASP.NET MVC系列文章 [01]浅谈Google Chrome浏览器(理论篇) [02]浅谈Google Chrome浏览器(操作篇)(上) [03]浅谈Google Chrome浏览器(操作 ...
-
【ASP.NET MVC系列】浅谈ASP.NET MVC 视图与控制器传递数据
ASP.NET MVC系列文章 [01]浅谈Google Chrome浏览器(理论篇) [02]浅谈Google Chrome浏览器(操作篇)(上) [03]浅谈Google Chrome浏览器(操作 ...
-
【ASP.NET MVC系列】浅谈ASP.NET MVC 控制器
ASP.NET MVC系列文章 [01]浅谈Google Chrome浏览器(理论篇) [02]浅谈Google Chrome浏览器(操作篇)(上) [03]浅谈Google Chrome浏览器(操作 ...
-
【ASP.NET MVC系列】浅谈ASP.NET MVC 路由
ASP.NET MVC系列文章 [01]浅谈Google Chrome浏览器(理论篇) [02]浅谈Google Chrome浏览器(操作篇)(上) [03]浅谈Google Chrome浏览器(操作 ...
-
【ASP.NET MVC系列】浅谈ASP.NET 程序发布过程
ASP.NET MVC系列文章 [01]浅谈Google Chrome浏览器(理论篇) [02]浅谈Google Chrome浏览器(操作篇)(上) [03]浅谈Google Chrome浏览器(操作 ...
-
浅谈ASP.NET ---- 系列文章
[01]浅谈Google Chrome浏览器(理论篇) [02]浅谈Google Chrome浏览器(操作篇)(上) [03]浅谈Google Chrome浏览器(操作篇)(下) [04]浅谈ASP. ...
随机推荐
-
java中的equals()方法重写
如何java中默认的equals方法跟实际不符的话,需要重写equals方法.例如: public class TestEquals { public static void main(String[ ...
-
fw: webdriver 那些坑
http://www.cnblogs.com/huang0925/p/3384596.html 使用WebDriver遇到的那些坑 在做web项目的自动化端到端测试时主要使用的是Selenium ...
-
ngrok内网穿透利器在windws下的使用
1.到官网下载windows版本:https://ngrok.com/download 2.解压,双击“ngrok.exe” 3.输入“ngrok http 80”,会随机给你分配域名.见下图. ng ...
-
Freemarker中遍历List以及内置函数使用
在Freemarker应用中经常会遍历List获取需要的数据,并对需要的数据进行排序加工后呈现给用户. 那么在Freemarker中如何遍历List,并对List中数据进行适当的排序呢?一. Free ...
-
MVC中System.InvalidOperationException: 传入字典的模型项的类型为“XXX”,但此字典需要类型“XXA”的模型项
出现此类错误的一个原因是Controller传过去的Model和View中的Model不是同一个Model
-
Android(java)学习笔记133:ListViewProject案例(ListView + BaseAdapter + CheckBox)
这个案例可能稍微复杂一点,我会讲述详细一点: 1.首先是AndroidManifest.xml: <?xml version="1.0" encoding="utf ...
-
java学习(四)--- String 、StringBuffer、StringBuilder 和 数组
对于 String.StringBuffer.StringBuilder比较一下 主要说说三者的不同 String 长度大小不可变 StringBuffer 和 StringBuilder 长度可变 ...
-
基于Java服务的前后端分离解决跨域问题
导语:解决跨域问题,前后端都增加相应的允许跨域的代码段即可. 一.后端增加允许跨域的代码,可以在具体controler层加,最好是在filter中添加,这样添加一次就够了,不用在每个controler ...
-
剑指offer之二叉树
二叉树前序,中序,后序遍历思想 前序遍历:ABDCEFGH 中序遍历:BDAFEHGC 后序遍历:DBFHGECA 科普 队列(queue)是一种常用的数据结构,可以将队列看做是一种特殊的线性表,该结 ...
-
koa2 中 cookie 存在的中文问题
koa2 中的 cookie 没办法直接设置中文,会报错 ‘ argument value is invalid ’ 解决办法: 先将它转成 ‘ base64 ’ 编码来存储 new Buffer( ...