Reputation: 679
I want to display Image in modal pop up after form submission. But currently, I am getting the path C:\fakepath\Flag.jpg, not the Image. And also When I edit my form, I am not getting the Image.
Can anyone please suggest me where I am going wrong. Thank you.
Controller
[HttpPost]
public JsonResult _Edit(ClsEmployee clsEmployee, HttpPostedFileBase FilePath)
{
try
{
if (Request.Files.Count > 0)
{
FilePath = Request.Files[0];
if (FilePath != null && FilePath.ContentLength > 0)
{
string fileName = Path.GetFileName(FilePath.FileName);
string path = "/Image/" + fileName;
clsEmployee.FilePath = path;
}
}
context.Entry(clsEmployee).State = System.Data.Entity.EntityState.Modified;
context.SaveChanges();
return Json(new { success = true });
}
catch
{
return Json(new { success = false });
}
}
Custom Image Helper
public static IHtmlString Image(this HtmlHelper helper, string src, string alt, string height, string width, params string[] allClasses)
{
TagBuilder tb = new TagBuilder("img");
tb.Attributes.Add("src", VirtualPathUtility.ToAbsolute(src));//throws error
tb.Attributes.Add("alt", alt);
if (!string.IsNullOrEmpty(height) || !string.IsNullOrEmpty(width))
{
StringBuilder value = new StringBuilder();
if (!string.IsNullOrEmpty(height))
value.AppendFormat("height:{0};", height);
if (!string.IsNullOrEmpty(width))
value.AppendFormat("width:{0};", width);
tb.Attributes.Add("style", value.ToString());
}
if (allClasses?.Any() ?? false)
tb.Attributes.Add("class", string.Join(" ", allClasses));
return new MvcHtmlString(tb.ToString(TagRenderMode.SelfClosing));
}
View
<tr>
<td class="Title">
@item.Title
</td>
<td class="Link">
@item.Link
</td>
<td class="filePath">
<a target="_blank" data-id="@item.FilePath" [email protected] >
@Html.Image(item.FilePath, "Image", "60px", "", "img-thumbnail")
</a>
</td>
<td>
<a class="mdlEdit" data-toggle="modal" data-target="#EditRecord">Edit</a>
</td>
</tr>
Partial View Modal
@using(Html.BeginForm("_Edit", "Home", FormMethod.Post, new {id = "Editform", enctype = "multipart/form-data" }))
{
<div class="modal fade" id="EditRecord" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
@Html.HiddenFor(m => m.Id)
@Html.EditorFor(model => model.Title)
@Html.EditorFor(model => model.Link)
@Html.TextBoxFor(m => m.FilePath, new { type = "file"})
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-primary">Save</button>
</div>
</div>
</div>
</div>
}
Script to show existing data into modal
var row;
$(document).on('click', '.mdlEdit', function () {
row = $(this).closest('tr');
var title = $.trim(row.find('.Title').text());
var link = $.trim(row.find('.Link').text());
var filepath = $(this).data("Id");
$('#Title').val(title);
$('#Link').val(link);
$('#FilePath').attr('src', filepath);
})
Script to Submit the form
$('#Editform').submit(function () {
var formdata = new FormData($('#Editform').get(0));
$.ajax({
url: '@Url.Action("_Edit", "Home")',
type: 'POST',
data: formdata,
processData: false,
contentType: false,
success: function(response) {
if (response.success) {
row.find('.Title').text($('#Title').val());
row.find('.Link').text($('#Link').val());
row.find('.filePath').text($('#FilePath').val());
$('#Editform').get(0).reset();
$('#EditRecord').modal('hide');
}
}
});
return false;
})
Upvotes: 0
Views: 350
Reputation:
You have multiple issues with your code. The first thing you should be doing is using a view model, not a data model in the view, and it will contain a public HttpPostedFileBase File { get; set; }
property in addition to your string FilePath
property (refer What is ViewModel in MVC?).
Your file input will then be generated using @Html.TextBoxFor(m => m.File, new { type = "file"})
, and the HttpPostedFileBase FilePath
parameter is not required in your POST method.
Next, in your script to show existing data into modal, you can delete the var filepath = $(this).data("Id");
and $('#FilePath').attr('src', filepath);
. You cannot set the value of a file input programatically for security reasons (it can only be set by the user selecting a file in the browser), and in any case the value of filepath
will be undefined
because the element does not have a data-Id
attribute, and an <input>
does not have a src
attribute.
The main issue with displaying you image is that you need to set the src
attribute the the path that you saved the file on the server, so that you need to return that path in your JsonResult
. Currently your not even saving the file to the server. Modify the controller method to
[HttpPost]
public JsonResult _Edit(EmployeeViewModel model)
{
try
{
ClsEmployee employee = .... // you code to get the data model from the database based on the ID
if (model.File != null && model.File.ContentLength > 0)
{
string fileName = Path.GetFileName(model.File.FileName);
string path = "/Image/" + fileName;
model.File.SaveAs(path);
employee.FilePath = path;
}
.... // map other properties from the view model to the data model - e.g.
employee.Title = model.Title; // etc.
context.SaveChanges();
return Json(new { success = true , filePath = employee.FilePath }); // include the file path in the JsonResult
}
catch
{
return Json(new { success = false });
}
}
Then modify the script to set the src
attribute to the path returned by the controller method
$('#Editform').submit(function () {
var formdata = new FormData($('#Editform').get(0));
$.ajax({
.... // as before
success: function(response) {
if (response.success) {
row.find('.Title').text($('#Title').val());
row.find('.Link').text($('#Link').val());
row.find('.filePath').find('img').attr('src', response.FilePath); // modify this
$('#Editform').get(0).reset();
$('#EditRecord').modal('hide');
}
}
});
return false;
})
Upvotes: 2