Asp.net MVC上传文件返回Json数据

最近写文件上传的时候,想实现页面动态的更新功能。也就是,页面上有个div,里面是所上传的附件列表,用jQuery Form插件的ajaxSubmit提交,每次上传一个以后,列表都能及时更新(类似于163邮箱上传附件的那个效果)。

准备用Json返回附件的名称。结果发现Controller里面方法能够正常执行,文件也被保存到服务器上,但是return Json("{'file_name':'XXXXX'}",JsonRequestBehavior.AllowGet);完全的不起作用,执行不了js里的success回调函数。

上网查了一通,发现有前辈给出了解决方案:

方法1:借用另外一个Success.aspx页面。

  以下为引用

最近做一个项目,上传文件后我返回一个Json格式的数据,提示上传成功,可是老弹出下载框如下

很郁闷,网上找了很多资料,都不理想,纳闷许久,终于有了解决方案。后台上传成功后是这么写的:return Json("{msg:'上传成功'}");前台是这么接的var json = eval("(" + data + ")");jAlert(json.msg, "提示信息");其中data就是后台返回给前台的Json数据。可是这样即使上传成功也不会弹出提示信息。最后想到了Ajax的原理,于是我重新定义一个页面名为Success.aspx。代码如下

    <%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<dynamic>" %>  
    <%  
    String json = "{suc:1, msg: '保存成功!',url:''}";  
    Response.Write(json);  
    %>  

 让上传文件完成后跳转到这个页面而不是返回给一个Json数据。应该是:return View("~/FileManage/Success.aspx");

本文出自 “微软技术” 博客,请务必保留此出处http://leelei.blog.51cto.com/856755/387271

方法2:是直接返回HTML。

查看jQuery Form的Demo,该插件“接受Server返回的HTML 或 XML数据没什么问题,但是接受script 或 JSON 时, 这两种形式的数据一般都需要处理一下然后利用页面上一些HTML代码来重新展示。考虑到处理 script 和 JSON 类响应的困难,这个插件允许你把这些响应代码嵌入到 textarea 元素里而且我们推荐当表单中有上传域时你使用这种方法’ 然而,请注意, 如果这个上传域里没有提供值,那么表单将会按常规的 XHR 方式提交(不使用iframe)。这就需要server端代码去判断何时使用textarea,何时不使用textarea。如果你喜欢,你可以一直按iframe方式处理。 插件有个选项可以使它强制一直使用 iframe 模式 而你的server端代码就可以一直使用在textarea里嵌入响应代码的形式。”

参考:http://www.cnblogs.com/kmhz/archive/2010/06/25/1765490.html

本来,通过jquery from,ajax上传文件挺容易的,但是,上传完之后想返回json的话,颇费了一些周折。

    asp.net mvc 中可以直接返回一个JsonResult,例如

代码
1 public JsonResult UploadImage()
2 {
3       //上传文件的处理
4   return new JsonResult
5 {
6 Data = _imageService.NewUrl,
7 JsonRequestBehavior = JsonRequestBehavior.AllowGet
8 };
9 }
 

然后

代码
1 $().ready(function () {
2 var options = {
3 dataType: 'json',
4 beforeSubmit: showRequest,
5 error:showError,
6 success: showResponse
7 };
8 $('#myform').ajaxForm(options);
9 });
10
11 function showRequest(formData, jqForm, options) {
12 alert('发送前');
13 return true;
14 }
15 function showError(data) {
16 alert('error');
17 }
18
19 function showResponse(data, status) {
20 alert('发送后');
21 }
 

做完这些,应该就能读取Json,没想到跳出一个文件保存窗口,保存下来的内容,就是我们发送的Json。

百度了一番,发现不仅asp.net平台有问题,J2EE平台也有这么个问题,解决的办法,是直接返回HTML。

public ActrionResult UploadImage()
{
  return Content("{error: 'file size is zero'}""text/html");
}

 这样做之后,终于alert了,但是弹出的信息是error。

仔细研究了一下jquery form官方的例子,发现json内容应该被<textarea>包围

修改后如下:

public ActrionResult UploadImage()
{
  
return Content("<textarea>{error: 'file size is zero'}</textarea>""text/html");
}

 修改完成后,依然跳到showError,通过搜索引擎再没搜索到有用的信息,不得不调试jquery.form.js

搜索textarea,很容易找到了合适的断点

代码
1 try{
2  if (opts.dataType == 'json' || opts.dataType == 'script') {
3 // see if user embedded response in textarea
4   var ta = doc.getElementsByTagName('textarea')[0];
5 if (ta)
6 xhr.responseText = ta.value;
7 else {
8 // account for browsers injecting pre around json response
9   var pre = doc.getElementsByTagName('pre')[0];
10 if (pre)
11 xhr.responseText = pre.innerHTML;
12 }
13 }
14 else if (opts.dataType == 'xml' && !xhr.responseXML && xhr.responseText != null) {
15 xhr.responseXML = toXml(xhr.responseText);
16 }
17 data = $.httpData(xhr, opts.dataType); //这里报错
18   }
19 catch(e){
20 log('error caught:',e);
21 ok = false;
22 xhr.error = e;
23 $.handleError(opts, xhr, 'error', e);
24 }

catch到的信息是“Invalid JSON”。原来从jquery1.4开始,键和值都必须使用两个引号包围,改为以下内容之后解决

return Content("<textarea>{'error': 'file size is zero'}</textarea>""text/html");

在这个问题上,耗费了一整天的时间,记录下来整个过程,希望其他人能用上

PS:有人回复return Content("<textarea>{'error': 'file size is zero'}</textarea>", "text/html");在我这还是报“Invalid JSON”改成return Content("<textarea>{/"error/": /"file size is zero/"}</textarea>", "text/html");就可以了

 

经过方法2返回的字符串,在success回调函数中不会自动转化为Json对象,要用eval("(" + 返回的字符串 + ")")才行。

至于为什么是这样的,自己也不是太清楚,还请各位指教下。

原文地址:https://www.cnblogs.com/huangzy/p/1891497.html