这样返回Json到页面后,为什么不需要序列化为json对象,可以直接使用
data.属性 之类的就可以使用了
而像这种 返回json到页面 需要序列化为对象,然后使用?
都可以直接使用,不需要序列化为对象,Json() 会自动进行序列化
嗯嗯,为什么有的时候在页面上需要序列化呢?
比如
var ajaxResult = eval("(" + data + ")");
@~雨落忧伤~: 那是其他问题引起的,不是 ActionResult 与 JsonResult 的问题
@~雨落忧伤~: 建议在出问题时看一下响应头中content-type是否正确
content-type:application/json; charset=utf-8
@dudu: content-type:application/json; 这就代表是json对象吗? 还是json字符串
你不是传了对象给JsonResult吗 —— 说明它做了这个过程三。
常见的各种Result都是 ActionResult 派生的,都去各自实现 自己的 成员 及 核心过程: ExecuteResult
比如以下是JsonResult的部分源代码,我们可以看到它在核心 函数 ExecuteResult 做了头部处理,做了Http Body 内容处理——
1 public override void ExecuteResult(ControllerContext context) 2 { 3 if (context == null) 4 throw new ArgumentNullException("context"); 5 if (this.JsonRequestBehavior == JsonRequestBehavior.DenyGet && string.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase)) 6 throw new InvalidOperationException(MvcResources.JsonRequest_GetNotAllowed); 7 HttpResponseBase response = context.HttpContext.Response; 8 response.ContentType = string.IsNullOrEmpty(this.ContentType) ? "application/json" : this.ContentType; 9 if (this.ContentEncoding != null) 10 response.ContentEncoding = this.ContentEncoding; 11 if (this.Data == null) 12 return; 13 JavaScriptSerializer scriptSerializer = new JavaScriptSerializer(); 14 if (this.MaxJsonLength.HasValue) 15 scriptSerializer.MaxJsonLength = this.MaxJsonLength.Value; 16 if (this.RecursionLimit.HasValue) 17 scriptSerializer.RecursionLimit = this.RecursionLimit.Value; 18 response.Write(scriptSerializer.Serialize(this.Data)); 19 }
所以以此类推,如果你想做其他result,只需要根据result最终的样子 —— 核心通过派生ActionResult,并重写ExecuteResult 即可实现。
response.ContentType = string.IsNullOrEmpty(this.ContentType) ? "application/json" : this.ContentType;
这么说
这个方法 应该还可以返回其他类型的数据吧?
@~雨落忧伤~:肯定可以三。
eg.
1 public class ImageResult : ActionResult 2 { 3 public ImageResult() { } 4 public Image Image { get; set; } 5 public ImageFormat ImageFormat { get; set; } 6 public override void ExecuteResult(ControllerContext context) 7 { 8 // verify properties 9 if (Image == null) 10 { 11 throw new ArgumentNullException("Image"); 12 } 13 if (ImageFormat == null) 14 { 15 throw new ArgumentNullException("ImageFormat"); 16 } 17 // output 18 context.HttpContext.Response.Clear(); 19 if (ImageFormat.Equals(ImageFormat.Bmp)) context.HttpContext.Response.ContentType = "image/bmp"; 20 if (ImageFormat.Equals(ImageFormat.Gif)) context.HttpContext.Response.ContentType = "image/gif"; 21 if (ImageFormat.Equals(ImageFormat.Icon)) context.HttpContext.Response.ContentType = "image/vnd.microsoft.icon"; 22 if (ImageFormat.Equals(ImageFormat.Jpeg)) context.HttpContext.Response.ContentType = "image/jpeg"; 23 if (ImageFormat.Equals(ImageFormat.Png)) context.HttpContext.Response.ContentType = "image/png"; 24 if (ImageFormat.Equals(ImageFormat.Tiff)) context.HttpContext.Response.ContentType = "image/tiff"; 25 if (ImageFormat.Equals(ImageFormat.Wmf)) context.HttpContext.Response.ContentType = "image/wmf"; 26 Image.Save(context.HttpContext.Response.OutputStream, ImageFormat); 27 } 28 }
class ViewResultBase //ViewResult 又是从这个派生的 { public override void ExecuteResult(ControllerContext context) { if (context == null) throw new ArgumentNullException(nameof (context)); if (string.IsNullOrEmpty(this.ViewName)) this.ViewName = context.RouteData.GetRequiredString("action"); ViewEngineResult viewEngineResult = (ViewEngineResult) null; if (this.View == null) { viewEngineResult = this.FindView(context); this.View = viewEngineResult.View; } TextWriter output = context.HttpContext.Response.Output; this.View.Render(new ViewContext(context, this.View, this.ViewData, this.TempData, output), output); if (viewEngineResult == null) return; viewEngineResult.ViewEngine.ReleaseView(context, this.View); } }
好好理解吧。
@花飘水流兮: 第一个勉强还看得懂,第二个就看不懂了
里面的
看的有点蒙,里面好多东西没用过
@~雨落忧伤~: 最重要的是你理解的截图,你就大大滴进步了。我也很多没用过,你心头好过些了吧。实际有的东西你用了只是你没觉得而已,比如ViewReuslt,你Return View()的时候就用了,上下文多多注意,多思考(假如是我,要怎么写才能这样提供接口),有条件和时间也可以看看人家源码是不是这么实现的。
@花飘水流兮: 嗯嗯,醍醐灌顶,说的很对,
@花飘水流兮: 大哥,请受小弟一拜, 你的方法我看了好久 还是不太明白 ViewResult 与 ViewEngineResult 这两者的区别...
@~雨落忧伤~: 你看命名空间就知道——那个是MVC本身的源码。这个你不用管太多,就是执行Razor解析的东西,执行为最终的html 文档的东西。你自己都可以加aspx或者Razor渲染器就可以完成到CustomerViewResult,然后可以不用系统自己的ViewResult。【当然这是多余的工作】
只有ImageResult和LJsonResult是个人补充的,前者因为没得,后者因为需要说明如何序列化。
@~雨落忧伤~: 站在通讯上来讲,本身http是个很简单的协议,通讯方式也很简单。你如果自己从tcp写一个mvc就很清楚了,没事的时候你可以试试。
@花飘水流兮: 从tcp写一个mvc tcp协议吗 mvc也可以不走http协议吗?
@~雨落忧伤~:
tcp=>http server=>request 通过文件规则map 各种 XxHandler
将会有一种叫做MvcHandler(还有普通的FileHandler,比如静态的css,js,html等等),该Handler又将实现Request 和 Response的各种类的封装,
其中Response过程 你又将封装各种ActionResult,其中有一种是 ViewResult,ViewResult又有各种Render引擎,比如Razor、aspx甚至jsp等等。
每个环节你都将会发现很多很多问题,比如http协议中get 判断是否修改,内容大小,连接时间...这些都足以搞死服务器,你会明白为什么file 是stream的请求,你会明白 原来 razor就是这么“简单”,自定义razor也是这么简单,然后你会发现razor原来还可以干点其他什么事...你也会发现http传输协议本身很简单,但结构意义却挺复杂,很多很多为什么...
空了慢慢玩吧。
@花飘水流兮: 但不知道怎么使用,代码怎么写?
@花飘水流兮: 也不理解原理~~
主要是$.ajax() 中的dataType参数决定(预期服务器返回的数据类型)。
其次是服务器端响应头的:
// 服务器响应头为:Content-Type:application/json; charset=utf-8 // 服务器返回的内容为:{"Success":true,"Message":null} $.ajax({ url: "/xxx/yyy", data: datas, type: "POST", success: function (data) { //这里的data为对象。 console.log(data); }, }); $.ajax({ url: "/xxx/yyy", data: datas, type: "POST", dataType: "text", success: function (data) { //这里的data为字符串。 console.log(data); }, }); $.ajax({ url: "/xxx/yyy", data: datas, type: "POST", dataType: "json", success: function (data) { //这里的data为对象。 console.log(data); }, });
参照:http://www.w3school.com.cn/jquery/ajax_ajax.asp
也就是说 如果服务器本身返回是json字符串
也可以通过dataType: "json" 设置为json 修改成 对象
这样就不用再这样
var ajaxResult = eval("(" + data + ")");
序列化为对象了
@~雨落忧伤~: 是的,主要以$.ajax的dataType参数为准,前提是要能保证服务器端返回的数据格式是预期的。
例:
服务器端
[HttpPost] public ActionResult Test() { return Content("{\"Test\":\"A\", \"C\":100}", "html/text"); }
客户端
$.ajax({ url: "@Url.Action("Test")", type: "POST", dataType: "json", success: function (data) { //这里的data为对象 console.log(data); }, });
注:因为这里已经知道服务器返回的文本是json格式,所以客户端可以直接当作json来解析。
@listen.core:服务器端返回的数据格式是预期的。
预期的 指的是,返回的数据要 是能被 dataType 转换的字符串吗?
@~雨落忧伤~: 预期的是指返回的数据格式正式客户端处理的那种,否则就没法正确识别啦。(●ˇ∀ˇ●)
@listen.core: 嗯嗯 返回格式 正是 浏览器处理的那种
兄台,学习下什么是 Content-Type。如果返回json格式的数据,js就能以对象的方式访问。否则只是一个字符串。
F12 后 提交的ajax 里面有个Response Headers 和 Request Headers
两个里面都有 Content-Type Content-Length 还有一些其他相同的, 一些不同的
问下,这两个里面的有什么区别吗?