ASP.NET MVC - conditionally open PDF / image in new tab
Here I have a filtering report page where I can filter some information for the report (RDLC, returning a PDF or image file). Today this page returns files always in a new tab because I use this:
@using (Html.BeginForm("Report", "ReportController", FormMethod.Post, new { target = "_blank" }))
and my ReportController returns a FileContentResult like below:
return File(renderedBytes, mimeType, fileName + "." + fileNameExtension);
However, this page has some server side validation and the postback always happens on the newly created tab and not the original where the submit button was clicked. Is there a way to return a new page (target = "_blank", generated PDF or image) only if the ModelState has no errors? I want to use the report filtering page if there are errors.
Thanks in advance.
source to share
You can split report generation into two separate steps.
1. Extend your view model with new Target, Action properties (this will help you dynamically change form attributes).
[HttpGet]
function ActionResult Report()
{
var model = new ReportViewModel{ Target = "_self", DownloadFile = false, Action = "Report" };
return View(model);
}
2.Inject 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 the second form submission for 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. Submitting the second form:
[HttpPost]
function ActionResult DownloadReport(ReportViewModel model)
{
// generate file
return File(renderedBytes, mimeType, fileName + "." + fileNameExtension);
}
source to share