MVC 3. VB.NET I have the following controller action in my application to send generated PDF files to the User by download. The function works fine when the controller itself has been invoked. But when I call to the function from outside the controller it returns a ” Object reference not set to an instance of an object ” error as soon as it hits the response.contenttype line. I have verified that all of the variables are in fact making it to the below action… But no dice if I try to call this in another controller:
Dim _print as new PrintController
_print.showUserPDF(firstName,lastName)
return RedirectToAction("Registrants")
the function in the PrintController that is throwing the error is:
Function showUserPDF(ByVal pdfName As String, ByVal fileName As String, ByVal _directory As String) As ActionResult
If Not String.IsNullOrEmpty(pdfName) Then
Response.ContentType = "application/pdf"
Response.AppendHeader("Content-Disposition", "attachment; filename=" + fileName)
Response.TransmitFile(pdfName)
Response.[End]()
Dim FileToDelete As String
FileToDelete = pdfName
If System.IO.File.Exists(FileToDelete) = True Then
System.IO.File.Delete(FileToDelete)
End If
Directory.Delete(_directory)
Return Nothing
End If
Return Nothing
End Function
any ideas why this is only working when called explicitly from inside its containing controller???
Clearly there is no Response object set on the method when called from another controller, nor should there be if (a) it’s not being created by the MVC framework or (b) you aren’t explicitly populating the HttpContext property via the ControllerContext. This is really the wrong way to go about both downloading content and sharing code between two controllers.
First, you should be using a FileResult, using the signature that takes a byte array since you might delete the file, to deliver a file as a download from a controller. The FileResult is explicitly designed to do this. You should not be writing directly to the Response from your controller as that violates the separation of concerns fundamental to MVC.
Second, to share the code you should abstract the code to a shared base controller from which both derive or a helper class, preferably the former. That way you will have the method available directly in the controller created by the framework and won’t need to instantiate another controller just to invoke the method.
Last, you can’t both deliver a file to download AND redirect in the same response. You might want to handle this client-side via javascript if this is required. Note the file download should leave you on the same page.
I apologize in advance for any syntax or other errors. I read VB better than I write it