This question already has answers here:
How to get full path of selected file on change of <input type=‘file’> using javascript, jquery-ajax?
(14 answers)
Closed 6 years ago.
I have the following razor code:
<div class="container">
#Html.ValidationSummary(false)
#using (Html.BeginForm("EncryptFile", "Encryption", new { returnUrl = Request.Url.AbsoluteUri }, FormMethod.Post, new { #id = "encryptionform", #class = "form-horizontal" }))
{
<div class="form-group">
#Html.Label("File", new { #class = "control-label col-md-2" })
<div class="col-md-10">
<input type="file" id="encryptfilefield" name="uploadedfile" enctype='multipart/form-data'/>
</div>
</div>
<button type="submit" id="encryptfilebutton">Encrypt</button>
<button id="decryptfilebutton" type="button">Decrypt</button>
<button id="reencryptfilebutton" type="button">Re-Encrypt</button>
}
</div>
and the following controller code gets called when I click the Encrypt button:
[HttpPost]
public ActionResult EncryptFile(string uploadedfile)
{
/*process the file without uploading*/
return Json(new { status = "success", message = "Encrypted!" });
}
I am able to hit this action when I click the encrypt button, but the uploadedfile string always comes in as null. How can I get the fill filepath of the file that was selected? Please note that I am not trying to upload it to the server (despite "uploaded" appearing in the name), I just need the filepath.
EDIT
I saw in IE 11 that the following showed the file path fully (the part inside the alert):
alert($("#encryptfilefield").val());
However this is not a full solution, and it seems there is no solution due to to it being a security issue.
Thank you.
Updated Answer
Unfortunately there's no way to get that info consistently among all browsers., there's multiple posts on here about this topic and the conclusion is browsers don't allow it for security purposes.
I did find that in IE 11 they do include the path within the input dom element .value property, but I don't know if that works in other versions, and it does not work in chrome.
$('input[type=file]').change(function () {
console.dir(this.value);
console.dir(this.files[0])
})
Unfortunately that's about the best you can expect. Here's a post that has a couple things you could do to possibly achieve some very specific scenarios.
How to get full path of selected file on change of <input type=‘file’> using javascript, jquery-ajax?
Original Answer (how to get file path "After" it reaches server)
The null param issue I'm thinking is because MVC binds on element name property.
<input type="file" id="encryptfilefield" name="uploadedfile" enctype='multipart/form-data'/>
and your controller action is marked as type string, which is not what your input type is.
you could either change that to this,
[HttpPost]
public ActionResult EncryptFile(HttpPostedFileBase uploadedfile)
{
or try grabbing the file straight from the Request object like below, you'd have to save it somewhere before you get the full path of it though, i don't believe you'll get the filepath of where it originated from, only after you save it.
[HttpPost]
public ActionResult EncryptFile(string uploadedfile)
{
HttpPostedFileBase myfile = Request.Files[0];
if (file.ContentLength > 0)
{
// extract only the fielname
var fileName = Path.GetFileName(file.FileName);
// store the file inside ~/App_Data/uploads folder
var path = Path.Combine(Server.MapPath("~/App_Data/uploads"),fileName);
file.SaveAs(path);
}
/*process the file without uploading*/
return Json(new { status = "success", message = "Encrypted!" });
}
Related
I have a button on my website where users can upload multiple files onto the site. For some reason, in my controller the "file" variable always gets the value of NULL. I am able to upload files as a user, but my controller doesn't read that in for some reason. I'm not sure why and any guidance to the right direction would be greatly appreciated !
This is my cshtml:
<p id="FileArea"></p>
<input id="Files" name="Files" type="file" multiple="multiple" />
This is my model:
public IEnumerable<HttpPostedFileBase> Files { get; set; }
This is my controller:
foreach (var file in viewModel.Candidate.Files)
{
var file_s = Path.GetFileName(file.FileName);
var path = Path.Combine(Server.MapPath("~/Files/location", file_s);
file_s.SaveAs(path);
}
I'm working on a ASP.NET MVC site that will allow a user to upload multiple images to a gallery. After a user uploads their images and before they are saved to the database, the user will have the ability to reorder the images using a jQuery drag and drop. The user can then submit their uploads. The user will also have the ability later on to edit their gallery and again have the ability to reshuffle the order of their images. I will not be saving the images to the database, just the filenames. I'm not sure how to best handle this. I'm thinking the POST controller will take a List<HttpPostedFileBase> parameter, and then convert to a byte [] array to maintain the image order. Then save the image names to the database as a comma separated string? What would the most efficient way to handle this be?
Alright so if we put drag and drop a side, see this as your view:
#using (Html.BeginForm("Index", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<input type="file" name="files" value="" multiple="multiple"/>
<input type="submit" value="Upload"/>
}
In your controller:
[HttpPost]
public ActionResult Index(HttpPostedFileBase[] files)
{
try
{
foreach (HttpPostedFileBase file in files)
{
string name = System.IO.Path.GetFileName(file.FileName);
file.SaveAs(Server.MapPath("~/Images/" + name));
string filename = "Images/" + name;
//Save the the filename to your database
}
}
catch
{
throw ex;
}
return View();
}
I've been looking for a long time for this but I'm still stuck, I need to have an upload control where the user can upload a document and give additional information.
I've had to do this before without the upload control so what I do is I get an ajax.beginform that will give all the input from the user to the controller and than close the popup trough a onsucces function, so this looks like this:
view:
#using (Ajax.BeginForm("Save", "Documents", new AjaxOptions { HttpMethod = "Post", OnSuccess = "CloseDialog" }, new { #class = "form-inline", id = "FormId" }))
{
#Html.Label("Description", "Description")
<div class="span3">
#Html.TextBoxFor(m => m.Description)
</div>
}
I tried adding there an Html.BeginForm but then I found out that it is not possible to use nested forms so I deleted this.
In my controller I have:
public PartialViewResult Index(string description)
{
var model = new DocumentsModel{ Description = description};
return PartialView(model);
}
[HttpPost]
public ActionResult UploadFile(HttpPostedFileBase file, string description)
{
if (file != null && file.ContentLength > 0)
{
var fileName = Path.GetFileName(file.FileName);
var path = Path.Combine(Server.MapPath(#"D:\Documentds\"), fileName);
file.SaveAs(path);
}
return RedirectToAction("Index", new { description = description });
}
Ofcourse because the html.beginform won't work this controlleraction won't work either
So my question is how to do this without having to use a html.beginform?
You need to have the file upload inside the form and also the enctype="multipart/form-data" property on the form that calls uploadfile. That could be one problem.
Also, you could use JavaScript to submit the form you want from another part of the page without having them nested and keeping your design.
Currently, I'm working on asp.net mobile website and I've to implement one functionality related to upload file in mobile website.
I'm using asp:upload Control but, It's not working in mobile website.
I have been searching in google for this issue since last week, But I can't find any relative source or blog.
Can anyone help me on this topic?
In view:
#using (Html.BeginForm("Index", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<input type="file" name="file" />
<input type="submit" value="OK" />
}
In Control:
[HttpPost]
public ActionResult Index(HttpPostedFileBase file)
{
// Verify that the user selected a file
if (file != null && file.ContentLength > 0)
{
// extract only the fielname
var fileName = Path.GetFileName(file.FileName);
// store the file inside ~/App_Data/uploads folder
var path = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName);
file.SaveAs(path);
}
// redirect back to the index action to show the form once again
return RedirectToAction("Index");
}
and remove the jquerymobile script from your page. Like in MVC4
#Scripts.Render("~/bundles/jquery", "~/bundles/jquerymobile")
Remove this line, it's the source of the conflict.
I am getting red x mark instead of the picture when storing in database. I believe I am having problems in the Views files. Please could someone have a look at this and tell me how to correct it. If I have wrong URL Actions please tell me which ones I should be using. Thanks in advance.
SubCategory2 Table has the following columns...
Column field > Picture1 : Data Type > varbinary(MAX)
Column field > ImageMimeType : Data Type > varchar(50)
Index.cshtml file
#foreach (var item in Model) {
<td>
<img src="#Url.Action("GetImage", "SubProductCategory2",
new { id = item.SubProductCategoryID})" alt="" height="100" width="100" />
</td>
Edit.cshtml file
"Edit" is the method in the contoller. "ProductCategoryL2" is the method in the controller. "GetImage" is the method in controller. All these methods are in the same controller file called ProductCategoryControllerL2
#using (Html.BeginForm("Edit", "ProductCategoryL2", "GetImage",
FormMethod.Post, new { #encType = "multipart/form-data" }))
{
<div class="editor-field">
<img src="#Url.Action("GetImage", "SubProductCategory2", new {
Model.SubProductCategoryID })" alt="" />
#Html.ValidationMessage("Picture1", "*")
<input type="file" id="fileUpload" name="Create" size="23"/>
</div>
}
ProductCategoryL2Controller.cs file
[HttpPost]
public ActionResult Edit(int id, FormCollection collection,
SubProductCategory2 editSubProdCat, HttpPostedFileBase image)
{
var r = db.SubProductCategory2.First(x => x.SubProductCategoryID
== id);
if (TryUpdateModel(r))
{
if (image != null)
{
editSubProdCat.ImageMimeType = image.ContentType;
editSubProdCat.Picture1 = new byte[image.ContentLength];
image.InputStream.Read(editSubProdCat.Picture1, 0,
image.ContentLength);
}
db.SaveChanges();
return RedirectToAction("/");
}
return View(r);
}
public FileContentResult GetImage(int productId)
{
var product = db.SubProductCategory2.First(x =>
x.SubProductCategoryID == productId);
return File(product.Picture1, product.ImageMimeType);
}
Addition Note
I am using MVC 3 framework. The GetImage method has been extacted from Steven Sanderson book Pro ASP.NET MVC 2 Framework. So I am not sure if that will be a problem?
The first step I would take to debug would be to try the URL for the image in your browser directly. Right-click on the red X, copy the url and paste it in your address bar. If the url looks right you should be a better error telling you what the problem is. If that fails, put a breakpoint in your GetImage routine to make sure the routes are correct and your method is getting called. Try Fiddler to see the request being made and what your web server is saying.
My guess is that you have the action wrong. It looks like you are linking to the GetImage action on the SubProductCategory2 controller when the method is on your ProductCategoryL2 controller.
Also I don't understand how your Model.SubProductCategoryID value is supposed to be mapped to your productId parameter. Try changing these calls:
Url.Action("GetImage", "SubProductCategory2",
new { id = item.ProductCategoryID})
Url.Action("GetImage", "SubProductCategory2", new {
Model.SubProductCategoryID })
to these:
Url.Action("GetImage", "ProductCategoryL2",
new { productId = item.ProductCategoryID})
Url.Action("GetImage", "ProductCategoryL2", new {
productId = Model.SubProductCategoryID })
Your input file field is called Create:
<input type="file" id="fileUpload" name="Create" size="23"/>
whereas the controller action parameter handling the form submission is called image (the one with HttpPostedFileBase type) => this parameter will always be null in your Edit controller action and nothing will be saved in the database.
Also the attribute is called enctype and not encType in the Html.BeginForm helper. Also inside the GetImage action ensure that product.Picture1 represents a correct image byte array and that it's content type matches with product.ImageMimeType.
So for example to further debug this issue you could try to save it to some temporary file to see if it is a valid image just before returning. Also make sure that the product instance you have fetched from the database is not null:
// if the content type is image/png:
File.WriteAllBytes(#"c:\foo.png", product.Picture1);
Then ensure that foo.png open successfully with an image viewer.
You are trying to return file content as the value to your img's src attribute. Your browser will need to issue a separate request for the image.
change your view to this:
<img src="GetImage/#(Model.SubProductCategoryID)" />