【问题标题】:How to Reference HTTP Handler from UserControl如何从 UserControl 引用 HTTP 处理程序
【发布时间】:2017-04-04 09:33:27
【问题描述】:

在创建 ASP.NET 自定义用户控件时,我是新手,该控件将呈现 .png 图表并将其返回到 ASP.NET Web 应用程序。

我创建了一个简单的沙盒项目,它在位图上创建一个椭圆,将其渲染到 MemoryStream,现在我想流式传输通过 HTTP 处理程序连接的输出,以便在我的标记页面中渲染一个 asp:image .

我的问题是我不知道如何将在我的用户控件中创建的 MemoryStream 连接到 http 处理程序的 GetImage 方法。我知道在方法中创建内存流的 HTTP Handler 的 GetMethod 不正确,但我不知道如何访问代码隐藏的内存流。

我的原型测试项目代码是:

namespace ChartControl
{
    public partial class ChartCtl : System.Web.UI.UserControl
    {

        private int imageHeight = 150;
        private int imageWidth = 400;

        protected void Page_Load(object sender, EventArgs e)
        {
            renderChart();
        }

        protected MemoryStream renderChart()
        {
            Image imgChart = new Bitmap(imageWidth, imageHeight);
            Graphics g = Graphics.FromImage(imgChart);
            Rectangle r = new Rectangle(0, 0, imageWidth, imageHeight);
            g.DrawEllipse(Pens.Orange, g.VisibleClipBounds);
            MemoryStream ms = new MemoryStream();
            imgChart.Save(ms, ImageFormat.Png);
            return ms;
        }
     }
}

我的 HTTP 处理程序是:

namespace WIChart.UserControls
{
    public class ImageHandler : IHttpHandler
    {
        public void ProcessRequest(HttpContext context)
        {
            context.Response.Clear();

            if (!String.IsNullOrEmpty(context.Request.QueryString["id"]))
            {
                int id = Int32.Parse(context.Request.QueryString["id"]);

                // Now we have the id, just pass it to GetImage to build the image
                Image image = GetImage(id);
                context.Response.ContentType = "image/png";
                image.Save(context.Response.OutputStream, ImageFormat.Png);
            }
            else
            {
                context.Response.ContentType = "text/html";
                context.Response.Write("<p>Valid id is required.</p>");
            }
        }
        #region IHttpHandler Members

        public bool IsReusable
        {
            get { return false; }
        }

        private Image GetImage(int id)
        {
            MemoryStream stream = new MemoryStream();
            return Image.FromStream(stream);
        }
        #endregion
    }

}

我的 .ascx 页面是:

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="ChartCtl.ascx.cs" Inherits="ChartControl.ChartCtl" %>
<%@ Register Assembly="System.Web.DataVisualization, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" Namespace="System.Web.UI.DataVisualization.Charting" TagPrefix="asp" %>


<div class="content-wrapper">
    <div class="float-left">
        <p class="site-title">
            <asp:Image id="imgChart" ImageUrl="~/ImageHandler.ashx?id=1" runat="server" />
        </p>
    </div>
</div>

感谢您提供的任何帮助!

【问题讨论】:

    标签: c# asp.net httphandler


    【解决方案1】:

    我不明白你到底需要什么。但是您可以使用以下代码从用户控件加载图像。

    using System.Web;
    using System.Web.UI;
    using System.IO;
    
    namespace WebApplication1
    {
        public class ImageHandler : Page, IHttpHandler
        {
            public new void ProcessRequest(HttpContext context)
            {
                context.Response.Clear();
                ChartCtl chartCtl = (ChartCtl)LoadControl(ResolveClientUrl("ChartCtl.ascx"));
                MemoryStream ms = new MemoryStream();
                ms = chartCtl.renderChart(ms);
    
                context.Response.Clear();
                context.Response.ContentType = "image/jpeg";
                context.Response.BinaryWrite(ReadFully(ms));
                context.Response.End();
            }
    
            public static byte[] ReadFully(Stream input)
            {
                byte[] buffer = new byte[16 * 1024];
                using (MemoryStream ms = new MemoryStream())
                {
                    int read;
                    while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
                    {
                        ms.Write(buffer, 0, read);
                    }
                    return ms.ToArray();
                }
            }
    
            #region IHttpHandler Members
    
            public new bool IsReusable
            {
                get { return false; }
            }
    
            #endregion
        }
    
    }
    

    HTML-

    <asp:Image ID="imgChart" ImageUrl="~/ImageHandler.ashx" runat="server" />
    

    ChartCtrl -

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.IO;
    using System.Drawing;
    using System.Drawing.Imaging;
    
    namespace WebApplication1
    {
        public partial class ChartCtl : System.Web.UI.UserControl
        {
            private int imageHeight = 150;
            private int imageWidth = 400;
    
            public MemoryStream renderChart(MemoryStream ms)
            {
                Image imgChart = new Bitmap(imageWidth, imageHeight);
                Graphics g = Graphics.FromImage(imgChart);
                Rectangle r = new Rectangle(0, 0, imageWidth, imageHeight);
                g.DrawEllipse(Pens.SteelBlue, g.VisibleClipBounds);
                imgChart.Save(ms, ImageFormat.Jpeg);                    // save the image to the memorystream to be processed via the Image/HttpHandler
                imgChart.Save(Context.Response.OutputStream, ImageFormat.Jpeg);    // save to drive just to verify that image is being properly created.
                return ms;
            }
        }
    }
    

    Web.Config [IIS 7] -

    <system.webServer>
        <modules runAllManagedModulesForAllRequests="true"/>
        <handlers>
          <add name="ImageHandler" verb="*"
           path="ImageHandler.ashx"
           type="WebApplication1.ImageHandler, WebApplication1"
           resourceType="Unspecified" />
        </handlers>
      </system.webServer>
    

    Mem Stream 到字节数组的转换是从Creating a byte array from a stream

    也请查看此链接http://www.codeproject.com/Articles/34084/Generic-Image-Handler-Using-IHttpHandler

    P.S - 我不知道为什么您的代码只使用构造函数执行。没有构造函数,我可以执行代码。当您从 Handler 加载 Web 控件时,不会执行正常的页面事件。我们需要手动调用方法。

    我认为您需要在 IIS 中托管您的网站才能调用 HTTpHandler,我不确定这部分。

    【讨论】:

    • IDE 抱怨代码中的第 8 行,在 LoadControl 和 ResolveClientURL 下方有一个红色波浪线,并显示“当前上下文中不存在名称 'LoadControl'”和“名称 'ResolveClientURL ' 在当前上下文中不存在。"
    • @PaulPerkins - 我已经修改了代码。请检查一下。我们必须为 LoadControl() 和 ResolveClientURL() 继承 Page
    • 谢谢。我尝试了您的代码,但代码中从未达到 renderChart。你有什么想法为什么?再次感谢您在解决此问题方面的专业知识!
    • 我已经编辑了我上面的代码以合并您建议的解决方案。问题是永远无法达到 renderChart()。
    • ... 直到我向 ChartCtl 添加了一个构造函数;但现在,正在到达 ChartCtl,但从未命中 ImageHandler(我在 ProcessRequest 和 ReadFully 方法中插入了从未到达过的断点)。
    【解决方案2】:

    将图像处理程序用作页面时,您有点倒退了——尝试将页面视为您引用图像的静态 HTML,答案非常简单。您需要做的是添加一个引用您的图形生成处理程序的图像标签——即&lt;img src="~/MyHandler.ashx" /&gt;

    接下来的挑战就变成了如何将数据编组到处理程序中。有很多方法可以处理这个问题,如果数据很简单,基本的方法是查询字符串变量,或者是具有足够数据的查询字符串,以便处理程序可以返回并加载它自己的数据。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-14
      • 1970-01-01
      • 2012-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多