通过外键获取图像

时间:2011-03-22 09:45:59

标签: c# .net asp.net

我有表有关于产品照片的数据,这张表与产品表和产品有关,可能比Image更多。我很好地完成了我的代码,通过productID查询字符串获取产品的所有图像,但只检索了第一个图像。请注意,处理程序页面中的ProductIDPhotobank图像表中的外键, 我还注意到productID的值ID表没有productID

存储过程:

ALTER proc [dbo].[SP_GetPhotoBank]
(
@ProductID Int 
)
as
SELECT     ID, ProductID, DesignImage
FROM       ProductImages
where      ProductID=@ProductID

标记:

<div>
    <asp:DataList ID="DLProduct" runat="server" OnItemDataBound="DLProduct_ItemDataBound">
        <ItemTemplate>
            <table style="width: 100%;">
                <tr>
                    <td>
                        <asp:Label ID="LblModel" runat="server" Text='<%#Eval("Model") %>' Style="color: #CC3300"></asp:Label>
                    </td>
                    <td>
                        &nbsp;
                    </td>
                </tr>
                <tr>
                    <td colspan="2">
                                                </td>
                </tr>
                <tr>
                    <td>
                        <asp:Image ID="IMGPhotoBank" runat="server" ImageUrl='<%#Eval("ProductID","~/Handlers/PhotoBankByProductID.ashx?ProductID={0}") %>' />
                    </td>
                   </tr>
               </table>
           </ItemTemplate>
       </asp:DataList>
   </div>

代码:

public void ProcessRequest(HttpContext context)
{
    using (SqlConnection con = Connection.GetConnection())
    {           
        SqlCommand com = new SqlCommand("SP_GetPhotoBank", con);
        com.CommandType = System.Data.CommandType.StoredProcedure;
        com.Parameters.Add(Parameter.NewInt("@ProductID", context.Request.QueryString["ProductID"].ToString()));
        SqlDataReader dr = com.ExecuteReader();
        if (dr.Read() && dr != null)
        {
            Byte[] bytes2 = (Byte[])dr["DesignImage"];
            context.Response.BinaryWrite(bytes2);
            dr.Close();
        }
    }
}

5 个答案:

答案 0 :(得分:3)

我认为你需要遍历数据阅读器中的数据,因为目前你只会阅读第一个结果,然后关闭数据阅读器。

while(dr.Read())
{
    // add results to some collection
}

// close the reader and tidy up
dr.Close();
dr.Dispose();

// now render your data 

答案 1 :(得分:1)

您无法在单个请求中向浏览器发送多个图像。基本上你有两个选择:

  1. 迭代页面中的图片
  2. 将所有图片合并到一个文件中,例如Shadow Wizard建议
  3. 在大多数情况下,选项1都可以。你需要做的是:

    • 确保可以通过唯一键访问每个图像。 您的处理程序应每个请求返回1个图像。所以你的网址看起来类似于: ~/Handlers/PhotoBank.ashx?ImageID={0}
    • 列出每个产品的图像,以便在数据绑定期间访问它们。我无法弄清楚你的应用程序会如何。您可以将图像标记包装在转发器中以迭代图像列表。

答案 2 :(得分:0)

您需要将数据库中的所有图像合并到一个位图中,然后将此合并的位图发送到浏览器。

基本上步骤是:

首先,在数据阅读器上循环时,将byte[]图像数据存储在List中。

第二步:使用以下代码迭代上面的List和每个byte[]构建位图:

MemoryStream stream = new MemoryStream(currentData);
Bitmap bitmap = new Bitmap(stream);

计算每个位图的高度和最大宽度之和,并使用该高度和宽度构建新的位图对象以保存合并的图像:

Bitmap mergedImages = new Bitmap(maxWidth, totalHeight);

第三步:使用以下代码将您上面的图片(每个Bitmap构建的byte[])添加到mergedImages

int yPos = 0;  
using (Graphics g = Graphics.FromImage(mergedImages))  
{  
   foreach (Bitmap curBitmap in arrBitmaps)  
    {  
        g.DrawImage(curBitmap, 0, yPos);  
        yPos += curBitmap.Height;  
    }  
}

然后最后一步是将合并后的位图发送到浏览器:

using (MemoryStream stream = new MemoryStream())
{
   bitmap.Save(stream, ImageFormat.Jpeg);
   Response.BinaryWrite(stream.GetBuffer());
}

我知道这可能看起来很复杂,但我相信一步一步地做到这一点你最终会得到这个想法。

答案 3 :(得分:0)

你的很多代码都丢失了。但我会尝试尽可能好地映射出来。

1)您的数据列表必须生成对象列表。通过拉起页面并查看产品列表来验证这一点。他们可能有一堆破碎的图像。

2)查看输出页面的源html。您会看到破损产品图片的一些网址。 URL看起来是否正确?它可能类似于/myproductimage.ashx?pid=5554172。

3)在您正确生成URL后,忽略产品页面。从现在开始,您正在测试图像处理程序。最好以这种方式考虑它,因为它实际上与您的DataGrid无关。

4)将该产品图片处理程序URL放入浏览器的栏中,看看会出现什么。可能没什么。但如果它是HTTP 404,那么您就知道您的处理程序未正确连接。我喜欢使用.ashx处理程序来完成这类任务。它更合适,是一个完整的aspx页面。

5)最后,在你正确调用处理程序之后。根据数据库中存储的内容,将Response.ContentType设置为“image / jpeg”或“image / png”。我建议将其添加为图像数据旁边的列,以便了解数据的格式。

如果这还不够清楚,请打我,我可以在这里为您发布一个旧的产品图片处理程序代码作为示例。

答案 4 :(得分:0)

出现问题是因为您尝试在处理程序的同一请求中处理多个图像,而是确保公开每个返回单个图像的URL(对处理程序的每个请求应仅返回一个图像)。

换句话说,你现在有一个处理程序,它公开了这样的入口点:

~/Handlers/PhotoBankByProductID.ashx?ProductID={0}

但是,您应该考虑重构处理程序,以便它像这样公开入口点URL:

~/Handlers/PhotoBankByProductID.ashx?ProductID={0}&ID={1}

其中{1}ID表中记录的ProductImages

确保此网址同时返回ProductID ID检索到的图片。

然后,在DataList中,请务必使用此类新网址。为此,检索每个ID中每个显示产品的ItemTemplate - s图像,然后使用另一个嵌套的类似列表的控件,该控件显示每个产品图像ID的图像元素当前ProductID

虽然这对于每个ID检索图像ItemTemplate - s似乎有点开销。在这种情况下,如果你有足够的雄心,你可以先检索所有需要的产品,然后检索与每个产品相关的所有图像(在一个结果集中全部),然后绑定到产品列表,然后,为每个嵌套列表产品图像,从相同的结果集中找到相应的图像。

为了使内部列表绑定,您需要OnItemDataBound事件处理程序,我认为您已经将其作为一个很好的起点。

我希望这有帮助!