Webhandler не стреляет при обратной передаче - PullRequest
3 голосов
/ 11 января 2010

У меня есть веб-приложение, в которое я загружаю изображение, изображение впоследствии сохраняется во временной папке сервера и отображается через веб-обработчик на странице aspx.

код для aspx:

<img src="PreviewImageQualityHandler.ashx" alt="Picture not loaded" runat="server" id="imagePreview" />

Код для загрузки изображения и добавления уникального идентификатора в сеанс:

protected void uploadButton_Click(object sender, EventArgs e)
{
    if (FileUploadControl.FileName.EndsWith(".jpg") || FileUploadControl.FileName.EndsWith(".jpeg"))
    {
        string tempFileName = Path.GetTempFileName();
        FileUploadControl.SaveAs(tempFileName);
        Session["tempName"] = tempFileName;
        Response.Write(Session["tempName"]);
        fileName = FileUploadControl.FileName;
    }
    else
    {
        Response.Write("<script>alert('Please select a .jpg/.jpeg image to upload')</script>");
    }
}

Код веб-обработчика:

public class PreviewImageQualityHandler : IHttpHandler, IRequiresSessionState
{   
    public void ProcessRequest(HttpContext context)
    {
        try
        {
            if (context.Session.Count > 0)
            {
                string sessID = context.Session["tempName"].ToString();
                Bitmap bmp = (Bitmap)System.Drawing.Image.FromFile(sessID);
                context.Response.ContentType = "image/jpg";
                MemoryStream ms = new MemoryStream();
                bmp.Save(ms, ImageFormat.Bmp);
                byte[] b = ms.ToArray();
                context.Response.OutputStream.Write(b, 0, b.Length);
            }
        }
        catch(Exception ex) 
        { 

        }
    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
}

Моя проблема в том, что веб-обработчик запускается только при первой загрузке изображения. Если я пытаюсь загрузить новое изображение, веб-обработчик никогда не запускается.

Если я удаляю все, что связано с Session, из веб-обработчика, он запускается при каждой обратной передаче, как и должно быть.

Если кто-нибудь сможет пролить свет на мою проблему, я буду чрезвычайно признателен!

Привет

Francis

1 Ответ

4 голосов
/ 11 января 2010

ОК, переписайте мой ответ (смотрите историю, если вы еще не видели предыдущих ответов). Несколько примечаний к вашему коду:

  1. Не используйте Response.Write. Вы не можете определить, когда он будет писать, и часто вы не увидите его в браузере. Используйте взамен asp:Literal или asp:Label. Связано с текущей проблемой, потому что: если вы не видите ее в браузере, возможно, вы думаете, что ничего не происходит.

  2. Вы не можете безопасно открывать / закрывать файловый поток. Добавьте using -блок вокруг него, чтобы поток был правильно закрыт и удален. Как у вас сейчас, файл останется открытым, пока поток жив, и это довольно долго.

    using(Bitmap bmp = (Bitmap)System.Drawing.Image.FromFile(sessID))
    {
         //.. your code...
         using(MemoryStream.... etc)
         {
             ....
         }
    }
    

    Проблема с закрытием: вы не сможете записать новый файл в то же место в следующий раз, вы не сможете открыть его для чтения, и вы очень быстро исчерпаете доступные обработчики файлов, когда ваш код запускается.

  3. Не уверен, что вы ожидаете от сеанса. Но, вероятно, лучше использовать некоторый идентификатор с изображением, сохранить его в базе данных с информацией о текущем пользователе и добавить его в качестве строки запроса запроса к URL-адресу изображения. Таким образом, у вас не будет проблем с сессиями:

    <img src="myimage.ashx?id=1234" />
    

    Либо 1234 относится к чему-то на диске, либо к чему-то в базе данных, что, в свою очередь, относится к чему-то на диске (гораздо безопаснее).

  4. Если вы не уверены, отправляет ли браузер запрос повторно, используйте FireBug с FireFox, который предоставляет вам полную информацию о HTTP-запросах и ответах. Если вы используете одно и то же имя, браузер (если вы не находитесь в режиме отладки) не будет каждый раз отправлять новый запрос.

  5. Вы используете универсальный обработчик исключений. Напишите что-нибудь там или установите точку останова в этой позиции. Универсальный обработчик исключений очень опасен: многие исключения никогда не будут видны. Вполне возможно, ваш текущий код вызывает исключение (см. Пункт 2 выше) и все. Удалите обработчик исключений и исключение будет перехвачено вашим отладчиком Visual Studio, чтобы вы знали, что случилось.

Я знаю, довольно много проблем. Просмотрите их один за другим и посмотрите, поможет ли это. По крайней мере, ваш код станет более стабильным.

...