I'm having a big headache with the following:
private bool AddImageToUser(HttpPostedFileBase photo)
{
string userId = FormsAuthentication.Decrypt(Request.Cookies[FormsAuthentication.FormsCookieName].Value).UserData.Split('|')[0];
string newPath = "", path = "";
string userDir = System.Web.HttpContext.Current.Server.MapPath(vars.getKeyValue("usersImagesPath") + "/" + userId);
System.IO.Directory.CreateDirectory(userDir);//create directory if it doesn't exist
bool valid = false;
try
{
path = Directory.GetFiles(userDir, "*foto_perfil.*").First();
if (path.Length > 0 && path != null)
{
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(path);
newPath = path.Replace(fileNameWithoutExtension, fileNameWithoutExtension + "_old");
System.IO.File.Move(path, newPath);
//The exception i'm refering to, happens with this File.Move
}
}
catch { }
//add a new image and replace the old one
try
{
HttpPostedFileBase attFile = photo;
int attachFileLength = attFile.ContentLength;
if (attachFileLength > 0)
{
string _name = attFile.FileName;
_name = _name.Substring(_name.LastIndexOf('\\') + 1);
string nome_ficheiro = DateTime.Now.ToString("ddMMyyyyhhmmfff") + "foto_perfil." + Path.GetExtension(attFile.FileName).Substring(1).ToLower();
attFile.SaveAs(System.Web.HttpContext.Current.Server.MapPath(vars.getKeyValue("usersImagesPath") + "/" + userId + "/" + nome_ficheiro)); //falta fazer o upload do ficheiro
if (newPath != "")
System.IO.File.Delete(newPath);
valid = true;
}
}
catch
{
//If there is an error saving new image, put the old one back if it exists
System.IO.File.Move(path, newPath);
valid = false;
}
return valid;
}
What i'm trying there is, discover the full path, to the only image file that is on a directory, and then in the variable "newPath" i get the that same path but with a rename. But when i get to File.Move, wich the intention is to rename the file using the "newPath" i get most of the times the error:
The process cannot access the file ... because it is being used by another process
StackTrace
StackTrace " em System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)\r\n em System.IO.__Error.WinIOError()\r\n em System.IO.File.InternalMove(String sourceFileName, String destFileName, Boolean checkHost)\r\n em System.IO.File.Move(String sourceFileName, String destFileName)\r\n em PGR_01.Controllers.AccountController.AddImageToUser(HttpPostedFileBase photo) em c:\\Dev\\Websites\\MVC\\PGR_01\\PGR_01\\Controllers\\AccountController.cs:line 409" string
Btw, in the same Razor page that i use to upload the new image, i'm displaying the last image upload, getting the path with a custom attribute:
In the page:
<img class="col-md-6 col-md-offset-3" src="/util/imgLoader2.ashx?h=214&w=320&img=@Html.pathOfUserPhoto()"/>
code:
public static MvcHtmlString pathOfUserPhoto(this HtmlHelper htmlHelper)
{
string userId = FormsAuthentication.Decrypt(HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName].Value).UserData.Split('|')[0];
string htmlString, userDir = System.Web.HttpContext.Current.Server.MapPath(vars.getKeyValue("usersImagesPath") + "/" + userId);
//using
//{
try
{
htmlString = Directory.GetFiles(userDir, "*foto_perfil.*").First();
}
catch
{
htmlString = "";
}
return new MvcHtmlString(htmlString);
//return MvcHtmlString.Empty;
}
I don't think it has anything to do with it.
What am i doing wrong? Is there a better way to do this?
Note: this error never happens if the folder is empty. Note 2: If i try to delete the file manually after being upload sometimes i can't because it says it's already being used by "IIS Express Worker Process"
EDIT:
I've found what is causing the lock, it's the following IHttpHandler that i call in the source of the img element. Is there something i can do to prevent it from locking the image?
public class imgLoader2 : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
int Width = 0;
int Height = 0;
string imgFile = vars.serverFolder;
string imgName = context.Request.QueryString["img"];
//string def = "/upload/blank.jpg";
string def = "/Uploads/blank.jpg";
System.Drawing.Image imgPhoto = null;
ImageFormat format = ImageFormat.Jpeg;
context.Request.ContentType = "image/jpeg";
ImageResize imgUtil = new ImageResize();
// HttpContext.Current.Response.Cache.SetExpires(yourCalculatedDateTime);
context.Response.Cache.SetCacheability(HttpCacheability.Public);
context.Response.Cache.SetExpires(DateTime.Now.AddDays(8));
context.Response.Cache.SetLastModified(DateTime.Now);
if(string.IsNullOrEmpty(imgName))
imgName=def;
if (context.Request.QueryString.Count > 0)
{
if (context.Request.QueryString["h"] != null)
Height = Convert.ToInt16(context.Request.QueryString["h"]);
if (context.Request.QueryString["w"] != null)
Width = Convert.ToInt16(context.Request.QueryString["w"]);
if (!string.IsNullOrEmpty(imgName))
{
imgPhoto = imgUtil.imgThumbCropTop(imgFile + imgName, Width, Height);
}
else
{
imgPhoto = imgUtil.imgThumbCropTop(context.Server.MapPath("~/" + def), Width, Height);
}
//imgPhoto = imgUtil.imgThumb(imgFile + imgName, Height);
}
else
{
imgPhoto = imgUtil.imgThumbCropTop(context.Server.MapPath("~/" + def), Width, Height);
}
if (imgName.ToLower().EndsWith(".gif"))
{
format = ImageFormat.Gif;
context.Response.ContentType = "image/gif";
}
else if (imgName.ToLower().EndsWith(".png"))
{
format = ImageFormat.Png;
context.Response.ContentType = "image/png";
}
else
{
format = ImageFormat.Jpeg;
context.Response.ContentType = "image/jpeg";
}
try
{
imgPhoto.Save(context.Response.OutputStream, format);
}
catch
{
//context.Request.ContentType = "image/gif";
imgPhoto = imgUtil.imgThumbCrop(context.Server.MapPath("~/" + def), Width, Height);
imgPhoto.Save(context.Response.OutputStream, format);
}
}
public bool IsReusable
{
get
{
return false;
}
}
}