4

Here I have a filtering report page, where I can filter some information for a report (RDLC, returning a PDF or Image file). Today, this page return files always on a fresh tab, because I'm using this:

@using (Html.BeginForm("Report", "ReportController", FormMethod.Post, new { target = "_blank" }))

and my ReportController returns a FileContentResult, as shown below:

return File(renderedBytes, mimeType, fileName + "." + fileNameExtension);

However, this page have some server-side validation, and the postback occurs always on the freshly created tab, not on the original one where the submit button was clicked. Is there a way of returning a new page (target = "_blank", with generated PDF or Image) only if ModelState has no errors? I want to stick on the report filtering page if there are errors.

Thank you in advance.

cezarlamann
  • 1,465
  • 2
  • 28
  • 43

1 Answers1

2

You can split your report generation in two separated actions.

1.extend your view model with new properties Target, Action (this will help you to dinamicaly change your form attributes).

   [HttpGet]
    function ActionResult Report()
    {
       var model = new ReportViewModel{ Target = "_self", DownloadFile = false, Action = "Report" };    
       return View(model);
    }

2.Validate your model and set these properties to new values in case of valid model state

[HttpPost]
function ActionResult Report(ReportViewModel model)
{
   if (ModelState.IsValid)
   {
      model.DownloadFile = true;
      model.Action = "DownloadReport";
      model.Target = "_blank";
      return View(model);
   }
   else
   {
      // server side error occurred
      return View(model);
   }
}

3.Use jquery to automatically execute a second form submission to the new target action

@using (Html.BeginForm(Model.Action, "ReportController", FormMethod.Post, new { target = Model.Target, id = "MyForm" }))
{
     @Html.HiddenFor(m => m.Action);
     @Html.HiddenFor(m => m.Target);

     @if(Model.DownloadFile)
     {
        <script>$(document).ready(function () { $("#MyForm").submit(); }</script>
     }
     // other form elements
}

3.Handle second form submission:

[HttpPost]
function ActionResult DownloadReport(ReportViewModel model)
{
   // generate file
   return File(renderedBytes, mimeType, fileName + "." + fileNameExtension);
}
Marian Ban
  • 8,158
  • 1
  • 32
  • 45