First and foremost, let's not store the Image in the database, but rather a reference to our image.
public class BUser {
public int Id {get;set;}
public string ImagePath {get;set;}
}
Now, in our Action lets POST up the image, save it in the relevant directory, say /Images/UserImages and then store a reference to that image on our class!
So to start here is the ActionResult with references to an ImageService we are going to use:
public ActionResult FileUpload(HttpPostedFileBase file)
{
if (file.ContentLength > 0 && _imageService.IsValidImageType(file.ContentType))
{
const string imagePath = "/Images/UserImages/";
string uploadedImage = _imageService.UploadImage(file, Server.MapPath(imagePath));
string uploadedPath = string.Format("{0}{1}",imagePath, uploadedImage);
if (uploadedPath.Contains("Fail"))
{
return RedirectToAction("Failed", "BPatient");
}
var bUser = new BUser() {Image = uploadedPath};
//Save to DB
}
return RedirectToAction("Display", "BPatient");
}
In reality we don't want to bloat the Controller action this much, however I am trying to keep it similar to what you already had, so it's not a complete rewrite. Now here is the code for our service which will Upload our image, and check its a valid type of image
//Extract this to a service or helper
private readonly string[] _validFileTypes = new[] { "image/jpeg", "image/pjpeg", "image/png", "image/gif" };
public string UploadImage(HttpPostedFileBase file, string path)
{
if (file != null)
{
try
{
string fileName = System.IO.Path.GetFileName(file.FileName);
if (string.IsNullOrEmpty(fileName))
{
return "Fail";
}
if (!IsValidImageType(file.ContentType))
{
return "Fail";
}
}
catch (Exception ex)
{
return "Fail";
}
string extensionlessName = NameWithoutExtesion(file.FileName);
string randomName = System.IO.Path.GetRandomFileName();
string pathMain = string.Format("{0}{1}{2}{3}", path, extensionlessName, randomName, System.IO.Path.GetFileName(Path.GetExtension(file.FileName)));
try
{
file.SaveAs(pathMain);
return string.Format("{0}{1}{2}", extensionlessName, randomName, System.IO.Path.GetFileName(Path.GetExtension(file.FileName)));
}
catch (Exception ex)
{
return "Fail";
}
}
return "Fail";
}
And here are two small methods from the Service that will just chop down the overall size of UploadImage
public bool IsValidImageType(string fileType)
{
if (string.IsNullOrEmpty(fileType))
{
return false;
}
if (!_validFileTypes.Contains(fileType))
{
return false;
}
return true;
}
public string NameWithoutExtesion(string name)
{
if (!name.Contains("."))
{
return name;
}
int index = name.LastIndexOf('.');
string newName = name.Substring(0, index);
return newName;
}
This is from what I can tell a working solution. Naturally it will require some more work for inserting into the database however I have left a comment there for you to put that code in.
Although the Service would work straight from a Copy-Paste the Action will need a little of your work. And once it's all hooked up I recommend you try and see what was done differently.