2013-06-14 3 views
1

Я новичок в создании пользовательского элемента управления ASP.NET, который будет отображать и возвращать диаграммы .png в веб-приложение ASP.NET.Как обращаться с обработчиком HTTP из UserControl

Я создал простой проект песочницы, который создает эллипс на растровом изображении, превращает его в MemoryStream, и теперь я хочу передать результат, связанный через обработчик HTTP, чтобы отобразить asp: image в моей разметке стр.

Моя проблема заключается в том, что я не знаю, как подключить MemoryStream, созданный в моем usercontrol, к методу GetImage обработчика http. Я знаю, что GetMethod обработчика HTTP, создающего поток памяти внутри метода, неверен, но я не знаю, как получить доступ к запоминающему потоку кода.

Мой прототип код тестового проекта является:

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 Handler является:

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> 

Спасибо за любую помощь, которую вам может обеспечить!

ответ

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 поток в байт преобразования массив из Creating a byte array from a stream

Проверить эту ссылку также http://www.codeproject.com/Articles/34084/Generic-Image-Handler-Using-IHttpHandler

P.S - Я не знаю, почему ваш код выполняется только с конструктором. Без конструктора я могу выполнить код. Когда вы загружаете веб-элемент управления из Handler, обычные события страницы не будут выполняться. Нам нужны методы вызова вручную.

Я думаю, вам нужно разместить свой сайт в IIS, чтобы вызвать HTTpHandler, я не уверен в этой части.

+0

IDE жалуется на 8-ю строчку в коде с красным squiggly под LoadControl и ResolveClientURL с сообщениями, что «Имя« LoadControl »не существует в текущем контексте» и «Имя« ResolveClientURL »не существует в текущий контекст ". – PaulPerkins

+0

@PaulPerkins - я изменил код. Пожалуйста, проверь это. Нам нужно наследовать «Страница» для LoadControl() и ResolveClientURL(). – mlg

+0

спасибо. Я пробовал ваш код, но renderChart никогда не достигается в коде. У вас есть идеи, почему? Еще раз спасибо за ваш опыт в решении этой проблемы! – PaulPerkins

0

Вы находитесь в этом немного назад, используя свой обработчик изображения как страницу - попробуйте подумать о странице как статическом HTML, где вы ссылаетесь на изображение, и ответ довольно прост. Что вам нужно сделать, это добавить тег изображения, ссылающийся на обработчик графического генерации - то есть <img src="~/MyHandler.ashx" />.

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

 Смежные вопросы

  • Нет связанных вопросов^_^