ASp.Net Mvc 1.0 Динамические изображения, возвращаемые из контроллера, занимающие 154 секунды + для быстрого и простого отображения в IE8, Firefox и всех других браузерах - PullRequest
0 голосов
/ 13 марта 2010

У меня возникла любопытная проблема с динамическими PNG-файлами в IE, IIS 6.0, и я озадачен тем, как это исправить.

Snippet from Helper (возвращает URL к представлению для запроса изображений из моего контроллера.

string url = LinkBuilder.BuildUrlFromExpression (helper.ViewContext.RequestContext, helper.RouteCollection, c => c.FixHeight (ir.Filename, ir.AltText, "FFFFFF")); url = url.Replace ("&", "&"); sb.Append (string.Format ("<<em> удалено id = \" TheImage \ "src = \" {0} \ "alt = \" \ "/>", url) + Environment.NewLine) ;

Это дает кусок HTML следующим образом: - img id = "TheImage" src = "/ ImgText / FixHeight? sFile = Изображения% 2FUser% 2FJulianGuppy% 2FMediums% 2Fconservatory.jpg & backgroundColour = FFFFFF" alt = "" /

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

Фрагмент из контроллера ImgTextController

    /// <summary>
    /// This function fixes the height of the image
    /// </summary>
    /// <param name="sFile"></param>
    /// <param name="alternateText"></param>
    /// <param name="backgroundColour"></param>
    /// <returns></returns>
    [AcceptVerbs(HttpVerbs.Get)]
    public ActionResult FixHeight(string sFile, string alternateText, string backgroundColour)
    {
        #region File
        if (string.IsNullOrEmpty(sFile))
        {
            return new ImgTextResult();
        }
        // MVC specific change to prepend the new directory
        if (sFile.IndexOf("Content") == -1)
        {
            sFile = "~/Content/" + sFile;
        }

        // open the file
        System.Drawing.Image img;
        try
        {
            img = System.Drawing.Image.FromFile(Server.MapPath(sFile));
        }
        catch
        {
            img = null;
        }
        // did we fail?
        if (img == null)
        {
            return new ImgTextResult();
        }
        #endregion File

        #region Width
        // Sort out the width from the image passed to me
        Int32 nWidth = img.Width;
        #endregion Width

        #region Height
        Int32 nHeight = img.Height;
        #endregion Height

        // What is the ideal height given a width of 2100 this should be 1400.
        var nIdealHeight = (int)(nWidth / 1.40920096852);
        // So is the actual height of the image already greater than the ideal height?
        Int32 nSplit;

        if (nIdealHeight < nHeight)
        {
            // Yes, do nothing, well i need to return the iamge...
            nSplit = 0;
        }
        else
        {
            // rob wants to not show the white at the top or bottom, so if we were to crop the image how would be do it
            // 1. Calculate what the width should be If we dont adjust the heigt
            var newIdealWidth = (int)(nHeight * 1.40920096852);

            // 2. This newIdealWidth should be smaller than the existing width... so work out the split on that
            Int32 newSplit = (nWidth - newIdealWidth) / 2;

            // 3. Now recrop the image using 0-nHeight as the height (i.e. full height)
            // but crop the sides so that its the correct aspect ration
            var newRect = new Rectangle(newSplit, 0, newIdealWidth, nHeight);

            img = CropImage(img, newRect);
            nHeight = img.Height;
            nWidth = img.Width;
            nSplit = 0;
        }

        // No, so I want to place this image on a larger canvas and we do this by Creating a new image to be the size that we want
        System.Drawing.Image canvas = new Bitmap(nWidth, nIdealHeight, PixelFormat.Format24bppRgb);
        Graphics g = Graphics.FromImage(canvas);

        #region Color
        // Whilst we can set the background colour we shall default to white
        if (string.IsNullOrEmpty(backgroundColour))
        {
            backgroundColour = "FFFFFF";
        }
        Color bc = ColorTranslator.FromHtml("#" + backgroundColour);
        #endregion Color

        // Filling the background (which gives us our broder)
        Brush backgroundBrush = new SolidBrush(bc);
        g.FillRectangle(backgroundBrush, -1, -1, nWidth + 1, nIdealHeight + 1);

        // draw the image at the position
        var rect = new Rectangle(0, nSplit, nWidth, nHeight);
        g.DrawImage(img, rect);

        return new ImgTextResult { Image = canvas, ImageFormat = ImageFormat.Png };
    }

My ImgTextResult - это класс, который возвращает мне результат Action, но встраивает изображение из потока памяти в response.outputstream.

фрагмент из моего ImageResults

    /// <summary>
    /// Execute the result
    /// </summary>
    /// <param name="context"></param>
    public override void ExecuteResult(ControllerContext context)
    {
        // output
        context.HttpContext.Response.Clear();
        context.HttpContext.Response.ContentType = "image/png";

        try
        {
            var memStream = new MemoryStream();
            Image.Save(memStream, ImageFormat.Png);
            context.HttpContext.Response.BinaryWrite(memStream.ToArray());
            context.HttpContext.Response.Flush();
            context.HttpContext.Response.Close();
            memStream.Dispose();
            Image.Dispose();
        }
        catch (Exception ex)
        {
            string a = ex.Message;
        }
    }

Теперь все это работает локально и прекрасно, и действительно все это работает на моем производственном сервере

НО Только для Firefox, Safari, Chrome (и других браузеров) IE подходит, и решает, что он либо не будет отображать изображение, либо отображает изображение примерно через 154 секунды ожидания .....

Я удостоверился, что мой HTML совместим с XHTML, я удостоверился, что я не получаю ошибок маршрутизации или сбоев в моем журнале событий на сервере ....

Теперь, очевидно, я был маппетом и сделал что-то не так ... но я не могу понять, почему в разработке все работает нормально, а в работе все браузеры, не поддерживающие IE, также работают нормально, но IE 8 использует рабочий сервер IIS 6.0 Возникает какая-то проблема с возвратом этого PNG, и у меня нет ошибки для отслеживания ... так что я ищу руководство о том, как я могу отладить эту проблему.

Ответы [ 3 ]

0 голосов
/ 14 марта 2010

Ну, я хотел конвертировать мои изображения (jpg, bmp и т. Д. И возвращать их как png) - однако. Хотя все другие браузеры принимали кодировку и отображали их нормально, IE решил скрыть изображение png (после его частичного отображения), поскольку считало, что это не изображение PNG. (Хотя это так и было) Поэтому я отказался от методов конвертации и просто вернул изображение в исходном формате. ---

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

Так что я закрываю это сейчас, поскольку IE выиграл эту битву -

Хотел бы я, чтобы IE просто отвалился и умер. Я так ненавижу IE. Серьезно это просто сосет пот шариков мертвецов.

0 голосов
/ 16 октября 2011

Никогда не вызывать Response.End ()

По крайней мере, так говорит сопровождающий документации HttpResponse .

Response.End () завершает соединение http, часто теряя данные в буфере сервера или где-то в потоке. Вместо этого лучше позволить IIS завершить соединение (или повторно использовать его), поскольку многие клиенты не имеют идеального сетевого стека.

IE имеет ужасный сетевой стек (как может засвидетельствовать любой, кто использовал IETab для FF, IE работает очень быстро, когда размещается поверх сетевого канала FF). Другие браузеры обрабатывают быстро закрытое соединение намного лучше, и поэтому, вероятно, не плохо реагируют на закрытое соединение.

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

Исходя из кода, который я вижу, похоже, что вы пропускаете растровое изображение GDI 'img', и могут возникнуть дополнительные утечки, если во время запроса произойдет что-то неожиданное. Обратите внимание, что .NET не обрабатывает сборщик мусора GDI должным образом, и это одна из главных причин сбоев сервера - убедитесь, что вы исправили это, мой друг:)

0 голосов
/ 13 марта 2010

Похоже, пора установить Fiddler или HttpWatch и выяснить, что происходит.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...