Ajax 将 JSON 数据发布到 MVC 收到错误意外令牌 P

本文关键字:错误 意外 令牌 MVC Ajax JSON 数据 | 更新日期: 2024-11-08 09:15:19

这让我发疯了。我有一个页面,我需要向控制器发布 JSON 帖子,它将处理它并返回一个 excel 文件以供下载。 到目前为止,它似乎运行正常,但是当它返回到ajax调用时,我收到解析器错误和消息"意外令牌P"。 我已经尝试了许多不同的配置和调用方法(标准MVC ActionRequest to WebApi帖子),但没有一个改变。 这是我正在运行的代码。

JavaScript:

       var treatmentplan = {"PlanRecordStatusId":"1","PlanRecordDateBegin":"","PlanRecordDateEnd":"","ClientClaimNumber":"","PatientNumber":0,"requestAction":3};
        $.ajax({
            //global: true,
            //url: '/home/ExcelRpt',
            url: '/api/TreatmentPlanExcel',
            type: 'POST',
            dataType: 'json',
            data: treatmentplan,
            //contentType: 'application/json; charset=utf-8',
            success: function (data) {
                //var msg = data.Message;
                //$('#results').html(msg);
                $("#tmpFrame").attr('src', 'URL-TO-EXCEL-FILE');
            }
            , error: function (jqXHR, exception, error) {
                if (jqXHR.status === 0) {
                    alert('Not connect.n Verify Network.');
                } else if (jqXHR.status == 404) {
                    alert('Requested page not found. [404]');
                } else if (jqXHR.status == 500) {
                    alert('Internal Server Error [500].');
                } else if (exception === 'parsererror') {
                    alert('Requested JSON parse failed.');
                } else if (exception === 'timeout') {
                    alert('Time out error.');
                } else if (exception === 'abort') {
                    alert('Ajax request aborted.');
                } else {
                    alert('Uncaught Error.n' + jqXHR.responseText);
                }
                $('#log').html(error.message);
            }
        });

这是 C# 代码(WebApi 和 MVC 控制器版本),我不打算包含我的 ToExcel 扩展,我知道这部分有效,只需在返回时下载即可。 它正在到达此代码,生成数据并返回。 我只需要看看到底发生了什么。 如果有首选的呼叫方式,请告诉我(WebApi 或 MVC)

C#

网页接口版本

    public HttpResponseMessage Post(TreatmentPlanRequest tpRequest) {
        tpRequest.Verify();
        List<TreatmentPlan> tpl = DataAccess.GetReportDap(tpRequest).ToList();
        HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
        var contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
        var package = tpl.ToExcel("TreatmentReport");
        var fileStream = new MemoryStream();
        package.SaveAs(fileStream);
        fileStream.Position = 0;
        result.Content = new StreamContent(fileStream);
        result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
        return result;
    }

这是MVC控制器版本

    [HttpPost]
    public ActionResult ExcelRpt(TreatmentPlanRequest tpRequest) {
        tpRequest.Verify();            
        List<TreatmentPlan> tpl = DataAccess.GetReportDap(tpRequest).ToList();
        var contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
        var package = tpl.ToExcel("TreatmentReport");
        var fileStream = new MemoryStream();
        package.SaveAs(fileStream);
        fileStream.Position = 0;
        var fsr = new FileStreamResult(fileStream, contentType);
        fsr.FileDownloadName = "TreatmentReport";
        return fsr;

    }

从这里开始,我不知道为什么这不起作用。 我已经在谷歌上搜索了如何在MVC中做到这一点(我曾经使用网络表单来做到这一点,从来没有遇到过问题)。 我猜我的问题在退货或

Ajax 将 JSON 数据发布到 MVC 收到错误意外令牌 P

更改 Success 方法以使用 URL 打开一个新窗口,而不是在当前窗口中设置框架。

所以这个:

$("#tmpFrame").attr('src', 'URL-TO-EXCEL-FILE');

成为:

window.open('URL-TO-EXCEL-FILE');

在绝大多数情况下,这应该完全符合您的要求。 有时,根据特定的浏览器设置,用户可能会收到"弹出窗口已阻止"消息,但在我使用过的应用程序中,这种情况很少发生。

编辑:

在进一步澄清之后,还有第二个问题。 从服务器返回的数据必须与 .ajax() 方法期望的格式相同,在本例中为"JSON"。 尝试返回一个 JSON 对象,而不是从您的操作返回 FileStreamResult ,该对象具有生成 Excel 文件所需的 URL。

return Json(new { URL = 'URL-TO-EXCEL-FILE' });

然后,按照我原始回复中的建议进行操作。

我要

感谢Kris Hatcher对此的解决方案。 他建议制定两个行动结果。 从初始请求的参数生成查询字符串。 它返回一个包含参数的完整 URL。 然后,它使用返回的 url 执行 Window.Open()。

在我找到的所有例子中,这是唯一一个对我有用的例子。 以下是代码的工作原理。

JavaScript:

function TestWebApiReport() {
    var reportData = GetReport();
    $.ajax({
        url: '/home/ExcelResults'
        , data: reportData
        , type: 'POST'
        , dataType: 'json'
        , success: function (data) {
            window.open(data.URL);
        }, error: function (jqXHR, exception, error) {
            alert("GRRRRRR!!!")
        }
    });
}

它创建 JSON 数据,然后将其发布到 JsonResult。 下面是控制器代码。

C#

    [HttpPost]
    public JsonResult ExcelResults(ReportRequest tpRequest) {
        StringBuilder sb = new StringBuilder();
        bool firstIn = true;
        sb.AppendFormat("{0}/Home/ExcelRpt", Request.Url.Scheme + "://" + Request.Url.Authority);
        foreach (var prop in tpRequest.GetType().GetProperties()) {
            if (prop.GetValue(tpRequest, null) != null) {
                if (firstIn) {
                    sb.AppendFormat("?");
                    firstIn = false;
                } else {
                    sb.AppendFormat("&");
                }
                sb.AppendFormat("{0}={1}", prop.Name, prop.GetValue(tpRequest, null));
            }
        }
        return Json(new { URL = sb.ToString() }); 
    }

回到 JavaScript,你会看到返回数据使用 URL 来执行 Window.Open()。 然后创建 excel 文件。 这是最后一个调用 (操作结果)。

    [HttpGet]
    public ActionResult ExcelRpt(ReportRequest tpRequest) {
        if (tpRequest.requestAction != RequestAction.Report) {
            throw new Exception("Did not use action request type of 'Report'.");
        }
        tpRequest.requestAction = RequestAction.Report;
        List<Report> tpl = DataAccess.GetReportDap(tpRequest).ToList();
        var contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
        var package = tpl.ToExcel("Report");
        var fileStream = new MemoryStream();
        package.SaveAs(fileStream);
        fileStream.Position = 0;
        var fsr = new FileStreamResult(fileStream, contentType);
        fsr.FileDownloadName = "TreatmentReport.xlsx";
        return fsr;
    }

报告请求是我有一个类,ToExcel(),我扩展了列表项。 现在这工作得很好。