JSON是专门为浏览器中的网页上运行的JavaScript代码而设计的一种数据格式。在网站应用中使用JSON的场景越来越多,本文介绍ASP.NET中JSON的序列化和反序列化,主要对JSON的简单介绍,ASP.NET如何序列化和反序列化的处理,在序列化和反序列化对日期时间、集合、字典的处理。 一、JSON简介 JSON(JavaScript Object Notation,JavaScript对象表示法)是一种轻量级的数据交换格式。 JSON是“名值对”的集合。结构由大括号'{}’,中括号'[]’,逗号’,’,冒号’:’,双引号’“”’组成,包含的数据类型有Object,Number,Boolean,String,Array, NULL等。 JSON具有以下的形式: 对象(Object)是一个无序的“名值对”集合,一个对象以”{”开始,”}”结束。每个“名”后跟着一个”:”,多个“名值对”由逗号分隔。如:
1 |
var user={"name":"张三","gender":"男","birthday":"1980-8-8"} |
数组(Array)是值的有序集合,一个数组以“[”开始,以“]”结束,值之间使用“,”分隔。如:
1 |
var userlist=[{"user":{"name":"张三","gender":"男","birthday":"1980-8-8"}},{"user":{"name":"李四","gender":"男","birthday":"1985-5-8"}}]; |
字符串(String)是由双引号包围的任意数量的Unicode字符的集合,使用反斜线转义。 二、对JSON数据进行序列化和反序列化 可以使用DataContractJsonSerializer类将类型实例序列化为JSON字符串,并将JSON字符串反序列化为类型实例。DataContractJsonSerializer在System.Runtime.Serialization.Json命名空间下,.NET Framework 3.5包含在System.ServiceModel.Web.dll中,需要添加对其的引用;.NET Framework 4在System.Runtime.Serialization中。 利用DataContractJsonSerializer序列化和反序列化的代码:
1 |
1: using System; |
1 |
2: using System.Collections.Generic; |
1 |
3: using System.Linq; |
1 |
4: using System.Web; |
1 |
5: using System.Runtime.Serialization.Json; |
1 |
6: using System.IO; |
1 |
7: using System.Text; |
1 |
8: |
1 |
9: /// <summary> |
1 |
10: /// JSON序列化和反序列化辅助类 |
1 |
11: /// </summary> |
1 |
12: public class JsonHelper |
1 |
13: { |
1 |
14: /// <summary> |
1 |
15: /// JSON序列化 |
1 |
16: /// </summary> |
1 |
17: public static string JsonSerializer<T>(T t) |
1 |
18: { |
1 |
19: DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T)); |
1 |
20: MemoryStream ms = new MemoryStream(); |
1 |
21: ser.WriteObject(ms, t); |
1 |
22: string jsonString = Encoding.UTF8.GetString(ms.ToArray()); |
1 |
23: ms.Close(); |
1 |
24: return jsonString; |
1 |
25: } |
1 |
26: |
1 |
27: /// <summary> |
1 |
28: /// JSON反序列化 |
1 |
29: /// </summary> |
1 |
30: public static T JsonDeserialize<T>(string jsonString) |
1 |
31: { |
1 |
32: DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T)); |
1 |
33: MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonString)); |
1 |
34: T obj = (T)ser.ReadObject(ms); |
1 |
35: return obj; |
1 |
36: } |
1 |
37: } |
序列化Demo: 简单对象Person:
1 |
1: public class Person |
1 |
2: { |
1 |
3: public string Name { get; set; } |
1 |
4: public int Age { get; set; } |
1 |
5: } |
序列化为JSON字符串:
1 |
1: protected void Page_Load(object sender, EventArgs e) |
1 |
2: { |
1 |
3: Person p = new Person(); |
1 |
4: p.Name = "张三"; |
1 |
5: p.Age = 28; |
1 |
6: |
1 |
7: string jsonString = JsonHelper.JsonSerializer<Person>(p); |
1 |
8: Response.Write(jsonString); |
1 |
9: } |
输出结果:
1 |
{"Age":28,"Name":"张三"} |
反序列化Demo:
1 |
1: protected void Page_Load(object sender, EventArgs e) |
1 |
2: { |
1 |
3: string jsonString = "{\"Age\":28,\"Name\":\"张三\"}"; |
1 |
4: Person p = JsonHelper.JsonDeserialize<Person>(jsonString); |
1 |
5: } |
运行结果: ASP.NET中的JSON序列化和反序列化还可以使用JavaScriptSerializer,在System.Web.Script.Serializatioin命名空间下,需引用System.Web.Extensions.dll.也可以使用JSON.NET. […]
View Detailsusing System; using System.Collections.Generic; using System.Text; namespace NET.MST.Fourth.StringByte { class StringByte { static void Main(string[] args) { String s = "我是字符串,I am string"; //字节数组转换到字符串 Byte[] utf8 = StringToByte(s, Encoding.UTF8); Byte[] gb2312 = StringToByte(s, Encoding.GetEncoding("GB2312")); Byte[] unicode = StringToByte(s, Encoding.Unicode); Console.WriteLine(utf8.Length); Console.WriteLine(gb2312.Length); Console.WriteLine(unicode.Length); //转换回字符串 Console.WriteLine(ByteToString(utf8, Encoding.UTF8)); Console.WriteLine(ByteToString(gb2312, Encoding.GetEncoding("GB2312"))); Console.WriteLine(ByteToString(unicode, Encoding.Unicode)); Console.Read(); } static Byte[] StringToByte(String s, Encoding encoding) { return encoding.GetBytes(s); } static String ByteToString(Byte[] b, Encoding encoding) { return encoding.GetString(b); } } } from:http://www.cnblogs.com/brainmao/archive/2011/05/29/2062385.html
View Details介绍 让用户从我们的网站上下载各种类型的文件是一个比较常用的功能,这篇文章就是告诉您如何创建一个.txt文件并让用户下载。 使用代码 虽然在示例里,我先创建了一个text文件,但是你不一定也要这么做,因为这个文件可能在你的网站里已经存在了。如果是这样的话,你只需要使用FileStream去读取它就可以了。 首先,我们将这个text文件读取到一个byte数组中,然后使用Response对象将文件写到客户端就可以了。 Response.AddHeader("Content-disposition", "attachment; filename=" + sGenName); Response.ContentType = "application/octet-stream"; Response.BinaryWrite(btFile); Response.End(); 这段代码是完成这个功能的主要代码。第一句在输出中添加了一个Header,告诉浏览器我们发送给它的是一个附件类型的文件。然后我们设置输出的ContentType是"application/octet-stream",即告诉浏览器要下载这个文件,而不是在浏览器中显示它。 下面是一个MIME类型的列表。 ".asf" = "video/x-ms-asf" ".avi" = "video/avi" ".doc" = "application/msword" ".zip" = "application/zip" ".xls" = "application/vnd.ms-excel" ".gif" = "image/gif" ".jpg"= "image/jpeg" ".wav" = "audio/wav" ".mp3" = "audio/mpeg3" ".mpg" "mpeg" = "video/mpeg" ".rtf" = "application/rtf" ".htm", "html" = "text/html" ".asp" = "text/asp" '所有其它的文件 = "application/octet-stream" 下面是一个完整的如何下载文本文件的示例代码 C# protected void Button1_Click(object sender, EventArgs e) { string sFileName = System.IO.Path.GetRandomFileName(); string sGenName = "Friendly.txt"; //YOu could omit these lines here as you may not want […]
View DetailsIIS上部署MVC网站,打开后ExtensionlessUrlHandler-Integrated-4.0解决方法 IIS上部署MVC网站,打开后500错误:处理程序“ExtensionlessUrlHandler-Integrated-4.0”在其模块列表中有一个错误模块“ManagedPipelineHandler” 解决方法如下: 以管理员运行下面的命令注册: 32位机器: C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis.exe -i 64位机器: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\aspnet_regiis.exe -i
View Details最近新换了系统还真是问题多多呀!! 系统更新补丁后打开 VS2012 ,新建C#项目的时候出现这个问题 VS2012 未找到与约束ContractName Microsoft.VisualStudio.Text.ITextDoc mentFactoryService 我勒个去,相当郁闷呀,赶紧百度,找到了下面两个解决方案: 方案一: 删除 kb2805222 .net4.5 framework 更新程序(控制面板->Windows Update->) 但是我这里没有这个更新 于是我采用第二套方案 方案二: 更新 (KB2781514) 下载网址:http://www.microsoft.com/zh-cn/download/confirmation.aspx?id=36020 OK了!哈哈~~~~ from:http://www.cnblogs.com/csulennon/p/3709019.html
View Details在Sql Server2005中,如果将某字段定义成日期 时间 类型DateTime,那么在视图中会默认显示成年月日时分秒的方式(如 2013/8/6 13:37:33) 如果只想显示成年月日形式,不要时分秒,那么该怎么办呢? 第一种方法:先设置一个时间显示的模板,然后在需要显示时间的地方调用这个模板就行了。 1、在Share文件夹下,创建一个文件夹DisplayTemplates 2、在DisplayTemplates文件夹下,创建一个视图LongDateTime.cshtml 3、在视图LongDateTime.cshtml中输入代码
1 2 3 |
<span class="variable">@model</span> <span class="constant">System</span>.<span class="constant">DateTime</span> <span class="variable">@Model</span>.<span class="constant">ToLongDateString</span>() |
当然,后面那句也可以换成@Model.ToShortDateString()或其它日期格式。 4、在需要显示日期的地方,由原来的
1 |
<span class="at_rule">@Html.<span class="function">DisplayFor(modelItem => item.PostTime)</span></span> |
替换成
1 |
<span class="at_rule">@Html.<span class="function">DisplayFor(modelItem => item.PostTime,<span class="string">"</span><span class="string">LongDateTime"</span>)</span></span> |
这样就完成了时间格式的显示转换。由原来的显示方式(2013/8/6 13:37:33)显示成了(2013年8月6日) 第二种方法:model类上面添加DisplayFormat的attribute. 如:
1 2 3 4 5 6 7 |
[Display(Name = <span class="string">"</span><span class="string">发布时间:"</span>)] [DisplayFormat(DataFormatString = <span class="string">"</span><span class="string">{0:yyyy年MM月dd日}"</span>)] <span class="keyword">public</span> <span class="keyword">virtual</span> System.DateTime PostTime { <span class="keyword">get</span>; <span class="keyword">set</span>; } |
显示出来后,照样是2013年8月6日这种格式。 from:http://www.cnblogs.com/Rising/p/3722299.html
View DetailsASP.NET MVC3中的Model是自验证的,这是通过.NET4的System.ComponentModel.DataAnnotations命名空间完成的。 我们要做的只是给Model类的各属性加上对应的验证标记(Attributes)就可以让MVC3框架帮我们完成验证。我以MVC3项目模板自带的登录 做例子讲解Model的验证。 一、启用客户端验证: 客户端验证主要是为了提高用户体验,在网页不回刷的情况下完成验证。 第一步是要在web.config里启用客户端验证,这在MVC3自带的模板项目中已经有了: <add key="ClientValidationEnabled" value="true"/> <add key="UnobtrusiveJavaScriptEnabled" value="true"/> 然后在被验证的View页面上要加入这样两个JavaScript,注意,他们是依赖于JQuery的: <script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script> <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script> 验证消息的显示有两种,一种是ValidationSummary,它可以显示一份验证消息的汇总,包括从后台Action里返回的消息。 @Html.ValidationSummary(true, "Login was unsuccessful. Please correct the errors and try again.") 另一种是Model中各属性对应HTML控件的验证消息: @Html.ValidationMessageFor(m => m.UserName) 二、在Model中加入验证标记 MVC3项目模板自带的登录模型类如下: public class LogOnModel { [Required] [Display(Name = "User name")] public string UserName { get; set; } [Required] [DataType(DataType.Password)] [Display(Name = "Password")] public string Password { get; set; } [Display(Name = "Remember me?")] public bool RememberMe { get; set; } } 对比普通的C#类,我们发现每个属性上都多了被方括号“[]”包围的标记。其中,[Required]是验证标记的一种,而[Display]、[DataType]则是为了显示对应的HTML控件,这不在本文讨论范围之内。 除了Required,我们还可以在Model中添加其他有用的验证标记。下面是个较完整的列表: Model类中可以添加的验证标记: 1. 必填字段 [Required] public string FirstName { […]
View Details在上一节中提到可以使用AuthorizeAttribute进行权限管理:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
[Authorize] public ActionResult TestAuthorize() { return View(); } [Authorize(Users="test1,test2")] public ActionResult TestAuthorize() { return View(); } [Authorize(Roles="Admin")] public ActionResult TestAuthorize() { return View(); } |
但是通常情况下,网站的权限并不是固定不变的,当新增角色或者角色改变时,只能修改每个Action对应的特性,当项目较大时工作量可想而知。幸运的是我们可以重写AuthorizeAttribute达到自定义的权限管理。新建一个CustomAuthorizeAttribute类,使这个类继承于AuthorizeAttribute。打开AuthorizeAttribute查看下方法说明,我们只需要重写AuthorizeCore和OnAuthorization就能达到我们的目的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
// Summary: // When overridden, provides an entry point for custom authorization checks. // // Parameters: // httpContext: // The HTTP context, which encapsulates all HTTP-specific information about // an individual HTTP request. // // Returns: // true if the user is authorized; otherwise, false. // // Exceptions: // System.ArgumentNullException: // The httpContext parameter is null. protected virtual bool AuthorizeCore(HttpContextBase httpContext); // // Summary: // Called when a process requests authorization. // // Parameters: // filterContext: // The filter context, which encapsulates information for using System.Web.Mvc.AuthorizeAttribute. // // Exceptions: // System.ArgumentNullException: // The filterContext parameter is null. public virtual void OnAuthorization(AuthorizationContext filterContext); |
在CustomAuthorizeAttribute中重载AuthorizeCore方法,它的处理逻辑如下:首先判断当前账户是否被认证,如果没有,则返回false;然后获取当前账户的类型,并跟给定的类型进行比较,如果类型相同,则返回true,否则返回false。一般网站中权限管理都会使用权限树,然后将角色的权限保存至数据库或者文件中,本例中我们使用XML文件保存每个Action的角色,这样在用户请求Action时,由XML文件获取Action对应的权限,然后检测账户是否有相应的权限。CustomAuthorizeAttribute类的代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
public class CustomAuthorizeAttribute : System.Web.Mvc.AuthorizeAttribute { public new string[] Roles { get; set; } protected override bool AuthorizeCore(HttpContextBase httpContext) { if (httpContext == null) { throw new ArgumentNullException("HttpContext"); } if (!httpContext.User.Identity.IsAuthenticated) { return false; } if (Roles == null) { return true; } if (Roles.Length == 0) { return true; } if (Roles.Any(httpContext.User.IsInRole)) { return true; } return false; } public override void OnAuthorization(System.Web.Mvc.AuthorizationContext filterContext) { string controllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName; string actionName = filterContext.ActionDescriptor.ActionName; string roles = GetRoles.GetActionRoles(actionName, controllerName); if (!string.IsNullOrWhiteSpace(roles)) { this.Roles = roles.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries); } base.OnAuthorization(filterContext); } } |
当用户请求一个Action时,会调用OnAuthorization方法,该方法中GetRoles.GetActionRoles(actionName, controllerName);根据Controller和Action去查找当前Action需要具有的角色类型,获得Action的Roles以后,在AuthorizeCore中与用户的角色进行比对Roles.Any(httpContext.User.IsInRole),如果没有相应权限则返回false,程序就会自动跳转到登录页面。 GetRoles为XML解析类,代码如下:
1 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
public class GetRoles { public static string GetActionRoles(string action, string controller) { XElement rootElement = XElement.Load(HttpContext.Current.Server.MapPath("/")+"ActionRoles.xml"); XElement controllerElement = findElementByAttribute(rootElement, "Controller", controller); if (controllerElement != null) { XElement actionElement = findElementByAttribute(controllerElement, "Action", action); if (actionElement != null) { return actionElement.Value; } } return ""; } public static XElement findElementByAttribute(XElement xElement,string tagName, string attribute) { return xElement.Elements(tagName).FirstOrDefault(x => x.Attribute("name").Value.Equals(attribute,StringComparison.OrdinalIgnoreCase)); } } |
相应的权限XMl文件:
1 2 3 4 5 6 7 8 |
<?xml version="1.0" encoding="utf-8" ?> <Roles> <Controller name="Home"> <Action name="Index"></Action> <Action name="About">Manager,Admin</Action> <Action name="Contact">Admin</Action> </Controller> </Roles> |
当需求发生变化时,只需要修改XML文件即可 使用时,只需要在FilterConfig中注册该filter
1 |
filters.Add(new CustomAuthorizeAttribute()); |
当然这只是一个简单的例子,实际应用中会复杂许多,还可能要实现在即的MemberShipProvider和RoleProvider from:http://www.cnblogs.com/jyan/archive/2012/07/24/2606646.html
View Details使用VS2010创建web应用程序时出现如下提示ASP.NET 4.0尚未在 Web 服务器上注册。为了使网站正确运行,可能需要手动将 Web 服务器配置为使用 ASP.NET 4.0,按 F1 可了解更多详细信息 解决方法: 首先设置IIS应用程序池 net framework版本为4.0 然后 开始->所有程序->附件->鼠标右键点击“命令提示符”->以管理员身份运行->%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis.exe -i from:http://www.cnblogs.com/lvxiouzi/p/3511446.html
View Details1. HttpClient简单介绍 依稀还记得那个时候用WebClient,HttpWebRequest来发送一个请求,现在ASP.NET MVC4中自带了一个类HttpClient,用于接收HttpResponseMessage和发送HttpRequestMesssage。 问题在于既然WebClient,HttpWebRequest可以完成相应的功能,为什么还要使用HttpClient类,.NET Framework中既然提出了这样一个类肯定是有其特别之处的,这里罗列几个不同之处: (1) 可以在HttpClient实例上配置扩展,设置默认的头部,取消未完成的的请求和设置 (2) HttpClient有自己的连接池 (3) HttpClient 不与特定的服务器绑定,可以访问任何Http请求 (4) HttpClient采用异步请求处理 2. HttpClient备注说明 HttpClient包含在System.net.Http.dll 程序集中,用户接受和发送http请求,该类适用于.NET4.0以上版本。 默认情况下,HttpWebRequest 将用于向服务器发送请求。此行为可指定一个不同的通道修改在获取 HttpMessageHandler 实例的构造函数重载之一中作为参数。如果需要与身份验证的功能或缓存,WebRequestHandler 可用于配置设置,而实例可传递给构造函数。返回的处理程序传递到采用 HttpMessageHandler 参数的构造函数重载之一 更多说明可以参考微软官方网站: http://msdn.microsoft.com/zh-cn/library/system.net.http.httpclient.aspx 3. HttpClient基本操作 static void BasicMethod() { string url = "http://www.baidu.com"; HttpClient client = new HttpClient(); string content = client.GetStringAsync(url).Result; Console.WriteLine(content); } 以上是使用HttpClient请求百度主页,貌似操作起来也挺方便的,运行输出请求得到的结果如下图: 控制台输出的为请求URL的内容。 HttpClient除了上面提到的GetStringAsync()方法之外,还提供了如下Get方法,详细可以参考MSDN: 4. 自定义请求头 如果要自定义请求头,我们需要继承一个类:HttpClientHandler public class GitHttpClientHandler:HttpClientHandler { protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { request.Headers.Referrer = new Uri("http://www.google.com/"); request.Headers.Add("UserAgent", "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727)"); Task<HttpResponseMessage> task = base.SendAsync(request, cancellationToken); HttpResponseMessage response = task.Result; MediaTypeHeaderValue contentType = response.Content.Headers.ContentType; if (string.IsNullOrEmpty(contentType.CharSet)) { contentType.CharSet = "GBK"; } return task; } } HttpClientHandler就是常见的代理模式,在HttpClient.GetStringAsync()加了一层封装,拦截了HttpClient的输入和输出,从而实现一些自定义的操作,这种方式我们在MVC 中非常常见,就是MVC中的过滤器。 5. 请求内容过长 HttpClient有一个属性MaxResponseContentBufferSize,它表示读取相应内容是最大的字节缓存数,默认值是64K,当页面内容很多的时候,超过64K则会抛出异常HttpRequestException,导致Get失败。 我们可以人工设置这个属性的大小: HttpClient client = new HttpClient() { MaxResponseContentBufferSize = 1024 * 1024 }; 使用如上方式处理即可。 6. 中文问题 中文问题总是令人头疼,很多时候会出现乱码。上面提到的自定义请求头也可以处理,这里贴出一段代码作参考,中文问题有点复杂需要根据具体情况处理: HttpResponseMessage response = task.Result; MediaTypeHeaderValue contentType = response.Content.Headers.ContentType; if(string.IsNullOrEmpty(contentType.CharSet)) { contentType.CharSet = "GBK"; } from:http://www.cnblogs.com/qingyuan/archive/2012/11/08/2760034.html
View Details