在MVC HttpPost动作控制器中返回FilePathResult和ViewResult

时间:2015-01-02 07:40:29

标签: asp.net-mvc razor

View接受一些用户输入,并有一个“下载”按钮,允许用户下载根据输入的字段生成的xml。我还在模型中具有[Required]属性验证,该验证按预期显示错误消息

[Required(ErrorMessage="Provider is Required")]
string provider { get; set; }

当用户填写错过的必填字段并点击“下载”时,控制器将xml作为FilePathResult返回

[AcceptVerbs(HttpVerbs.Post)]
        [ValidateInput(false)]
        public ActionResult TestXMLCreator(TemplateModel model)
        {
        .
        .
        if (ModelState.IsValid)
            {
            .
            .
            System.IO.File.WriteAllText(Server.MapPath("~/Generated.xml"), testXml);
            return File(Server.MapPath("~/Generated.xml"), "text/plain", testXML.xml");
            }
        return View(model)

当ModelState处于有效状态且文件作为结果返回时,视图不会刷新,并且仍会显示旧的验证错误。如何返回FileResult并刷新View?

2 个答案:

答案 0 :(得分:1)

你不能在一次操作中完成这两件事。

您唯一能做的就是返回刷新的视图,包括生成文件的链接。用户只需要进行额外的点击即可下载该文件。

如果你想避免那次点击,你可以使用JavaScript来模拟它,例如,使用jQuery,就像this SO Q&A一样。

答案 1 :(得分:0)

当ModelState有效时,您可以使用jquery请求返回文件路径和下载文件。

[AcceptVerbs(HttpVerbs.Post)]
[ValidateInput(false)]
public ActionResult TestXMLCreator(TemplateModel model)
{
    .
    .
    if (ModelState.IsValid)
    {
        .
        .
        System.IO.File.WriteAllText(Server.MapPath("~/Generated.xml"), testXml);
        var filePath = Server.MapPath("file path");
        TempData["FilePath"] = filePath;
        return View();
    }

    return View(model)

并在视野中:

@if(TempData["FilePath"] != null)
{
   // When js disabled file can be downloaded via click
   <a href="@TempData["FilePath"]">Download now!</a>

   // File will be downloaded immediately when view rendered
   $(function() {
       window.location.href = $('a').attr('href'));
   });
}