Saving file path to database, only saves the file name - c#

Ok So I have been searching all over have come to this little bit of code and got almost everything to work. I can upload an image and save it to the folder that was created. I can save the the other values pass to the database as well. My problem now is that i want to save the file path to the data base so i can call it to display the image on another page. For some reason it will only save the image's name that is being uploaded and not the path.
When i debug it and see what all is getting passed, when i add a watch to
file.SaveAs(pathLoc);
Expression has been evaluated and has no value void
Here is the code I've beed using
Controller
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(ImageInfo info, HttpPostedFileBase file)
{
if (ModelState.IsValid)
{
if (file != null)
{
var pic = Path.GetFileName(file.FileName);
var pathLoc = Path.Combine(Server.MapPath("~/Uploads/") + pic);
file.SaveAs(pathLoc);
info.ImagePath = file.FileName;
db.SaveChanges();
}
return RedirectToAction("Index");
}
return View(info);
}
View
<h2>Create</h2>
#using (Html.BeginForm("Create", "ImageInfoes", null, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<div class="form-horizontal">
<h4>ImageInfo</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.ImageName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.ImageName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.ImageName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ImageSize, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.ImageSize, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.ImageSize, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ImagePath, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
<input id="ImagePath" title="Upload a product image" type="file" name="file" />
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
Model
public partial class ImageInfo
{
public byte id { get; set; }
public string ImageName { get; set; }
public Nullable<long> ImageSize { get; set; }
public string ImagePath { get; set; }
}
Anything would be help full.

If you want, full path you need to combine file path and file name both.
Console.WriteLine(Path.Combine(System.Reflection.Assembly.GetExecutingAssembly().Location, System.IO.Path.GetRandomFileName()));
C:\Users\02483695\Documents\Visual Studio
2015\Projects\ConsoleApplication5\Cons
oleApplication5\bin\Debug\ConsoleApplication5.exe\tv1k1uev.jsq
Also below you may find a sample about file, file directory, file path and file extension.
System.IO.FileInfo fileInfo = new FileInfo("filename.file");
var fileDirectory = fileInfo.DirectoryName;
var fileName = fileInfo.Name;
var fileExtension = fileInfo.Extension;
var filePathandFileNameBoth = fileInfo.FullName;
Console.WriteLine("filePathandFileNameBoth: ");
Console.WriteLine(filePathandFileNameBoth);
Console.WriteLine("-");
Console.WriteLine("fileDirectory:");
Console.WriteLine(fileDirectory);
Console.WriteLine("-");
Console.WriteLine("fileName:");
Console.WriteLine(fileName);
Console.WriteLine("-");
Console.WriteLine(filePathandFileNameBoth == fileDirectory + "\\" + fileName ? fileExtension : "I'm totally wrong");
Console.ReadLine();
as a result:

Related

ASP.NET invalid base64 input. The input is not a valid Base-64 string

I tried to upload a photo to my controller, but it shows this error. However, the other page works fine. May I ask why? below is my code for view.
#using (Html.BeginForm("ManageProfile", "Owner", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<input type="file" id="profilePic" name="profilePic" />
}
The other view that works fine
<div class="form-group">
#Html.LabelFor(model => model.photo3, htmlAttributes: new { #class = "control-label col-md-4" })
<div class="col-md-8">
<input type="file" id="photoupload3" name="photoupload3" />
<img id="photo3" style="max-height:300px;max-width:300px;" />
</div>
</div>
The name of the input file is "profile1".
And in my controller
[HttpPost]
public ActionResult ManageProfile(Owner owner, HttpPostedFileBase profilePic)
{
string name = HttpContext.User.Identity.Name;
var dbOwner = _context.OwnerDB.Find(owner.ownerID);
dbOwner.contact = owner.contact;
dbOwner.email = owner.email;
dbOwner.Name = owner.Name;
dbOwner.password = owner.password;
if (profilePic != null)
{
dbOwner.profilePic = new byte[profilePic.ContentLength];
profilePic.InputStream.Read(dbOwner.profilePic, 0, profilePic.ContentLength);
}
_context.SaveChanges();
return RedirectToAction("Index","Home",null);
}
and the other controller works fine
[HttpPost]
public ActionResult NewRoom(Room room, HttpPostedFileBase photoupload, HttpPostedFileBase photoupload2, HttpPostedFileBase photoupload3)
{
var ownerName = HttpContext.User.Identity.Name.ToString();
Owner owner = _context.OwnerDB.Where(o => o.Name == ownerName).FirstOrDefault();
room.ownerID = owner.ownerID;
if (photoupload != null)
{
room.photo1 = new byte[photoupload.ContentLength];
photoupload.InputStream.Read(room.photo1, 0, photoupload.ContentLength);
}
Stack trace
stacktrace
View full code
#using (Html.BeginForm("ManageProfile", "Owner", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Owner</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.ownerID)
<div class="form-group">
#Html.LabelFor(model => model.Name, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Name, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Name, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.contact, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.contact, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.contact, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.email, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.email, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.email, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.password, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.password, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.password, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#*#Html.LabelFor(model => model.profilePic, htmlAttributes: new { #class = "control-label col-md-2" })*#
<div class="col-md-10">
<div class="col-md-10">
#{
if (Model.profilePic != null)
{
var base64 = Convert.ToBase64String(Model.profilePic);
var imgsrc = string.Format("data:image/gif;base64,{0}", base64);
<img src='#imgsrc' width="300" height="300" class="reel"
data-image='#imgsrc'
data-stitched="600"
data-frames="30"
data-frame="15"
data-rows="1"
data-row="1"
data-loops="false"
alt="#Model.Name" />
}
}
<input type="file" id="profilePic" name="profilePic" />
</div>
</div>
</div>
<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>
}

Change what submit button does based on editorFor circumstance

I have an edit form page on my website that allows users to edit quantities, on this page I used editorFor's which look like this
#Html.EditorFor(model => model.item_qty, new { htmlAttributes = new { min = 0, #class = "form-control" } })
And I have a submit button that looks like this
<input type="submit" value="Save" class="btn" />
I want to make it so that if the user increases the qty, it will go ahead and run the post method. But on the other hand, if a user was to decrease the qty, I would want the save button to look like this
<input type="submit" value="Save" onclick="confirm()" class="btn" />
Where it gets the user to confirm before running the post.
How can I make my save button change based on what the user types into the editorFor?
Here is my entire view page as requested
#model PIC_Program_1._0.Models.JODetails
#using PIC_Program_1._0.Models
#{
ViewBag.Title = "Edit";
PIC_Program_1_0Context db = new PIC_Program_1_0Context();
var currentData = db.JODetails.AsNoTracking().FirstOrDefault(j => j.ID == Model.ID);
Component comp = db.Components.Find(Model.ComponentID);
Item i = db.Items.Find(Model.ItemID);
}
<script type="text/javascript">
function clicked(e) {
if(#i != null ) {
var itemDiff = // model - new editorfor value;
if (!confirm('Are you sure? Doing this will reduce item ' + #i.ItemID + ' future stock to ' + itemDiff))e.preventDefault();
}
}
function OnChangeEvent(){
alert("value is changed");
var itemQty = $('#itemQTY').val();
if (itemQty < #Model.item_qty) {
btn.Attributes.Add("onclick", "clicked(event)");
}
}
</script>
<h2>Edit</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>JODetails</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.ID)
#Html.HiddenFor(model => model.subDetail)
<p style="color:red">#ViewBag.Error</p>
<div class="form-group">
#Html.LabelFor(model => model.ItemID, "ItemID", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("ItemID", null, "-- Select --", htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.ItemID, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.item_qty, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#if (ViewBag.isValid == false)
{
#Html.TextBoxFor(model => model.item_qty, new { disabled = "disabled", #Value = Model.item_qty, #readonly = "readonly" })
}
else
{
#Html.EditorFor(model => model.item_qty, new { htmlAttributes = new { onchange = "OnChangeEvent()", min = 0, #class = "form-control" #id = "itemQTY"} })
#Html.ValidationMessageFor(model => model.item_qty, "", new { #class = "text-danger" })
}
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn"/>
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
For the on change you can on your editor for:
#Html.EditorFor(model => model.item_qty, new { htmlAttributes = new { onchange = "OnChangeEvent(this)", min = 0, #class = "form-control", #id ="someId" } })
<script type="text/javascript">
function OnChangeEvent(){
var itemQty = $('#someID').val(); //This will give you value of editor for
alert("new value is: " + itemQty);
//Call some controller function here and do your increase/decrease logic and return value so we know what to do. also perform your save in controller too if needed.
#Model.IsChanged = true;
//do other functions here also like change button
//if decrease add below
btn.Attributes.Add("onclick", "confirm()");
//if increase remove and perform save.
}
</script>
You can also change the button from that method. There is no good way to do on call events at a server level, unless using blazor, so javascript is your best bet here.
Updated answer per OP:
#model PIC_Program_1._0.Models.JODetails
#using PIC_Program_1._0.Models
#{
ViewBag.Title = "Edit";
PIC_Program_1_0Context db = new PIC_Program_1_0Context();
var currentData = db.JODetails.AsNoTracking().FirstOrDefault(j => j.ID == Model.ID);
Component comp = db.Components.Find(Model.ComponentID);
Item i = db.Items.Find(Model.ItemID);
}
<h2>Edit</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>JODetails</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.ID)
#Html.HiddenFor(model => model.subDetail)
<p style="color:red">#ViewBag.Error</p>
<div class="form-group">
#Html.LabelFor(model => model.ItemID, "ItemID", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("ItemID", null, "-- Select --", htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.ItemID, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.item_qty, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#if (ViewBag.isValid == false)
{
#Html.TextBoxFor(model => model.item_qty, new { disabled = "disabled", #Value = Model.item_qty, #readonly = "readonly" })
}
else
{
#Html.EditorFor(model => model.item_qty, new { htmlAttributes = new { onchange = "OnChangeEvent(this)", min = 0, #class = "form-control", #id = "itemQTY"} })
#Html.ValidationMessageFor(model => model.item_qty, "", new { #class = "text-danger" })
}
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn"/>
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
<script type="text/javascript">
function OnChangeEvent(){
alert("value is changed");
var itemQty = $('#itemQTY').val();
if (itemQty < #Model.item_qty) {
btn.Attributes.Add("onclick", "clicked(event)");
}
}
</script>

Upload file from input file to a folder using Visual Studio 2017 Asp.net mvc 5

I'm working on Visual Studio 2017 using Asp.net Mvc 5 to build a web site,My problem is that I can't upload an image from a input file to a server folder
MY CODE:
Create: Views
#using (Html.BeginForm("Create","Jobs",null,FormMethod.Post,new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Jobs</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.JobTitle, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.JobTitle, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.JobTitle, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.JobContent, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.JobContent, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.JobContent, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.JobImage, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
<input type="file" name="upload"/>
#Html.ValidationMessageFor(model => model.JobImage, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.CategoryId, "JobType", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("CategoryId", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.CategoryId, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
#ViewBag.Message
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
Controller:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create( Jobs jobs,HttpPostedFile upload)
{
try
{
if (ModelState.IsValid)
{
if (upload != null && upload.ContentLength > 0)
{
string FileName = Path.GetFileName(upload.FileName);
string path = Path.Combine(Server.MapPath("~/Uploads"), FileName);
upload.SaveAs(path);
jobs.JobImage = FileName;
db.Jobs.Add(jobs);
db.SaveChanges();
}
else{
}
}
}
catch (RetryLimitExceededException /* dex */)
{
//Log the error (uncomment dex variable name and add a line here to write a log.
ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists see your system administrator.");
}
ViewBag.CategoryId = new SelectList(db.Categories, "Id", "CategoryName", jobs.CategoryId);
return View(jobs);
}
when I click submit Button nothing change on browser and no error is generated, but when I check Uploads file I found nothing(img file ) ,the same on the database , I don't know where is the error
Note:
Before I added the input file , my code was working perfectly
Any Help Please

how to upload image as part of a form with other fields in asp.net mvc5

I'm just trying record student information with an image profile. I want to upload the image as part of the form to application->Image directory and save the image name to the database.
This is my controller
public ActionResult Create([Bind(Include ="StudentId,StudentName,StudentLastName,StudentPhone,StudentAge,StudentEmail,photo")] Student student , HttpPostedFileBase file)
{
if (ModelState.IsValid)
{
file.SaveAs(HttpContext.Server.MapPath("~/Images/") + file.FileName);
db.Students.Add(student);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(student);
}
in my view
#using (Html.BeginForm("Create", "Students", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Student</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.StudentName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.StudentName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.StudentName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.StudentLastName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.StudentLastName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.StudentLastName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.StudentPhone, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.StudentPhone, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.StudentPhone, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.StudentAge, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.StudentAge, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.StudentAge, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.StudentEmail, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.StudentEmail, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.StudentEmail, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.photo, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextBoxFor(model => model.photo, new { type = "file" })
#Html.ValidationMessageFor(model => model.photo, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
but when i upload, it generates an error message
An exception of type 'System.NullReferenceException'
on this line
file.SaveAs(HttpContext.Server.MapPath("~/Images/") + file.FileName
please help me this issue please...
Try this one:
change it:
From
file.SaveAs(HttpContext.Server.MapPath("~/Images/") + file.FileName
To
file.SaveAs(HttpContext.Server.MapPath("~/Images/" + file.FileName))
System.NullReferenceException means that something is null at this reported line of code.
In this situation, it should be your HttpPostedFileBase file.
Try run the application in debug mode, and check again the name of your upload field, whether it's set as "file". MVC asp.net using Name attribute to define parameter.
In my case, I'm using a simple <input> to do the upload file and another <img> for displaying:
View:
<!--Displaying: You need some code for this-->
<img src="#ViewBag.ImagePath" alt="Message picture" style="width:100%;">
<!--Uploading-->
#using (Html.BeginForm("Create", "Students", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<!-- Your other part of form -->
<!-- Uploading -->
<input type="file" name="file" />
}
Controller:
// extract only the filename
var fileName = Path.GetFileName(file.FileName);
// initial new path for upload file
var newSPath = Path.Combine(Server.MapPath("~/Images"), fileName);
// store file
file.SaveAs(newSPath);
Try this:-
public ActionResult Create([Bind(Include ="StudentId,StudentName,StudentLastName,StudentPhone,StudentAge,StudentEmail,photo")] Student student , HttpPostedFileBase photo)
{
if (ModelState.IsValid)
{
var fileName=Path.GetFileName(photo.FileName);
var path=Path.Combine(Server.MapPath("~/Images/") + fileName)
photo.SaveAs(path);
db.Students.Add(student);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(student);
}

null value after reading from database in mvc

I have the edit view and the edit action in my blog controller.
After I created a post with the "create action" and after I upload the image to the database folder, I update the path on the post.PostImage (string value).
I can see the image in the folder, and I can see the path of my image and I can also see the preview of the picture in the edit view. In my database it saved as (~/Images/PostID/PictureName). But after I edit my post, I want to make a checkbox that if checked I can edit the picture and when is it not checked I delete the picture. I send the parameters, and my problem is that on the debugger I see the "string postimage" as null but on the database table it has the path!
and because of that all of this doesn't work, I don't care about logic, why is it null????
here is my code:
VIEW:
#model WebApplication1.Models.Post
#{
ViewBag.Title = "Edit";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Edit</h2>
#using (Html.BeginForm(Html.BeginForm("Edit", "Blog", FormMethod.Post, new { enctype = "multipart/form-data" })))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Post</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.PostID)
<div class="form-group">
#Html.LabelFor(model => model.PostTitle, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.PostTitle, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.PostTitle, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.PostAuthor, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.PostAuthor, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.PostAuthor, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.WebSite, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.WebSite, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.WebSite, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.PostDate, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.PostDate, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.PostDate, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.PostText, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.PostText, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.PostText, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div>
<b>Upload image:</b>
#if (!Model.PostImage.IsEmpty())
{
#Html.CheckBox("checkImage", true)
<img src="#Url.Content(Model.PostImage)" alt="#Model.PostAuthor" width="300" />
}
else
{
#Html.CheckBox("checkImage", false)
}
</div>
<input type="file" name="file" id="file" />
<!-- Show message of the controller -->
#ViewBag.Message
</div>
<div class="form-group">
#Html.LabelFor(model => model.PostVideo, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.PostVideo, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.PostVideo, "", new { #class = "text-danger" })
</div>
</div>
<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>
}
<div>
#Html.ActionLink("Back to Posts List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
EDIT ACTION IN BLOG CONTROLLER:
// GET: Blog/Edit/5
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Post post = db.Posts.Find(id);
if (post == null)
{
return HttpNotFound();
}
return View(post);
}
// POST: Blog/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "PostID,PostTitle,PostAuthor,WebSite,PostDate,PostText,PostImage,PostVideo")] Post post, HttpPostedFileBase file, bool checkImage)
{
var fileName = "";
if (ModelState.IsValid)
{
db.Entry(post).State = EntityState.Modified;
if (checkImage == true)
{
//Check if there is a file
if (file != null && file.ContentLength > 0)
{
//Check if there is an image
var supportedTypes = new[] { "jpg", "jpeg", "gif", "png" };
var fileExt = System.IO.Path.GetExtension(file.FileName).Substring(1);
if (!supportedTypes.Contains(fileExt))
{
ViewBag.Message = "Invalid image type. Only the following types (jpg, jpeg, gif, png) are supported";
return View();
}
//Check if there is a file on database
if ( !(String.IsNullOrEmpty(post.PostImage)) )
{
//Delete old file in folder
System.IO.File.Delete(post.PostImage);
//Save new file in folder
var folder = Path.Combine(Server.MapPath("~/Images/"), Convert.ToString(post.PostID));
var path = Path.Combine(folder, fileName);
file.SaveAs(path);
//Save path in database
string targetPath = String.Concat("~/Images/", Convert.ToString(post.PostID), "/", fileName);
post.PostImage = targetPath;
}
//No file in database
else
{
var folder = Path.Combine(Server.MapPath("~/Images/"), Convert.ToString(post.PostID));
var path = Path.Combine(folder, fileName);
file.SaveAs(path);
//Save path in database
string targetPath = String.Concat("~/Images/", Convert.ToString(post.PostID), "/", fileName);
post.PostImage = targetPath;
}
}
//Checkbox is checked but not file uploaded
else
ViewBag.Message = "Checkbox is checked, please upload an image";
return View();
}
else
{
//Checkbox is not checked - Delete the image from database
if( !(String.IsNullOrEmpty(post.PostImage)) )
{
//Delete old file in folder
try
{
System.IO.File.Delete("\a.txt");
post.PostImage = null;
}
catch (System.IO.IOException e)
{
Console.WriteLine(e.Message);
}
}
db.SaveChanges();
return RedirectToAction("Index");
}
}
return View(post);
}
Render the postImage field
#Html.EditorFor(model => model.PostImage, new { htmlAttributes = new { #class = "form-control" } })
So from what I have read recently, do not pass your Entity Framework model directly into your view. Create a separate ViewModel. On GET, Construct this ViewModel based on your EF model, and on POST, extract the information you need from your ViewModel and update your EF model that is in the database.
In your View, you don't have a EditorFor() or HiddenFor() for the image URL, and that is why on your POST it will be null.
This is EXACTLY why you want to use ViewModels instead of directly using EF models in your view so you can have a separate view model that only contains property that needs to be edit/updated/displayed, while properties from the entities that needs to be remained untouched will remain untouched.

Categories

Resources