Background
I have a secured folder containing secret report files (in pdf format). Each file corresponds to a single user.
My site is developed using Asp.net MVC 3 Razor.
When a user navigate to http://mydomain.com/UserProfile/Report, it invokes the GET-handling action method Report and return a view with a submit button Download Report.
When the user click the button, it invokes the POST-handling action method. Verification will be done in this action method. When the verification is successfully passed, the action method returns the requested file.
Question
Could you give me an example how to implement the POST-handling action method?
Here is the skeleton:
[HttpPost]
public ActionResult Report(/*any parameter I don't know*/)
{
if(!IsAuthenticated())
return RedirectToActionLink("SomeActionMethod","SomeController");
else
{
// what should I do here?
// Asssume my secret folder is d:\mydomain.com\secret and the public folder is d:\mydomain.com\httpdoc
}
}
Here is how you can return a file back to the client:
public FileContentResult Report(/*any parameter I don't know*/)
{
if(!IsAuthenticated())
return RedirectToActionLink("SomeActionMethod","SomeController");
else
{
// Read the file from your location into a byte array named content
Response.ContentType = "application/pdf";
return new FileContentResult(content, "application/pdf");
}
}
You can use the File method to return a FileContentResult
[HttpPost]
public FileContentResult Report()
{
if(!IsAuthenticated())
return RedirectToActionLink("SomeActionMethod","SomeController");
else
{
string path = #"d:\mydomain.com\secret\" + fileName;
return File(path, "application/pdf"); ////
}
}
Related
I'm trying to connect an object from one View to another. I have a user action history where I have all of my CRUD operations listed. I'm trying to add an action link that when I go to my action history the name of the object that was created/updated/deleted(soft delete), becomes a link that will redirect me to the Edit view of that object. I tried via. #Html.ActionLink like this:
#Html.ActionLink(item.PreduzvePibfkNavigation.NazivPreduzeca, "IzmenaPreduzeca","Preduzece", new {Id = item.PreduzvePibfk}, null)
This is my controller for the 'IzmenaPreduzeca' action:
[HttpGet]
public IActionResult IzmenaPreduzeca(int id)
{
Preduzece preduzece = _preduzece.getById(id);
ViewBag.izabrani = preduzece.NazivPreduzeca;
return View(preduzece);
}
[HttpPost]
public IActionResult IzmenaPreduzeca(Preduzece preduzece, IstorijaPromena istorijaPromena, string razlog)
{
try
{
_preduzece.Update(preduzece);
_preduzece.IstorijaPromene(preduzece, istorijaPromena, CrudType.Update, DateTime.Now, "Branislav Zivanovic", razlog);
_preduzece.SaveToDb();
return RedirectToAction("PregledPreduzeca");
}
catch (Exception ex)
{
return NotFound($"Error, details: {ex.Message}");
}
}
I don't understand why do I get this error
Object reference not set to an instance of an object
Is there another way?
This is the user action history:
Image of the user action history
input parameter id is always 0, fix the action header
[HttpGet("{id}")]
public IActionResult IzmenaPreduzeca(int id)
Here is the controller.
I need to upload a image to AWS S3 but I'm get a error . I'm using the MVC project for asp application.
[HttpPost, ValidateInput(false)]
[ValidateAntiForgeryToken]
public ActionResult Nueva(Historia historia, HttpPostedFileBase HeroImagen)
{
try
{
if (ModelState.IsValid)
{
IAmazonS3 client;
using (client = Amazon.AWSClientFactory.CreateAmazonS3Client(_awsAccessKey, _awsSecretKey))
{
var request = new PutObjectRequest()
{
BucketName = _bucketName,
CannedACL = S3CannedACL.PublicRead,
Key = string.Format("UPLOADS/{0}", HeroImagen.FileName),
InputStream = HeroImagen.InputStream
};
client.PutObject(request);
}
historia.HeroImagen = HeroImagen.FileName;
db.Historias.Add(historia);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.AutorID = new SelectList(db.Autores, "AutorID", "AutorNombre", historia.AutorID);
return View(historia);
}
catch (Exception)
{
return View();
}
}
But, when I submit the form get an error.
.
For me it look like your AWS related code is not even running.
You get an error based on the line "Viewbag.AutorID = ...", which means, the redirect command above it was never running. For me it looks like your ModelState is invalid.
Note: Please copy your code and exception to your question as text, that would make your question searchable.
I am using Rotativa to turn a Razor view into a PDF.
The PDF file is not downloading.
I can see it in Fiddler but the browser is not prompting for download - I have tried this with both IE and Chrome.
I also tried to download the file to a physical path using the solution in this question here. but that didn't work either because of the system couldn't access the folder (Access Denied).
Here is my code:
public ActionResult Index()
{
var model = new CustomerDashboardVM();
return View("Index", model);
}
public ActionResult print(int voucherID)
{
var pdf = new ActionAsPdf("Index", new { voucherID}) { FileName = "testInvoice.pdf", PageSize = Rotativa.Options.Size.A4};
// RotativaHelper.SaveHttpResponseAsFile("http://localhost:65425/BlankDashboard", Server.MapPath("~\\PdfDownloads"));
return pdf;
}
I wonder why is this happening - I click the button, it calls the print ActionResult method - no error messages (I wrapped this in a try and catch block). I have tried this on a colleague PC and it was the same issue!
Many thanks.
The issue was that I was calling the ActionResult print() method on a button click event through an Ajax post. This apparently doesn't work.
It should work if you replace the button with a link, which has the print() mehtod in its URL; i.e., just the way mvc links work..
Okay, i got your mistake. You have not passed parameter name voucherID in Index method.
So now your code look like this:
public ActionResult Index(int voucherID) // Here you have to pass parameter
{
var model = new CustomerDashboardVM(voucherID);
return View("Index", model);
}
and Print() method look like this -
public ActionResult Print(int voucherID)
{
return new ActionAsPdf(
"Index",
new { voucherID = voucherID })
{
FileName = "testInvoice.pdf",
PageSize = Rotativa.Options.Size.A4
};
}
I'm working on an ASP.NET MVC4 web app, and I have a controller method for handling a GET request with an id in the URL, like so ...
[PortalAuthorization]
public ActionResult View(int id)
{
// get the individual ftp log
PortalFTPLog log = PortalFTPLogs.Get(id);
if (log == null)
{
TempData["Error"] = "The provided ftp log id does not exist.";
return RedirectToAction("Index");
}
// get the available matters to tie uploads to
ViewBag.matters = PortalMatters.Get();
return View(log);
}
In my view for this controller method, I have a form so that they can update it, that I want to POST back to the same URL. A URL like foo.com\items\1. Thats what the function above handles.
How do I make a function that handles a POST request for a function that requires a parameter, though? IN previous POST handlers I create a FormsCollection param, but when I add it to the param list for this function, the id param is null.
[HttpPost]
[PortalAuthorization]
public ActionResult View(FormCollection collection, int id)
{
PortalFTPLog log = PortalFTPLogs.Get(id);
if (log == null)
{
TempData["Error"] = "The provided ftp log id does not exist.";
return RedirectToAction("Index");
}
// update the matter id and save to database
log.Matter = Convert.ToInt32(collection.Get("matter"));
log.Save();
TempData["Notice"] = "The FTP log meta data has been updated.";
return RedirectToAction("View", new { id = id });
}
You need to provide RouteValues in Html.BeginForm on your View:
#using (Html.BeginForm(new {id = someIntIdValue}))
{
// Your form code
}
public class Sampleontroller:apicontroller
{
public void PostBodyMethod() {
HttpRequestMessage request=this.request;
//How to read the multi part data in the method
}
}
I am sending a multi part data to webapi controller.
How to read the contents in the method?
An 'async' example:
public async Task<HttpResponseMessage> PostSurveys()
{
// Verify that this is an HTML Form file upload request
if (!Request.Content.IsMimeMultipartContent("form-data"))
{
return Request.CreateResponse(HttpStatusCode.BadRequest);
}
//Destination folder
string uploadFolder = "mydestinationfolder";
// Create a stream provider for setting up output streams that saves the output under -uploadFolder-
// If you want full control over how the stream is saved then derive from MultipartFormDataStreamProvider and override what you need.
MultipartFormDataStreamProvider streamProvider = new MultipartFormDataStreamProvider(uploadFolder );
MultipartFileStreamProvider multipartFileStreamProvider = await Request.Content.ReadAsMultipartAsync(streamProvider);
// Get the file names.
foreach (MultipartFileData file in streamProvider.FileData)
{
//Do something awesome with the files..
}
}
Have a look at the article by Mike Wasson:
http://www.asp.net/web-api/overview/working-with-http/sending-html-form-data,-part-2
Or if you are doing file uploads, here: www.strathweb.com/2012/08/a-guide-to-asynchronous-file-uploads-in-asp-net-web-api-rtm/