我有表有关于产品照片的数据,这张表与产品表和产品有关,可能比Image更多。我很好地完成了我的代码,通过productID
查询字符串获取产品的所有图像,但只检索了第一个图像。请注意,处理程序页面中的ProductID
是Photobank
图像表中的外键,
我还注意到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>
</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();
}
}
}
答案 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都可以。你需要做的是:
~/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
事件处理程序,我认为您已经将其作为一个很好的起点。
我希望这有帮助!