Reputation: 316
My application allow user to upload upload a single image by selecting images with: @Html.TextBoxFor(m => m.Image, new {type = "file"})
. If there was any validation error, I lose its selected file. Therefore I need to temporary save it via If(!ModelState.IsValid)
code block:
public ActionResult Create(MyModel model) {
if (!ModelState.IsValid)
{
if(model.Image != null && model.Image.ContentLength > 0) {
var displayName = Path.GetFileName(model.Image.FileName);
var fileExtension = Path.GetExtension(displayName);
var fileName = string.Format("{0}{1}", Guid.NewGuid(), fileExtension);
var path = Path.Combine(Server.MapPath("~/App_Data/Files"), fileName);
model.Image.SaveAs(path);
model.displayName = displayName;
model.FilePath = path;
return View(model);
}
}
I use @Html.HiddenFor(m => m.FilePath)
in view.
model.Image
type is HttpPostedFileBase
. I must somehow re-gain users selected Image as HttpPostedFileBase
after !ModelState.IsValid
, in order to be able to save it in database. Any chance to pass back info inside @Html.TextBoxFor(m => m.Image, new {type = "file"})
?
How I later convert HttpPostedFileBase to byte[], in order to store image-data in database.
I don't know how to do it with the tools I have.
Edit: model property:
public string displayName { get; set; }
public string FilePath { get; set; }
public HttpPostedFileBase Image { get; set; }
Upvotes: 2
Views: 2335
Reputation:
You cannot set the value of a file input for security reasons (it can only be set by the user selecting a file in the browser).
In the view, you will need a conditional check to display the file name and path (initially it will be null
)
@if (Model.displayName != null)
{
<div>@Model.displayName</div> // let the user know that its been uploaded
@Html.HiddenFor(m => m.FilePath)
}
Then in the controller, if ModelState
is valid, you need to conditionally check the value of FilePath
. In the case where you submit and ModelState
is invalid, the value of FilePath
will now contain the path to the save file when the user re-submits. But in the case where ModelState
is valid on the initial submit, the value of FilePath
will be null
You controller code needs to be (note, this assumes MyModel
is actually a view model, and you have an associated data model containing a property public byte[] Image { get; set; }
for saving the file in the database table
public ActionResult Create(MyModel model)
{
if (!ModelState.IsValid)
{
.... // code as above to save temporary file and return the view
}
// Initialize an instance of your data model
var dataModel = new .... // assumes this contains a property byte[] Image
if (model.FilePath == null)
{
// The code above has never run so read from the HttpPostedFileBase property
if(model.Image != null && model.Image.ContentLength > 0) {
{
MemoryStream target = new MemoryStream();
model.Image.InputStream.CopyTo(target);
dataModel.Image = target.ToArray();
}
}
else
{
// Read from the temporary file
dataModel.Image = System.IO.File.ReadAllBytes(filename);
.... // Delete the temporary file
}
// Map other properties of your view model to the data model
// Save and redirect
}
Upvotes: 1