【问题标题】:MVC3 (Razor) How to do something with json passed data in ControllerMVC3(Razor)如何在Controller中使用json传递的数据做一些事情
【发布时间】:2012-06-06 10:29:32
【问题描述】:

我已使用以下 jQuery Ajax 代码将视图中的模型传递给控制器​​:

$.ajax({
        data: model,
        type: "POST",
        url: '@Url.Action("createDoc")',
        datatype: "json",
        contentType: "application/json; charset=utf-8",
        success: function (result) {
            alert('Done '+ result.toString());
        }
    });

问题是:在Controller方法“createDoc”中

[HttpPost]
    public ActionResult createDoc(IEnumerable<Movie> movies)
    {
        CreateWordprocessingDocument(movies);
        return Json(new { result = movies.Count()});
    }

我无法对电影 Enumerable 数据做任何事情。 调用 CreateWordProcessingDocument 创建一个包含电影数据的文档。但事实并非如此。 这是方法代码:

public void CreateWordprocessingDocument(IEnumerable<Movie> movies)
{
    HttpContextWrapper context = new HttpContextWrapper(System.Web.HttpContext.Current);
    context.Response.Clear();
    context.Response.Buffer = true;
    context.Response.AddHeader("content-disposition", "attachment;filename=example.doc");
    context.Response.ContentType = "application/vnd.ms-word.document";
    context.Response.Charset = "";
    StringBuilder sb = new StringBuilder();
    sb.AppendLine("<p  align='Center'><b> GENERAL TITLE</b></p>");
    sb.Append("<br>"+movies.Count());
    for (int i = 0; i < movies.Count(); i++) {
        sb.Append("<br>Title:" + movies.ElementAt(i).Title +"");
    }
    context.Response.Output.Write(sb.ToString());
    context.Response.Flush();
    context.Response.End();
}

但它不起作用:它返回到 ajax 帖子并弹出“完成”警报,result.tostring() 显示我在 createWordProcessingDocument 方法上创建的 HTML 代码。 我怎样才能避免这种行为,以便我可以对从视图传递给控制器​​的数据做一些事情? 谢谢。

【问题讨论】:

  • 电影 Enumerable 是否为空,或者究竟是什么问题?
  • 你想改什么?
  • @mfusseneggerthe movies Enumerable 不是空的:它实际上拥有我想要的所有数据。我的问题是,在 createDoc(和 CreateWordProcessingDocument)中,我无法像以前那样创建以前的文档并询问用户他想在哪里保存文件(或打开它)。

标签: asp.net-mvc json razor


【解决方案1】:

ASP.net MVC 包含一个 FileResult 以便将具有 mime 类型的文件返回给浏览器。

改为这样做:

public ActionResult  createDoc(IEnumerable<Movie> movies)
{
    byte[] fileContents = CreateFileFromMovies(movies);

    return File(fileContents, "application/vnd.ms-word.document");
}

不要直接访问响应,而是将文档创建为字节数组并使用File() 方法返回内容。

【讨论】:

  • 抱歉,好像没用。它不允许我打开一个对话框窗口来打开/保存文件,它仍然会弹出 result.toString() 语句生成的 HTML 代码。
【解决方案2】:

问题已解决:我在此处发布解决方案,如果它可以帮助解决我的问题。 在我的 createDoc 方法中,我使用所需数据创建字符串,然后将它们放入 tempData 属性中。这就是 createDoc 的样子:

[HttpPost]
    public void createDoc(IEnumerable<Movie> movies)
    {
        String mov="";
        mov = mov + "<br>" + movies.Count();
        for (int i = 0; i < movies.Count(); i++)
        {
           mov=mov+"<br>Title:" + movies.ElementAt(i).Title + "";
        }
        TempData["movies"] = mov;
    }

然后“控制”返回到Ajax的post方法,在它的最后我放这个:

success: function (result) {
            window.location.href = '@Url.Action("CreateWordprocessingDocument","Movies")'
        }

所以我的 Ajax 帖子完整代码是:

<script type="text/javascript">
function postData() {
    var urlact = '@Url.Action("createDoc")';
    var model = '@Html.Raw(Json.Encode(Model))';

    alert(model);
    alert(JSON.stringify(model));

    $.ajax({
        data: model,
        type: "POST",
        url: urlact,
        datatype: "json",
        contentType: "application/json; charset=utf-8",
        success: function (result) {
            window.location.href = '@Url.Action("CreateWordprocessingDocument","Movies")'
        }
    });
}
</script>

现在“控件”被重定向到 CreateWordProcessingDocument 操作,我实际上是在其中创建文档:

public void CreateWordprocessingDocument()
    {
        string movies = TempData["movies"] as string;
        context.Response.Clear();
        context.Response.Buffer = true;
        context.Response.AddHeader("content-disposition", "attachment;filename=example.doc");
        context.Response.ContentType = "application/vnd.ms-word.document";
        context.Response.Charset = "";
        StringBuilder sb = new StringBuilder();
        sb.AppendLine("<p  align='Center'><b>TITLE</b></p>");
        sb.Append(movies);
        context.Response.Output.Write(sb.ToString());
        context.Response.Flush();
        context.Response.End();
    }

就是这样。谢谢大家的帮助,希望我能帮助别人解决这个问题。

【讨论】:

  • 恭喜修复!如果可以,请确保将您的答案标记为“已接受”,以便其他人能够从您的成功中学习。干杯~
【解决方案3】:

之所以获得在 CreateWordprocessingDocument 中创建的 HTML 代码,是因为它是您直接输出到 HTTP 响应的内容。然后您结束了响应。基本上,您通过自己直接编写响应绕过了很多 ASP.NET MVC。

【讨论】:

  • 那么,我怎样才能绕过这个问题并创建一个文档文件(格式如 CreateWordProcessingDocument 所示)并询问用户是否要打开/保存它?
  • 现在,有趣的是我尝试了@Dismissile 解决方案(没有用),即使我不再使用 HTTP 响应,我仍然在弹出警报中拥有 HTML 代码。
猜你喜欢
  • 2012-06-08
  • 1970-01-01
  • 2018-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-11
  • 1970-01-01
  • 2014-12-02
相关资源
最近更新 更多