C# 如何从UserControl引用HTTP处理程序

C# 如何从UserControl引用HTTP处理程序,c#,asp.net,httphandler,C#,Asp.net,Httphandler,在创建ASP.NET自定义用户控件时,我是个新手,该控件将呈现.png图表并将其返回给ASP.NET web应用程序 我已经创建了一个简单的沙盒项目,该项目在位图上创建一个椭圆,将其渲染到MemoryStream,现在我希望通过HTTP处理程序对连接的输出进行流式处理,以便在我的标记页面中渲染asp:图像 我的问题是,我不知道如何将usercontrol中创建的MemoryStream连接到http处理程序的GetImage方法。我知道HTTP处理程序在方法中创建内存流的GetMethod是不正

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

我已经创建了一个简单的沙盒项目,该项目在位图上创建一个椭圆,将其渲染到MemoryStream,现在我希望通过HTTP处理程序对连接的输出进行流式处理,以便在我的标记页面中渲染asp:图像

我的问题是,我不知道如何将usercontrol中创建的MemoryStream连接到http处理程序的GetImage方法。我知道HTTP处理程序在方法中创建内存流的GetMethod是不正确的,但我不知道如何访问codebehind的memorystream

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

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
    }

}
namespace WIChart.UserControls
{
公共类ImageHandler:IHttpHandler
{
公共void ProcessRequest(HttpContext上下文)
{
context.Response.Clear();
如果(!String.IsNullOrEmpty(context.Request.QueryString[“id”]))
{
intid=Int32.Parse(context.Request.QueryString[“id”]);
//现在我们有了id,只需将其传递给GetImage即可构建图像
Image=GetImage(id);
context.Response.ContentType=“image/png”;
image.Save(context.Response.OutputStream,ImageFormat.Png);
}
其他的
{
context.Response.ContentType=“text/html”;
context.Response.Write(“需要有效id.

”; } } #区域IHttpHandler成员 公共布尔可重用 { 获取{return false;} } 私有映像GetImage(int-id) { MemoryStream stream=新的MemoryStream(); 返回Image.FromStream(stream); } #端区 } }
我的.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>


感谢您提供的任何帮助

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

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-

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>

也请检查此链接

我不知道为什么你的代码只能用构造函数执行。没有构造函数,我可以执行代码。当您从处理程序加载web控件时,将不会执行正常的页面事件。我们需要手动调用方法


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

我无法理解您到底需要什么。但您可以使用下面的代码从用户控件加载图像

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-

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>

也请检查此链接

我不知道为什么你的代码只能用构造函数执行。没有构造函数,我可以执行代码。当您从处理程序加载web控件时,将不会执行正常的页面事件。我们需要手动调用方法


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

您将imagehandler用作页面的做法有点倒退--尝试将页面视为静态HTML,其中引用的是图像,答案非常简单。您需要做的是添加一个引用图形生成处理程序的图像标记——即


接下来的挑战是如何将数据封送到处理程序中。有很多方法可以处理这个问题,基本的方法是查询字符串变量,如果数据很简单,或者查询字符串包含足够的数据,那么处理程序可以返回并加载自己的数据

将imagehandler用作页面的做法有点倒退——尝试将页面视为静态HTML,在这里引用图像,答案非常简单。您需要做的是添加一个引用图形生成处理程序的图像标记——即


接下来的挑战是如何将数据封送到处理程序中。有很多方法可以处理这个问题,基本的方法是查询字符串变量,如果数据很简单,或者查询字符串包含足够的数据,那么处理程序可以返回并加载自己的数据

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