Uploading picture in ASP.net core stays NULL - c#

Im trying to pass the filepath into my ProfileViewModel but it seems to stay Null even thought the other values are filled.
I have tried debugging it but cant seem to find where its going wrong.
My view
#using (Html.BeginForm("EditProfile", "Profile", FormMethod.Post))
{
#Html.AntiForgeryToken()
#Html.LabelFor(model => model.Photo, htmlAttributes: new { #class = "control-label col-md-2" })
<input asp-for="Photo" type="file"/><br />
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
my controller
public IActionResult profile()
{
return View();
}
private readonly IHostingEnvironment he;
public ProfileController(IHostingEnvironment e)
{
he = e;
}
[HttpPost]
public ActionResult EditProfile(ProfileViewModel profile)
{
string ID = Request.Cookies["UserID"];
if (ModelState.IsValid)
{
var Photo = profile.Photo;
var FileName = Path.Combine(he.WebRootPath, Path.GetFileName(Photo.FileName));
if (logicprofile.logicEditProfile(profile.BIO, profile.Sex, profile.Preffered, FileName, Convert.ToInt32(ID)) == true)
{
profile.Photo.CopyTo(new FileStream(FileName, FileMode.Create));
ViewBag.Message = "Profile Updated";
return View("profile", profile);
}
else
{
ViewBag.Message = "Something went wrong";
return View("profile", profile);
}
}
else
{
return View("profile", profile);
}
}
ViewModel
[DisplayName("A picture of you!")]
public IFormFile Photo { get; set; }
I expect my pictures to be saved in a folder and the path to a database so I can use them as profile pictures.

You should use enctype in form for passing file type data.
#using (Html.BeginForm("EditProfile", "Profile", FormMethod.Post, new { enctype = "multipart/form-data" }))

Related

how to add image in Asp.net?

I cannot add image in about -> post method. This is my code please help.
This is my controller section:
ActionResult Register(Admin adm)
{
string fileName = Path.GetFileNameWithoutExtension(adm.ImageFile.FileName);
string exe = Path.GetExtension(adm.ImageFile.FileName);
fileName = fileName + DateTime.Now.ToString("yymmssfff") + exe;[enter image description here][1]
adm.Adm_Image_path = "~/Image/" + fileName;
fileName = Path.Combine(Server.MapPath("~/Image/"), fileName);
adm.ImageFile.SaveAs(fileName);
// Upload_Image(adm.ImageFile);
if (ModelState.IsValid)
{
if (adm.Adm_Password == adm.Adm_Confirm_Password)
{
adm.Adm_Type = "Admin";
db.admin.Add(adm);
db.SaveChanges();
return RedirectToAction("Login", "Home");
}
}
return View();
}
View section here
<div class="form-group">
#Html.LabelFor(x => x.Adm_Image_path, new { #class = "control-label col-md-2" })
<div class="col-md-10">
<input type="file" name="ImageFile" id="ImageFile" value="ImageFile" required />
#Html.ValidationMessageFor(x => x.Adm_Image_path, "", new { #class="text-danger"})
</div>
</div>
<input type="submit" value="Save" class="btn btn-default" />`
I cannot upload the image in the specific section.
Use Below code.
Model Class:
public class Admin
{
public string ImagePath { get; set; }
public HttpPostedFileBase ImageFile { get; set; }
}
Controller:
public ActionResult Register()
{
return View();
}
[HttpPost]
public ActionResult Register(Admin adm)
{
string fileName = Path.GetFileNameWithoutExtension(adm.ImageFile.FileName);
string exe = Path.GetExtension(adm.ImageFile.FileName);
fileName = fileName + DateTime.Now.ToString("yymmssfff") + exe;
adm.ImagePath = "~/Images/" + fileName;
fileName = Path.Combine(Server.MapPath("~/Images/"), fileName);
adm.ImageFile.SaveAs(fileName);
//Upload_Image(adm.ImageFile);
if (ModelState.IsValid)
{
//if (adm.Adm_Password == adm.Adm_Confirm_Password)
//{
// adm.Adm_Type = "Admin";
// db.admin.Add(adm);
// db.SaveChanges();
// return RedirectToAction("Login", "Home");
//}
return View();
}
else
{
return View();
}
}
View:
#model testProject.Models.Admin
#{
ViewBag.Title = "Register";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Register</h2>
#using (Html.BeginForm("Register", "Signup", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div class="form-group">
#Html.LabelFor(x => x.ImagePath, new { #class = "control-label col-md-2" })
<div class="col-md-10">
<input type="file" name="ImageFile" id="ImageFile" value="ImageFile" required />
#Html.ValidationMessageFor(x => x.ImagePath, "", new { #class = "text-danger" })
</div>
</div>
<input type="submit" value="Save" class="btn btn-default" />
}
Hope this will surely help you.

Can't upload file in MVC

I have a problem with uploading files to my database, PostedFile is always a null.
Controller:
public ActionResult Create(Sound sound)
{
if (sound.PostedFile != null && sound.PostedFile.ContentLength > 0)
{
MemoryStream temp = new MemoryStream();
sound.PostedFile.InputStream.CopyTo(temp);
sound.Data = temp.ToArray();
db.SoundsTable.Add(sound);
db.SaveChanges();
ViewBag.Message = "DONE";
}
else
{
ViewBag.Message = "ERR";
}
return RedirectToAction("Index");
}
Model:
public class Sounds : DbContext
{
public Sounds()
: base("name=Sounds")
{
}
public virtual DbSet<Sound> SoundsTable { get; set; }
}
public class Sound
{
public int Id { get; set; }
public string Name { get; set; }
[MaxLength(8388608)]
public byte[] Data { get; set; }
[NotMapped]
[Required(ErrorMessage = "Please select file.")]
public HttpPostedFileBase PostedFile { get; set; }
}
View:
#model WebApp.Models.Sound
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
#using (Html.BeginForm())
{
<div class="form-horizontal">
<h4>Sound</h4>
#Html.EditorFor(model => model.Name, new { htmlAttributes = new { #class = "form-control" } })<br />
#Html.TextBoxFor(model => model.PostedFile, new { type = "file" })<br />
#Html.ValidationMessageFor(model => model.PostedFile, "", new { #class = "error" })<br />
<input type="submit" value="UPLOAD" />
<br />
#ViewBag.Message
</div>
<div>
#Html.ActionLink("Back to List", "Index")
</div>
}
Everything works fine with Name value being send from View to Controller. But I cant get working sending PostedFile value, as it is always a null.
enctype = multipart/form-data is indeed required
#using (Html.BeginForm("Create", //Your action
"Test", //Your controller
FormMethod.Post,
new { enctype = "multipart/form-data"}))
{
<div class="form-horizontal">
<h4>Sound</h4>
#Html.EditorFor(model => model.Name, new { htmlAttributes = new { #class = "form-control" } })<br />
#Html.TextBoxFor(model => model.PostedFile, new { type = "file" })<br />
#Html.ValidationMessageFor(model => model.PostedFile, "", new { #class = "error" })<br />
<input type="submit" value="UPLOAD" />
<br />
#ViewBag.Message
</div>
<div>
#Html.ActionLink("Back to List", "Index")
</div>
}
try this:
#using (Html.BeginForm("Create", "Test", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
//other controls here
<input type="file" name="postedFile" id="fileInputId" />
//submit button here }
Then your controller:
[HttpPost]
public ActionResult Create(Sound model, HttpPostedFileBase postedFile)
{
//do stuff
}
Make sure that the name in input file element is the same as the parameter name in the controller.

How to pass model between different method of controller from view MVC

I search much but I am not lucky to find the solution, My aim is save a model depending on the button that the user chooses.
I have two inputs of type button, which should each invoke a different method from the controller at the moment of press click. You must have an account. All this happens in the same view for only a model.
This is my view:
#model WebShop.Models.Product
#{
ViewBag.Title = "Create";
}
<h2>Crear</h2>
#using Newtonsoft.Json
#using (Html.BeginForm(new { #id = "create" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Producto</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.ProductNumber, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.ProductNumber, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.ProductNumber, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ProductTitle, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.ProductTitle, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.ProductTitle, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Crear" class="btn btn-default" />
<input type="submit" value="Crear en memoria" class="btn btn-default" id="InMemory" />
</div>
</div>
</div>
}
And these are my methods:
[HttpPost]
public ActionResult Create(Product product)
{
try
{
List<Product> listProducts = new List<Product>();
if (ModelState.IsValid)
{
db.Products.Add(product);
db.SaveChanges();
TempData["list"] = db.Products.ToList();
return RedirectToAction("Index");
}
return View(product);
}
catch
{
return View(product);
}
}
[HttpPost]
public ActionResult CreateInMemory(Product product)
{
try
{
if (ModelState.IsValid)
{
using (SQLiteConnection con = new SQLiteConnection("Data Source=:memory:"))
{
con.Open();
if (string.IsNullOrEmpty(result.ToString()))
{
string query = #"CREATE TABLE Products
(ProductID integer primary key,
ProductNumber integer,
ProductTitle varchar(100));";
using (SQLiteCommand comd = new SQLiteCommand(query,con))
{
comd.ExecuteNonQuery();
TempData["list"] = saveListProduct(product, con);
}
}
else
{
TempData["list"] = saveListProduct(product, con);
}
con.Close();
return RedirectToAction("Index");
}
}
return View(product);
}
catch(Exception e)
{
string message = e.Message;
return View("Index");
}
}
In order that they are in context, I want to guard the model in the database and in memory with SQLite, and any suggestion is welcome.
I think you can use formaction attribute (HTML5) for this. Try the following. Hope to help, my friend :))
<input type="submit" name="response" value="Create" formaction=#Url.Action("Create") formmethod="post" class="btn btn-default" />
<input type="submit" name="response" value="CreateInMemory" formaction=#Url.Action("CreateInMemory") formmethod="post" class="btn btn-default" />
Note: It just can be implemented in HTML5.
consider the following sample , how to send a model to different methods of same controller:
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Method1(BooModel model)
{
...
}
[HttpPost]
public ActionResult Method2(BooModel model)
{
...
}
}
public class BooModel
{
public int Id { get; set; }
public string Name { get; set; }
}
#model WebApi.Controllers.BooModel
#using (Html.BeginForm())
{
#Html.TextBoxFor(x=>x.Id)
#Html.TextBoxFor(x=>x.Name)
<input type="submit" value="Method1" onclick='this.form.action="#Url.Action("Method1", "Home", null, this.Request.Url.Scheme)"' />
<input type="submit" value="Method2" onclick='this.form.action="#Url.Action("Method2", "Home", null, this.Request.Url.Scheme)"' />
}
For a jQuery solution change your <input> elements into plain <button> ones and use the below jQuery in your $(document).ready() function :
$("#btnCreate").on('click', function () {
$.ajax({
url: '#Url.Action("Create", "Controller", new { area="Area"})',
type: "POST",
data: $('form').serialize(),
success: function () {
//Go to new location etc
}
})
})
$("#btnCreateInMemory").on('click', function () {
$.ajax({
url: '#Url.Action("CreateInMemory", "Controller", new { area="Area"})',
type: "POST",
data: $('form').serialize(),
success: function () {
//Go to new location etc
}
})
})

File Upload ASP.NET MVC Not Working

I have tried my best however HttpPostedFileBase filee is always null
Controller Action
public ActionResult UploadFile(HttpPostedFileBase filee)
{
try
{
if (filee.ContentLength > 0)
{
string _FileName = Path.GetFileName(filee.FileName);
string _path = Path.Combine(Server.MapPath("~/UploadedFiles"), _FileName);
filee.SaveAs(_path);
}
ViewBag.Message = "File Uploaded Successfully!!";
return View();
}
catch
{
ViewBag.Message = "File upload failed!!";
return View();
}
}
Razor View
#{
ViewBag.Title = "UploadFile";
}
<h2>UploadFile</h2>
#using (Html.BeginForm("UploadFile", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div>
#Html.TextBox("file", "", new { type = "file" }) <br />
<input type="submit" value="Upload" />
#ViewBag.Message
</div>
}
Either change the name of parameter in public ActionResult UploadFile(HttpPostedFileBase filee) to public ActionResult UploadFile(HttpPostedFileBase file) or change the input name #Html.TextBox("file", "", new { type = "file" }) to #Html.TextBox("filee", "", new { type = "file" }).
You have to use same name of yor input field as your HttpPostedFileBase object name while you are working on loosly type view !
Example :
#{
ViewBag.Title = "UploadFile";
}
<h2>UploadFile</h2>
#using (Html.BeginForm("UploadFile", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div>
#Html.TextBox("filee", "", new { type = "file" }) <br />
<input type="submit" value="Upload" />
#ViewBag.Message
</div>
}
Or If you don't want to use same names ?
you just have to use a tightly coupled view type view
Tightly
Example:
#model PROJECTNAME.Models.MODELNAME
#{
ViewBag.Title = "UploadFile";
}
<h2>UploadFile</h2>
#using (Html.BeginForm("UploadFile", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div>
#Html.TextBox(model => model.YOURCOLUMNNAME , "", new { type = "file" }) <br />
<input type="submit" value="Upload" />
#ViewBag.Message
</div>
}

Can I accept a HttpPostedFileBase as part of a ViewModel

I am setting up a view and ViewModel to accept some data and a File. But when I look at the returned model, I do not see a file.
Here's my ViewModel:
public class ResourceReviewViewModel
{
public Guid ResourceReviewId { get; set; }
//....
[Display(Name="Review Document File")]
public HttpPostedFileBase ReviewFile { get; set; }
}
My view:
My controller to handle the submit:
[HttpPost]
[ValidateAntiForgeryToken]
public virtual ActionResult ResourceReview(ResourceReviewViewModel model)
{
//...
return View(model); // model.ReviewFile is null
}
#model PublicationSystem.ViewModels.ResourceReviewViewModel
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Submit Your Review</h4>
<hr/>
#Html.HiddenFor(model => model.RequestReviewId, new { htmlAttributes = new { #class = "form-control" } })
<div class="form-group">
#Html.LabelFor(model => model.ReviewFile, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
<input type="file" id="ReviewFile" name="ReviewFile" value="ActionHandlerForForm" />
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Submit" class="btn btn-default" />
</div>
</div>
</div>
}
The model comes back with values, but the file property is NULL. The HTML for the Input I copied from another page, so I'm not sure I need value="ActionHandlerForForm".
Yes, it's possible. I think in your example you're just missing multipart/form-data
Try this (replace "Index" and "Home" to the View/Controller you have):
#using (Html.BeginForm("Index", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
...
}

Categories