在创建ASP.NET自定义用户控件时,我是一个新手,它将呈现并将.png图表返回到ASP.NET Web应用程序。
我创建了一个简单的沙箱项目,它在位图上创建一个椭圆,将其呈现给MemoryStream,现在我想通过HTTP处理程序流输出连接的输出,以便在我的标记页面中呈现一个asp:image 。
我的问题是我不知道如何将我的usercontrol中创建的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>
感谢您提供任何帮助!
答案 0 :(得分: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,我不确定此部分。
答案 1 :(得分:0)
使用图像处理程序作为页面,你会稍微向后看 - 尝试将页面视为静态HTML,您正在引用图像,答案非常简单。您需要做的是添加引用图形生成处理程序的图像标记 - 即<img src="~/MyHandler.ashx" />
。
然后挑战变成如何将数据编组到处理程序中。有很多方法可以处理这个问题,基本的方法是查询字符串变量,如果数据很简单,或者查询字符串有足够的数据,那么处理程序可以返回并加载它自己的数据。