Unable to save my image in a folder using ASP.NET MVC - asp.net

I have tried this code but I'm unable to save the image/file in the specified folder. What is wrong with the code?
Controller:
public ActionResult Work(Work workmodel, HttpPostedFileBase workpostpath)
{
if (workpostpath != null)
{
// Upload your service images
using (entities = new saabinteriormodel())
{
string workpic = System.IO.Path.GetFileName(workpostpath.FileName);
string workpath = System.IO.Path.Combine(Server.MapPath("~/Content/Images/work/"), workpic);
workpostpath.SaveAs(workpath);
Work work = new Work
{
work_image = "~/Content/Images/work/" + workpic};
workmodel.work_image = work.work_image;
entities.Works.Add(work);
entities.SaveChanges();
}
}
return View();
}
}
View:
#using (Html.BeginForm ("Work", "Admin", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<input id="uploadimage" type="file" />
#ViewBag.Message
<input id="work" type="submit" value="Save Work"/>
}
Thank you.

you're creating a new record in db, but not saving posted files anywhere. try
workpostpath.SaveAs(Server.MapPath("~/folder/file.extension"));
Alsou you could retrieve the posted files from request
HttpPostedFileBase file = Request.Files[0];

Related

How can I download a PDF file from a path or folder using asp.net

Good afternoon, I have an asp.net project and I would like that through an asp.net c # form a patient can download a certificate from a path or folder through their identification number or code, the folder it contains contains pdf and are organized by ID number
Thank you
Due to your vague description, I am not sure if you are an mvc project
or a core project.
The following is a case of downloading pdf in each project, please refer to:
In mvc:
public ActionResult DownLoad()
{
return View();
}
[HttpPost]
public ActionResult DownLoad(string id)
{
//PdfFiles is the name of the folder where these pdf files are located
var path = Server.MapPath("~/PdfFiles/pdf" + id + ".pdf");
var memory = new MemoryStream();
using (var stream = new FileStream(path, FileMode.Open))
{
stream.CopyToAsync(memory);
}
memory.Position = 0;
return File(memory, "application/pdf", Path.GetFileName(path));
}
View:
<form method="post" action="DownLoad">
Pdf Id: <input id="Text1" type="text" name="id" />
<input id="Submit1" type="submit" value="submit" />
</form>
Here is the test result:
In Core:
public IActionResult DownLoad()
{
return View();
}
[HttpPost]
public async Task<IActionResult> DownLoad(string id)
{
//here i put the PdfFiles folder in the wwwroot folder
var path = Path.Combine(
Directory.GetCurrentDirectory(),
"wwwroot", "PdfFiles/pdf" + id + ".pdf");
var memory = new MemoryStream();
using (var stream = new FileStream(path, FileMode.Open))
{
await stream.CopyToAsync(memory);
}
memory.Position = 0;
return File(memory, "application/pdf", Path.GetFileName(path));
}
View:
<form asp-action="DownLoad" method="post">
Pdf Id: <input id="Text1" type="text" name="id"/>
<input id="Submit1" type="submit" value="submit" />
</form>
Here is the test result:

how can i save more than one image in the database?

I just want to save the route of the images in the database.
So i try this.
And i get this error System.NullReferenceException: Object reference not set to an instance of an object.
This is my Controller
public ActionResult SaveImages(IEnumerable<HttpPostedFileBase> img, Imagenes images)
{
foreach (var n in img)
{
var PhotoUrl = Server.MapPath("/images" + n.FileName);
if (n != null && n.ContentLength > 0)
n.SaveAs(PhotoUrl);
images.imgUrl = "/images" + n.FileName;
db.Imagenes.Add(images);
db.SaveChanges();
}
return View("Index");
}
This is my model class
public partial class Imagenes
{
public int id { get; set; }
[StringLength(200)]
public string imgUrl { get; set; }
}
my View
#{
ViewBag.Title = "Home Page";}
#using (Html.BeginForm("SaveImages", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div>
<input type="file" name="img" id="img" multiple />
<input type="submit" name="submit" value="Save"/>
</div>}
The error you are getting is nothing about the image saving part, but I'm assuming it's the use of your images property...
As you didn't specify where that property comes from, MVC automatically assumes that's a POST Variable, and in your HTML, you have nothing of sorts...
change your action code to:
public ActionResult SaveImages(IEnumerable<HttpPostedFileBase> img)
{
const string folderToUpload = "/images";
foreach (var n in img)
{
var imageToUpload = folderToUpload + n.FileName;
var photoUrl = Server.MapPath(imageToUpload);
if (n != null && n.ContentLength > 0) {
n.SaveAs(photoUrl); // save to folder
var images = new Imagenes {
imgUrl = imageToUpload
};
db.Imagenes.Add(images); // add to repository
db.SaveChanges(); // save repositorychanges
}
}
return redirectToAction("Index");
}
I'm also assuming that db was already injected in your constructor, and it's not NULL
Code edited:
create a constant variable to have the folder to upload, so you don't repeat that code over and over
create a variable to hold the full path of the image, so you don't repeat that code over and over (remember: DRY - Don't Repeat Yourself)
save to database only if the file was saved
create a new variable to hold your object to be saved
redirect to the action using redirectToAction as you might have some calls in your Index and only redirecting to the View would give you an error
to be persistence, change the PhotoUrl to photoUrl (local variables = start with lowercase)

MVC 5 - two separate models on a page, how do I attach one to a form so I can submit it?

TL;DR: How do I handle form data that is being submitted with nonstandard names for the data?
The stats:
MVC 5
ASP.NET 4.5.2
I am bringing in two different models:
public async Task<ActionResult> Index() {
var prospectingId = new Guid(User.GetClaimValue("CWD-Prospect"));
var cycleId = new Guid(User.GetClaimValue("CWD-Cycle"));
var viewModel = new OnboardingViewModel();
viewModel.Prospecting = await db.Prospecting.FindAsync(prospectingId);
viewModel.Cycle = await db.Cycle.FindAsync(cycleId);
return View(viewModel);
}
One called Prospecting, the other called Cycle. The Prospecting one is working just fine, as nothing else on the page needs it except one small item.
The Cycle has a mess of separate forms on the page, each needing to be separately submittable, and editing just one small part of the Cycle table. My problem is, I don't know how to submit the correct data to the backend. I am also not entirely sure how to "catch" that data.
The bright spot is that apparently the front end is properly reflective of what is in the db. As in, if I manually change the db field to a true value, the checkbox ends up being selected on refresh.
My current form is such:
#using(Html.BeginForm("UpdatePDFResourceRequest", "Onboarding", FormMethod.Post, new { enctype = "multipart/form-data" })) {
#Html.AntiForgeryToken()
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<fieldset>
#Html.LabelFor(Model => Model.Cycle.PDFResourceLibrary, htmlAttributes: new { #class = "control-label" })
#Html.CheckBoxFor(Model => Model.Cycle.PDFResourceLibrary, new { #class = "form-control" })
#Html.ValidationMessageFor(Model => Model.Cycle.PdfResourceLibrary, "", new { #class = "text-danger" })
<label class="control-label"> </label><button type="submit" value="Save" title="Save" class="btn btn-primary glyphicon glyphicon-floppy-disk"></button>
</fieldset>
}
But the resulting HTML is such:
<input id="Cycle_PDFResourceLibrary" class="form-control" type="checkbox" value="true" name="Cycle.PDFResourceLibrary" data-val-required="'P D F Resource Library' must not be empty." data-val="true">
As you can see, the name= is Cycle.PDFResourceLibrary and I don't know how to catch this on the backend.
My model for that specific form is:
public class PDFResourceRequestViewModel {
[DisplayName("PDF Resource Library Request")]
public bool PDFResourceLibrary { get; set; }
[DisplayName("Date Requested")]
[DataType(DataType.Date)]
public DateTime PDFResourceLibraryDate { get; set; }
[DisplayName("Notes")]
public string PDFResourceLibraryNotes { get; set; }
}
(not the overall model for that table, though)
And the method used to handle the form submission is:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> UpdatePDFResourceRequest(PDFResourceRequestViewModel model) {
var id = new Guid(User.GetClaimValue("CWD-Cycle"));
Cycle cycle = await db.Cycle.FindAsync(id);
if(cycle == null) {
return HttpNotFound();
}
try {
cycle.CycleId = id;
cycle.PDFResourceLibrary = model.PDFResourceLibrary;
cycle.PDFResourceLibraryDate = DateTime.Now;
cycle.PDFResourceLibraryNotes = model.PDFResourceLibraryNotes;
db.Cycle.Add(cycle);
await db.SaveChangesAsync();
return RedirectToAction("Index");
} catch { }
return View(model);
}
Now, I know that the method is wrong, for one I am editing just three values out of dozens in that table, so I need to be using something like this method. Problem is, the form is getting submitted with the name= of Cycle.PDFResourceLibrary and it is not being matched up on the back end.
Help?
You can use the [Bind(Prefix="Cycle")] attribute to 'strip' the prefix so that name="Cycle.PDFResourceLibrary" effectively becomes name="PDFResourceLibrary" and will bind to your PDFResourceRequestViewModel
public async Task<ActionResult> UpdatePDFResourceRequest([Bind(Prefix="Cycle")]PDFResourceRequestViewModel model)

Asp.NET temporary file saving

I got a path from the jquery code URL.createObjectURL(event.target.files[0]);
It returns something like this : blob:http%3A/localhost%3A59105/f7dae0f7-088f-48cf-b446-eeda0bf23705
I tried to save this file like
byte[] data;
using (WebClient client = new WebClient())
{
data = client.DownloadData("blob:http%3A/localhost%3A59105/f7dae0f7-088f-48cf-b446-eeda0bf23705");
}
File.WriteAllBytes(#"~/a.jpg", data);
But it gives an error about the code above:
The URI prefix is not recognized.
How exactly I can copy this file?
Thanks for your suggestions.
1.Create simple GET method
[HttpGet]
public ActionResult GetFile(){
return View();
}
2. Create View with #Html.BeginForm helper
#using (Html.BeginForm("GetFile","YourController", FormMethod.Post, { enctype = "multipart/form-data" }))
{
<input type="file" id="fileup" name="file"/>
<input type="submit" value="Send">
}
Rembember to use name attribute and overloaded version of Html.BeginForm()
3.Get data in Backend
[HttpPost]
public ActionResult GetFile(HttpPostedFileBase file)
{
if (file != null && file.ContentLength > 0)
{
var fileName = Path.GetFileName(file.FileName);
var filePath = Path.Combine(Server.MapPath("~/Temp/"), fileName);
file.SaveAs(path);
}
return RedirectToAction("Success");
}
Name in html attribute must have same name as HttpPostedFileBase.

How to upload file with web-api

Client side code:
<form action="api/MyAPI" method="post" enctype="multipart/form-data">
<label for="somefile">File</label> <input name="somefile" type="file" />
<input type="submit" value="Submit" />
</form>
And how to process upload file with mvc web-api,have some sample code?
HTML Code:
<form action="api/MyAPI" method="post" enctype="multipart/form-data">
<label for="somefile">File</label>
<input name="somefile" type="file" />
<input type="submit" value="Submit" />
</form>
Controller
// POST api/MyAPI
public HttpResponseMessage Post()
{
HttpResponseMessage result = null;
var httpRequest = HttpContext.Current.Request;
if (httpRequest.Files.AllKeys[0] == "image")
{
if (httpRequest.Files.Count > 0)
{
var docfiles = new List<string>();
foreach (string file in httpRequest.Files)
{
var postedFile = httpRequest.Files[file];
var filePath = HttpContext.Current.Server.MapPath("~/Images/" + postedFile.FileName);
postedFile.SaveAs(filePath);
docfiles.Add(filePath);
}
result = Request.CreateResponse(HttpStatusCode.Created, docfiles);
}
}
else
{
result = Request.CreateResponse(HttpStatusCode.BadRequest);
}
return result;
}
try below link
this link use for me hopefully it will work you
http://www.asp.net/web-api/overview/advanced/sending-html-form-data,-part-2
You can use ApiMultipartFormFormmatter to upload file to web api 2.
By using this library, you can define a view model to get parameters submitted from client-side. Such as:
public class UploadFileViewModel
{
public HttpFile Somefile{get;set;}
}
And use it in your Api controller like this:
public IHttpActionResult Upload(UploadFileViewModel info)
{
if (info == null)
{
info = new UploadFileViewModel();
Validate(info);
}
if (!ModelState.IsValid)
return BadRequest(ModelState);
return Ok();
}
Nested objects can be parsed by this library.

Resources