I am trying to create a user profile picture in a ASP MVC5 project. I have added a page that is called changepicture.cshtml and will display the current user's picture.
I have an upload function that will take a picture someone uploads like hank.jpg and rename it to that users_id.jpg.
For example:
System.Data.Entity.DynamicProxies.ApplicationUser_9C8230B38B954135385F2B0311EAC02ED8B95C4D504F8424BA3ED79B37F0AAAF.jpg
I would like to display each users individual picture in the page by grabbing there user id and adding .jpg, how would I do this?
changepicture.cshtml
#model KidRoutineLogging.Models.ChangePictureViewModel
#{
ViewBag.Title = "Change Picture";
}
<h2>#ViewBag.Title.</h2>
<h4>Your Current Picture : #Html.ViewBag.CurrentPicture</h4>
<img src="#Url.Content("~/uploads/hank.jpg")" />
<br />
<br />
#using (Html.BeginForm("", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<input type="file" name="FileUpload1" /><br />
<input type="submit" name="Submit" id="Submit" value="Upload" />
}
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
HomeController.cs
public async Task<ActionResult> Index()
{
foreach (string upload in Request.Files)
{
var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
string path = AppDomain.CurrentDomain.BaseDirectory + "uploads/";
//string filename = Path.GetFileName(Request.Files[upload].FileName);
//Request.Files[upload].SaveAs(Path.Combine(path, filename));
Request.Files[upload].SaveAs(Path.Combine(path, user + ".jpg"));
}
return View();
}
You are getting a funky-typed name for your file because you are attempting to cast an entire class (object) to string. Additionally, if you are wanting to name the file "UserId.jpg", your code is doing more work than it should.
This line:
var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
Can be simplified to this line:
var userId = User.Identity.GetUserId();
That would leave your final code as:
public async Task<ActionResult> Index()
{
foreach (string upload in Request.Files)
{
var userId = User.Identity.GetUserId();
string path = AppDomain.CurrentDomain.BaseDirectory + "uploads/";
Request.Files[upload].SaveAs(Path.Combine(path, userId + ".jpg"));
}
return View();
}
You could get rid of the userId variable completely, and update your SaveAs method to
Request.Files[upload].SaveAs(Path.Combine(path, User.Identity.GetUserId()+ ".jpg"));
Also - you really should decorate this ActionResult with the <HttpPost> attribute since it should only be handling the POSTing of the form and not associated with a GET request.
Related
I have a importFile button the HTML page, upon clicking of it Import File, process the file and return back if there are any errors with a message "File upload Failed with errors. Please check downloaded Error File." If there are no errors, then just "File uploaded successfully" message.
This is what my view looks like:
#using (Html.BeginForm("FileUpload", "Plt", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<input type="file" name="file" />
<input type="submit" value="OK" />
}
Server Side Code:-
[HttpPost]
public virtual ActionResult ImportFileData(HttpPostedFileBase importFile)
{
if (importFile.ContentLength > 0)
{
var target = new MemoryStream();
importFile.InputStream.CopyTo(target);
byte[] data = target.ToArray();
var fileNameWithoutExtension = importFile.FileName.Remove(importFile.FileName.IndexOf("."));
var file = new FileDetails(fileNameWithoutExtension, data, FileTypes.Xlsx);
var importedFileDetails = PortalService.ImportFromExcel(file);
return File(importedFileDetails.FileBytes, importedFileDetails.MimeType, importedFileDetails.FileName);
}
return RedirectToAction(MVC.SystemSetup.Index());
}
On failure. return to the same View and send message and code regarding failure in a ViewBag. Example ViewBage.ErrorMessage and ViewBag.ErrorID.
On View, check if the ViewBag.ErrorID is empty or not. If not empty create a <div> which will show the error message as will as a link to download the file.
Somewhat like below code.
#if (ViewBag.ErrorID != null)
{
<div>
Error : #ViewBag.ErrorMessage.ToString();
#Html.ActionLink("Download Error Log", "FileDownloadAction", new { ErrorID = ViewBag.ErrorID });
</div>
}
The FileDownloadAction should accept the ErrorID as parameter. Using this Error ID you could create the required Error log file. The FileDownloadAction should reutn FileResult.
I'm creating an app in c# mvc, where users can upload mp3 files, Below is my Upload controller:
[HttpPost]
public ActionResult Index(HttpPostedFileBase file)
{
string x = Request["ss"];
song std = new song();
if (file != null && file.ContentLength > 0)
try
{
// string path = Path.Combine(Server.MapPath("~/Songs"), Path.GetFileName(file.FileName));
string path = "~/Songs/" + Path.GetFileName(file.FileName);
var allowedExtensions = new[] { ".mp3",".MP3" };
var extension = Path.GetExtension(file.FileName);
if (!allowedExtensions.Contains(extension))
{
ViewBag.Message = "Only .mp3 extension files are allowed!!";
}
else
{
file.SaveAs(Server.MapPath(#"~\Songs\" + file.FileName));
//file.SaveAs(path);
string[] arr = { };
arr = (file.FileName).Split('.');
std.name = arr[0];
if (x == null || x == "")
{
std.artist = "Not Mentioned";
}
else {
std.artist = x;
}
std.likes = "0";
std.dislikes = "0";
repo4.save4(std); //call the function..
ViewBag.Message = "Song uploaded successfully!! ";
}
}
catch (Exception ex)
{
ViewBag.Message = "ERROR:" + ex.Message.ToString();
}
else
{
ViewBag.Message = "You have not specified a file.";
}
return View();
}
below is my view for index.cshtml:
#using (Html.BeginForm("index", "Upload", FormMethod.Post, new { enctype ="multipart/form-data" }))
{
<label class="l" for="file">Upload Song:</label>
<input class="l" type="file" name="file" id="file" />
<div class="form-inline form-group">
<label class="l">Artist' Name : </label>
<input type="text" class="form-control" name="ss" maxlength="30" placeholder="Leave it blank if u want.." />
</div>
<input type="submit" class="btn btn-warning" value="Upload" />
<div class="text-danger">#ViewBag.Message</div><br /><div class="text-success">Search uploaded song HERE</div>
}
Now, I'm saving the mp3 files to a folder named as Songs..this code seems to be working fine when i build my project on VS..but after deployment on app harbor, when i try to upload an mp3 file i keep getting following error:
ERROR:Access to the path
'D:\Users\apphb180c99d1921484\app_PublishedWebsites\WebMatrixWebsite\Songs\Wake
Me Up.mp3' is denied.
Please any help would be appreciated as i cant get my head around it..thanx!!
Working for me now..in case anyone's still wondering how..you need to give permissions for NETWORK SERVICE to your folder where the files are being stored..
In this case:
Songs->properties..open the security tab -> edit -> Add..
choose the Locations.. to your pc..then write "NETWORK SERVICE" under "enter the object names to select" then check names and enter ok...
now give it the permissions by selecting one of the check boxes, you might wanna choose read/write..
I chose "full control" and it's working perfectly for me..hopefully it'll work out for you guys too :) cheers..
I have some issue for my c# code for upload some file...in controller file detect null.
My html code
#using (Html.BeginForm("Index", "UploadHistory",FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<input type="file" name="uploadFile" id="uploadFile" />
<input type="submit" value="Upload File" id="btnSubmit" />
}
and this code for my controller
[HttpPost]
public ActionResult Index(HttpPostedFileBase uploadFile)
{
// Verify that the user selected a file
if (uploadFile != null && uploadFile.ContentLength > 0)
{
// extract only the fielname
var fileName = Path.GetFileName(uploadFile.FileName);
// store the file inside ~/App_Data/uploads folder
var path = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName);
uploadFile.SaveAs(path);
}
// redirect back to the index action to show the form once again
return RedirectToAction("Index");
}
Any ideas why my upload file detect null?? i use C# mvc 4 and razor thank you.
[SOLVED]
Just error in javascript method post.
Refer to this link
Possible copy of
In short
Use
public ActionResult Index(HttpPostedFileBase uploadFile)
Also change
<input type="file" name="file" id="file" />
to
<input type="file" name="uploadFile" id="uploadFile" />
The following should work for you:
Model
public class UploadFileModel
{
public UploadFileModel()
{
Files = new List<HttpPostedFileBase>();
}
public List<HttpPostedFileBase> Files { get; set; }
}
View
#using (Html.BeginForm("Index", "Home",FormMethod.Post, new { enctype = "multipart/form-data" }))
{
Html.TextBoxFor(m => m.Files.Files, new { type = "file", name = "Files" })
<input type="submit" value="Upload File" id="btnSubmit" />
}
Controller
[HttpPost]
public ActionResult Index(UploadFileModel model)
{
var file = model.Files[0];
return View(model);
}
Use below
[HttpPost]
public ActionResult Index(HttpPostedFileBase file)
{
if (file != null && file.ContentLength > 0)
{
var fileName = Path.GetFileName(file.FileName);
var path = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName);
file.SaveAs(path);
}
return RedirectToAction("Index");
}
mainly use HttpPostedFileBase in your parameter
I am not sure model binding works in this scenario. Either you need to use HttpPostedFileBase as a parameter to the controller action or you need to use Request.Files option.
Using Request.Files option.
foreach (string file in Request.Files)
{
HttpPostedFile hpf = Request.Files[file] as HttpPostedFile;
if (hpf.ContentLength == 0)
continue;
string savedFileName = Path.Combine(
AppDomain.CurrentDomain.BaseDirectory,
Path.GetFileName(hpf.FileName));
hpf.SaveAs(savedFileName);
}
EDIT : Here I found a blog which uses similar scenario (Model binding). It may help you - http://cpratt.co/file-uploads-in-asp-net-mvc-with-view-models/
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.