asp.net mvc ajax上传文件 然后返回json
本来,通过jquery from,ajax上传文件挺容易的,但是,上传完之后想返回json的话,颇费了一些周折。
asp.net mvc 中可以直接返回一个JsonResult,例如
代码
public JsonResult UploadImage()
{
{
//上传文件的处理
return new JsonResult
{
Data = _imageService.NewUrl,
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
return new JsonResult
{
Data = _imageService.NewUrl,
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
然后
代码
$().ready(function () {
var options = {
dataType: 'json',
beforeSubmit: showRequest,
error:showError,
success: showResponse
};
$('#myform').ajaxForm(options);
});
function showRequest(formData, jqForm, options) {
alert('发送前');
return true;
}
function showError(data) {
alert('error');
}
function showResponse(data, status) {
alert('发送后');
}
var options = {
dataType: 'json',
beforeSubmit: showRequest,
error:showError,
success: showResponse
};
$('#myform').ajaxForm(options);
});
function showRequest(formData, jqForm, options) {
alert('发送前');
return true;
}
function showError(data) {
alert('error');
}
function showResponse(data, status) {
alert('发送后');
}
做完这些,应该就能读取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");
}
{
return Content("<textarea>{error: 'file size is zero'}</textarea>", "text/html");
}
修改完成后,依然跳到showError,通过搜索引擎再没搜索到有用的信息,不得不调试jquery.form.js
搜索textarea,很容易找到了合适的断点
代码
try{
if (opts.dataType == 'json' || opts.dataType == 'script') {
// see if user embedded response in textarea
var ta = doc.getElementsByTagName('textarea')[0];
if (ta)
xhr.responseText = ta.value;
else {
// account for browsers injecting pre around json response
var pre = doc.getElementsByTagName('pre')[0];
if (pre)
xhr.responseText = pre.innerHTML;
}
}
else if (opts.dataType == 'xml' && !xhr.responseXML && xhr.responseText != null) {
xhr.responseXML = toXml(xhr.responseText);
}
data = $.httpData(xhr, opts.dataType); //这里报错
}
catch(e){
log('error caught:',e);
ok = false;
xhr.error = e;
$.handleError(opts, xhr, 'error', e);
}
if (opts.dataType == 'json' || opts.dataType == 'script') {
// see if user embedded response in textarea
var ta = doc.getElementsByTagName('textarea')[0];
if (ta)
xhr.responseText = ta.value;
else {
// account for browsers injecting pre around json response
var pre = doc.getElementsByTagName('pre')[0];
if (pre)
xhr.responseText = pre.innerHTML;
}
}
else if (opts.dataType == 'xml' && !xhr.responseXML && xhr.responseText != null) {
xhr.responseXML = toXml(xhr.responseText);
}
data = $.httpData(xhr, opts.dataType); //这里报错
}
catch(e){
log('error caught:',e);
ok = false;
xhr.error = e;
$.handleError(opts, xhr, 'error', e);
}
catch到的信息是“Invalid JSON”。原来从jquery1.4开始,键和值都必须使用两个引号包围,改为以下内容之后解决
return Content("<textarea>{'error': 'file size is zero'}</textarea>", "text/html");
在这个问题上,耗费了一整天的时间,记录下来整个过程,希望其他人能用上