Search code examples
asp.net-mvcimageresponseoutputstream

ASP.NET MVC Image in response output stream. Not working


I want to display an image directly into the view and so I am calling an action method and writing the image in output stream.

But I am getting error saying "The image cannot be displayed as it contains error". I am sure the image is generating properly but not sure whats wrong with my controller code.. had anyone came across such scenario?

Thanks in advance..

Here is my controller action

[ChildActionOnly]
    public ActionResult GetCaptcha()
    {

        try
        {
            this.Session["CaptchaImageText"] = GenerateRandomCode();

            this.Response.Clear();

            this.Response.ContentType = "image/jpeg";

            Bitmap img = new Bitmap(Server.MapPath("../Images/captcha.jpg"));

            Graphics graphicImage = Graphics.FromImage(img);
            graphicImage.SmoothingMode = SmoothingMode.AntiAlias;

            graphicImage.DrawString(this.Session["CaptchaImageText"].ToString(),
                                    new Font("Arial", 12, FontStyle.Bold),
                                    SystemBrushes.WindowText, new Point(100, 250));

            graphicImage.DrawArc(new Pen(Color.Red, 3), 90, 235, 150, 50, 0, 360);

            //Save the new image to the response output stream.
            img.Save(this.Response.OutputStream, ImageFormat.Jpeg); 

            // Create a CAPTCHA image using the text stored in the Session object.

            graphicImage.Dispose();
            img.Dispose();
        }
        catch (Exception ex)
        {
            ex = null;
        }
        var v = new FileStreamResult(Response.OutputStream,"image/jpeg");
        return v;
    }

And here is how I am calling the action method from view

    <tr><td> <iframe width="200px" height="80px" frameborder="1" scrolling="no"> <img src="@Url.Action("GetCaptcha")" alt="SimpleChart" /> </iframe>  </td></tr>

Solution

  • You need to return file instead of EmptyResult.

    return File(imageByteData, "image/png"); 
    

    and in the view side:

    <tr><td> <iframe>  <img src='@Url.Action("GetCaptcha")'/> </iframe>  </td></tr>
    

    Update

    Don't write to response instead do like below.

    [ChildActionOnly]
    public ActionResult GetCaptcha()
    {
    
        try
        {
            byte[] imageByteData = null
            this.Session["CaptchaImageText"] = GenerateRandomCode();
    
            this.Response.Clear();
    
            this.Response.ContentType = "image/jpeg";
    
            Bitmap img = new Bitmap(Server.MapPath("../Images/captcha.jpg"));
    
            Graphics graphicImage = Graphics.FromImage(img);
            graphicImage.SmoothingMode = SmoothingMode.AntiAlias;
    
            graphicImage.DrawString(this.Session["CaptchaImageText"].ToString(),
                                    new Font("Arial", 12, FontStyle.Bold),
                                    SystemBrushes.WindowText, new Point(100, 250));
    
            graphicImage.DrawArc(new Pen(Color.Red, 3), 90, 235, 150, 50, 0, 360);
    
            MemoryStream stream = new MemoryStream();
                bitmap.Save(stream, ImageFormat.Jpeg);
                imageByteData = stream.ToArray();
    
            // Create a CAPTCHA image using the text stored in the Session object.
    
            graphicImage.Dispose();
            img.Dispose();
            return File(imageByteData, "image/png"); 
        }
        catch (Exception ex)
        {
            ex = null;
        }
    
    }