ASP.NET - 在GridView中显示图像和pdf

时间:2009-11-28 23:40:27

标签: .net asp.net gridview webforms ashx

我想在asp:GridView中显示一个“Images”列。我们的想法是提供图像的缩略图,并链接到实际尺寸的图像。对于某些行,这可以替代地是PDF文档。我想要链接到PDF。 PDF或图像存储在SQL数据库中。

现在我在Handler(.ashx)文件中有错误:

  

“没有数据时无效尝试读取。”

这是我的代码:

ASP:

<asp:GridView ID="GridView1" runat="server" 
            AutoGenerateColumns="False" DataKeyNames="ID"
            DataSourceID="SqlDataSource1">
   <Columns>
      <asp:BoundField DataField="assessment_id" HeaderText="assessment_id" 
                    InsertVisible="False" ReadOnly="True"
                    SortExpression="assessment_id" />
      <asp:BoundField DataField="a_mime" HeaderText="a_mime" SortExpression="a_mime" />
      <asp:TemplateField HeaderText="a_data">       
        <ItemTemplate>
        <asp:Image ID="Image1" runat="server" ImageUrl='<%# "Handler.ashx?ID=" + Eval("ID")%>'/>
        </ItemTemplate>
      </asp:TemplateField>
  </Columns>
</asp:GridView>

<asp:SqlDataSource ID="SqlDataSource1" runat="server" 
  ConnectionString="<%$ ConnectionStrings:testConnectionString %>"
  SelectCommand="SELECT [assessment_id], [a_data], [a_mime] FROM [Assessments]">    
</asp:SqlDataSource>

处理程序ASHX:

<%@ WebHandler Language="C#" Class="Handler" %>

public class Handler : IHttpHandler {

public void ProcessRequest (HttpContext context) 
{
    SqlConnection con = new SqlConnection();
    con.ConnectionString = ConfigurationManager.ConnectionStrings["testConnectionString"].ConnectionString;

    // Create SQL Command 
    SqlCommand cmd = new SqlCommand();
    cmd.CommandText = "Select a_data from Assessments where assessment_id =@ID";
    cmd.CommandType = System.Data.CommandType.Text;
    cmd.Connection = con;

    SqlParameter ImageID = new SqlParameter("@ID", System.Data.SqlDbType.Int);
    ImageID.Value = Convert.ToInt32(context.Request.QueryString["assessment_id"]);
    cmd.Parameters.Add(ImageID);
    con.Open();

    SqlDataReader dReader = cmd.ExecuteReader();
    dReader.Read();

    context.Response.BinaryWrite((byte[])dReader["a_data"]);

    dReader.Close();

    con.Close();
}

如果有可能,请帮助我。如果耗时,请提供示例或博客文章的链接。

1 个答案:

答案 0 :(得分:1)

Invalid attempt to read when no data is present错误的原因是因为DataReader不包含任何记录(给定ID没有图像)。 考虑将您的代码更改为:

SqlDataReader dReader = cmd.ExecuteReader();

if (dReader.HasRows)
{
  while (dReader.Read())
  {
     context.Response.BinaryWrite((byte[])dReader["a_data"]);
  }

  dReader.Close();
}

一些改进建议

  • 尝试预测某行何时没有图像
  • 当您可以在ASP.NET页面上检测到时,执行对.ashx页面的调用
  • 当您检测到需要呈现PDF链接时,请显示一个漂亮的静态pdf图像,其链接将是URL。

考虑在可能的情况下检查给定的评估是否需要图像或PDF。也许添加一个where子句以某种方式确定此记录是否需要显示PDF或图像场景。

我可以建议您将SQL语句转换为存储过程,如上所述,并修改您的SqlDataSource:     

CREATE PROC ListAssessments
AS

SELECT [assessment_id]
     , [a_data]
     , [a_mime] 
     , CASE WHEN a_mime = 'PDF' THEN 1
       ELSE 0
       END AS IsPDF

FROM Assessments  

现在,在Gridview上,您可以确定是要渲染图像还是PDF链接。

<asp:TemplateField HeaderText="Image">       
  <ItemTemplate>
     <asp:PlaceHolder id="ph1" runat="server" />    
  </ItemTemplate>
</asp:TemplateField>

将Gridview设置为具有ItemDataBound事件,该事件调用您可以编写的新方法。

<asp:GridView OnRowDataBound="ShowImageOrPdf" 

在您的代码隐藏中,您可以确定要在该占位符中呈现的webcontrol。

protected void ShowImageOrPdf(object sender, GridViewRowEventArgs e)
{
    const string LINK = "handler.ashx?Id={0}&Type={1}";
    GridView gv = (GridView)sender;

    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        string assessmentID = gv.DataKeys[e.Row.RowIndex].Value.ToString();
        bool isPDF =  (bool)e.Row.DataItem["IsPDF"];
        HyperLink h = new HyperLink();

        if (isPDF)
        {
            //render a link showing that it's a PDF.
            h.NavigateUrl = string.Format(LINK, assessmentID, "PDF");
            h.ImageUrl = "http://www.adobe.com/images/pdficon_large.gif";
            h.Text = "View PDF";
        }
        else
        {
            //render a thumbnail with a link to the image
            h.NavigateUrl = string.Format(LINK, assessmentID, "IMG");

            //have the handler create a thumbnail somehow.
            h.ImageUrl = string.Concat(h.NavigateUrl + "&Size=Small");
        } 
       //write the link back to the placeholder.
       e.Row.FindControl("ph1").Controls.Add(h);
    }
}

然后在.ashx中,您必须阅读查询字符串参数以确定要输出的内容:图像,缩略图图像或存储在数据库中的PDF文档。