I am trying to use an ashx page as a http handler for images stored in an SQL server database. These Images are to be displayed in a gridview on an aspx page.
<%# WebHandler Language="C#" Class="LinqHandler" %>
using System;
using System.Web;
using System.Drawing.Imaging;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Configuration;
using System.IO;
public class LinqHandler : IHttpHandler {
public void ProcessRequest(HttpContext context)
{
SqlConnection connect = new SqlConnection();
connect.ConnectionString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
SqlCommand command = new SqlCommand();
command.CommandText = "SELECT roomID,roomNumber,roomImage1 FROM Rooms "
+ "WHERE roomID = #roomID";
command.CommandType = System.Data.CommandType.Text;
command.Connection = connect;
SqlParameter RoomID = new SqlParameter("#roomID", System.Data.SqlDbType.Int);
RoomID.Value = context.Request.QueryString["roomID"];
command.Parameters.Add(RoomID);
connect.Open();
SqlDataReader dr = command.ExecuteReader();
dr.Read();
context.Response.BinaryWrite((byte[])dr["roomImage1"]);
context.Response.ContentType = "image/gif";
dr.Close();
connect.Close();
}
public bool IsReusable {
get {
return false;
}
}
}
for some reason, the images don't bind to the asp:Image control on the aspx page. I'm stumped as to why.
Here is the databinding snippet:
<asp:GridView ID="GridView1" runat="server"
CssClass="gridviews" PagerStyle-CssClass="pager"
DataKeyNames="roomID" AlternatingRowStyle-CssClass="alt"
AutoGenerateColumns="False" DataSourceID="SqlDataSource1">
<Columns>
<asp:BoundField DataField="roomID" HeaderText="roomID" />
<asp:BoundField DataField="roomNumber" HeaderText="Room Number" />
<asp:TemplateField HeaderText="Image 1">
<ItemTemplate>
<asp:Image runat="server" ID="pic1"
ImageUrl='<%# "~/LinqHandler.ashx?roomID=" + Eval("roomID") %>'>
</asp:Image>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:ConnectionString %>"
SelectCommand="SELECT [roomID], [roomNumber], [roomImage1] FROM [Rooms]">
</asp:SqlDataSource>
you can use Handler.ashx for show image. For example:
<img src="Handler.ashx?roomID=1" />
this way you can show image of the one number room.
If you want to do it another way, you can use base64 in css. You dont need to use handler. For example:
<img runat="server" ID="image"/>
//code behind
var bytes = (byte[])dr["roomImage1"]);
var base64String = System.Convert.ToBase64String(bytes, 0, bytes.Length);
image.src = "data:image/gif;base64,"+ base64String;
EDIT:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
var bytes = (byte[])((DataRow)e.Row.DataItem)["roomImage1"];
var base64String = System.Convert.ToBase64String(bytes, 0, bytes.Length);
var image = (Image)e.Row.FindControl("pic1");
image.ImageUrl = "data:image/gif;base64,"+ base64String;
//or
image.ImageUrl = "LinqHandler.ashx?roomID="+((DataRow)e.Row.DataItem)["roomID"];
}
}
Try as below:
<ItemTemplate>
<asp:Image ID="pic1" runat="server"
ImageUrl='<%# Eval("roomID", "LinqHandler.ashx?roomID={0}") %>'
Height="100px" Width="80px" />
</ItemTemplate>
It turns out that my problems stem from inserting garbage into my SQL BLOB fields. There is nothing wrong with the retrieval mechanism posted in my source code. If you are curious to see the insert statements I used, let me know and I will be glad to post them.
Related
Dear all I am displaying an image in my gridview, this image is saved in database in varbinary format, with its content type and image name. And my image in gridview is displaying perfect, now I want to insert this same image from gridview to another table from the button click outside the gridview, How do I achieve this can anyone please guide me? I tried achieving it by receiving this image data from gridview such as Varbinary data - which is an image in database and content type and imagename into textbox but it thorws an error "Implicit conversion from data type nvarchar to varbinary(max) is not allowed. Use the CONVERT function to run this query"
<asp:TemplateField HeaderText="" ItemStyle-Width="" Visible="true">
<ItemTemplate>
<asp:HyperLink ID="HyperLink1" class="preview" ToolTip='<%#Bind("StaffName") %>'
NavigateUrl='' runat="server">
<asp:ImageButton runat="server" ID="Image2" class="img2" ImageUrl='<%# Eval("ImageName") %>'
CommandName='<%# Eval("Id") %>' CommandArgument='<%# Eval("ImageName") %>' />
</asp:HyperLink>
<asp:TextBox ID="txtFileType" runat="server" Text='<%# Eval("FileType") %>' Visible="true"></asp:TextBox>
<asp:TextBox ID="txtBData" runat="server" Text='<%# Eval("BData") %>' Visible="true"></asp:TextBox>
<asp:TextBox ID="txtImageName" runat="server" Text='<%# Eval("ImageName") %>' Visible="true"></asp:TextBox>
<br />
<br />
</ItemTemplate>
<ControlStyle Width="100%" />
<HeaderStyle HorizontalAlign="Left" VerticalAlign="Middle" Width="10%" />
<ItemStyle HorizontalAlign="Center" VerticalAlign="Middle" Width="20%" />
</asp:TemplateField>
foreach (GridViewRow row1 in gvImage.Rows)
{
if (row1.RowType == DataControlRowType.DataRow)
{
// txtFileType
// txtBData
// txtImageName
TextBox txtFileType, txtBData, txtImageName;
txtFileType = (row1.Cells[1].FindControl("txtFileType") as TextBox);
txtBData = (row1.Cells[1].FindControl("txtBData") as TextBox);
txtImageName = (row1.Cells[1].FindControl("txtImageName") as TextBox);
string constr = ConfigurationManager.ConnectionStrings["CONNECTION"].ConnectionString;
using (SqlConnection con8 = new SqlConnection(constr))
{
string query = "insert into SShare (FId,UDetails,ShareBy,ShareByUserId,BData,FileType,ImageName) values(#FId,#UDetails,#ShareBy,#ShareByUserId,#BData,#FileType,#ImageName)";
using (SqlCommand cmd8 = new SqlCommand(query))
{
cmd8.Parameters.AddWithValue("#FId", txt_Tester.Text);
cmd8.Parameters.AddWithValue("#UDetails", TextBox1.Text);
cmd8.Parameters.AddWithValue("#ShareBy", txt_StaffId.Text);
cmd8.Parameters.AddWithValue("#ShareByUserId", txt_Employee.Text);
cmd8.Parameters.AddWithValue("#BData", txtBData.Text);
cmd8.Parameters.AddWithValue("#FileType", txtFileType.Text);
cmd8.Parameters.AddWithValue("#ImageName", txtImageName.Text);
con8.Open();
// cmd8.ExecuteNonQuery();
this.ExecuteQuery(cmd8, "SELECT");
con8.Close();
}
}
}
}
Here is what I suggest. You could get all the data out of the grid, but you can also just do it in SQL.
Notice BDAta is NOT a SqlParameter, it is pulled from the Employee table:
INSERT INTO [SShare](FId,UDetails,ShareBy,ShareByUserId,BData,FileType,ImageName)
SELECT #FId, #UDetails, #ShareBy, #ShareByUserId, BData, #FileType, #ImageName
FROM Employee
WHERE FId = #FId;
After beating head everywhere atlast I figured out and I am posting it incase if someone may refer to. Thanks to #Crowcoder for giving a logic to make it happen.
foreach (GridViewRow row1 in gvImage.Rows)
{
if (row1.RowType == DataControlRowType.DataRow)
{
string Id = gvImage.DataKeys[row1.RowIndex].Value.ToString();
ImageButton imgbtn = (ImageButton)gvImage.Rows[row1.RowIndex].FindControl("Image2");
string filename = imgbtn.ImageUrl;
TextBox ftype = (row1.FindControl("txtFileType") as TextBox);
byte[] bytes = (byte[])GetData("SELECT BData FROM Employee WHERE Id =" + txt_StaffId.Text).Rows[0]["BData"];
string base64String = Convert.ToBase64String(bytes, 0, bytes.Length);
imgbtn.ImageUrl = "data:image/png;base64," + base64String;
{
string constr = ConfigurationManager.ConnectionStrings["CONNECTION"].ConnectionString;
using (SqlConnection con8 = new SqlConnection(constr))
{
string query = "insert into SShare (FId,UDetails,ShareBy,ShareByUserId,BData,ImageName, FileType) values(#FId,#UDetails,#ShareBy,#ShareByUserId,#BData,#ImageName,#FileType)";
using (SqlCommand cmd8 = new SqlCommand(query))
{
cmd8.Parameters.AddWithValue("#FId", txt_Tester.Text);
cmd8.Parameters.AddWithValue("#UDetails", TextBox1.Text);
cmd8.Parameters.AddWithValue("#ShareBy", txt_StaffId.Text);
cmd8.Parameters.AddWithValue("#ShareByUserId", txt_Employee.Text);
cmd8.Parameters.AddWithValue("#BData", bytes);
cmd8.Parameters.AddWithValue("#ImageName", filename);
cmd8.Parameters.AddWithValue("#FileType", ftype.Text);
con8.Open();
// cmd8.ExecuteNonQuery();
this.ExecuteQuery(cmd8, "SELECT");
con8.Close();
}
}
}
}
}
I have what I think is a simple question, however it might be more complex..
I have spent a few days looking for the answer on google and various questions on this site but cannot seem to come right.
What I am trying to do is to bind to a Gridview on the User Control ascx page from the Default.aspx.cs on the Page Load event.
User Control markup is as follows:
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="VulnerabilityExternalIP.ascx.cs" Inherits="VulnerabilityAssesment.Controls.VulnerabilityExternalIP" %>
<asp:Table runat="server" CellPadding="1" CellSpacing="2">
<asp:TableRow>
<asp:TableCell>
<asp:Label ID="lblVulnerabilityName" runat="server" Text="Vulnerability Name:" CssClass="itemName"></asp:Label>
</asp:TableCell>
<asp:TableCell>
<asp:Label ID="lblVulnerabilityNameText" runat="server" Text='<%# Eval("MainVulnerabilityName") %>'></asp:Label>
</asp:TableCell>
</asp:TableRow>
<asp:TableRow>
<asp:TableCell>
<asp:Label ID="lblVulnerabilityCategory" runat="server" Text="Category:" CssClass="itemName"></asp:Label>
</asp:TableCell>
<asp:TableCell>
<asp:Label ID="lblVulnerabilityCategoryText" runat="server" Text='<%# Eval("Category") %>'></asp:Label>
</asp:TableCell>
</asp:TableRow>
<asp:TableRow>
<asp:TableCell>
<asp:Label ID="lblVulnerabilityPopularity" runat="server" Text="Popularity:" CssClass="itemName"></asp:Label>
</asp:TableCell>
<asp:TableCell>
<asp:Label ID="lblVulnerabilityPopularityText" runat="server" Text='<%# Eval("Popularity") %>'></asp:Label>
</asp:TableCell>
</asp:TableRow>
<asp:TableRow>
<asp:TableCell>
<asp:Label ID="lblVulnerabilityRisk" runat="server" Text="Risk:" CssClass="itemName"></asp:Label>
</asp:TableCell>
<asp:TableCell>
<asp:Label ID="blVulnerabilityRiskText" runat="server" Text='<%# Eval("RiskFactor") %>'></asp:Label>
</asp:TableCell>
</asp:TableRow>
</asp:Table>
<br />
<asp:Label ID="lblHostsAffected" runat="server" Text="Hosts Affected:" CssClass="itemName"></asp:Label>
<br />
<asp:TextBox ID="txtHostsAffected" runat="server" TextMode="MultiLine" Width="700px" ReadOnly="true" BroderWidth="0px" Text='<%# Eval("HostNamePort") %>'></asp:TextBox>
<asp:GridView ID="gvHostsAffected" runat="server" AutoGenerateColumns="False" AutoGenerateEditButton="True">
</asp:GridView>
I am referencing the User Control on the Default.aspx as follows:
<%# Register Src="~/Controls/VulnerabilityExternalIP.ascx" TagName="VulnerabilityExternalIP" TagPrefix="uc1" %>
Within the default.asxp I have the following defined:
<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">
<asp:ListView ID="lvVulnerabilityExternalIP" runat="server">
<ItemTemplate>
<uc1:VulnerabilityExternalIP Template="<%# Container.DataItem %>" runat="server" ID="vulnerabilityExtIP" name="vulnext" />
</ItemTemplate>
</asp:ListView>
</asp:Content>
The code behind on Default.aspx.cs is as follows:
namespace VulnerabilityAssesment
{
public partial class _Default : Page
{
protected void Page_Load(object sender, EventArgs e)
{
string HostNamePort = "";
string VulnerabilityDesc = "";
string VulnerabilitySummary = "";
string VulnerabilitySolution = "";
string VulnerabilityCVE = "";
string VulnerbilityLink = "";
// Use connection string from Web.Config
string connection = ConfigurationManager.ConnectionStrings["csVulnerabilityAssesment"].ConnectionString;
//Create new SQL Connection
SqlConnection conn = new SqlConnection(connection);
//Create Stored Procedure Command and Declare Parameters
SqlCommand vulnerabilityHeader = new SqlCommand("[dbo].[_spGet_VulnerabilityHeader]", conn);
vulnerabilityHeader.CommandType = CommandType.StoredProcedure;
vulnerabilityHeader.Parameters.Add("#VulnerabilityReport", SqlDbType.VarChar).Value = "External IP Ranges";
//Create Data Adapter and Data Set
SqlDataAdapter sdaVulnerabilityHeader = new SqlDataAdapter(vulnerabilityHeader);
DataSet dsVulnerabilityHeader = new DataSet();
//Open Connection
conn.Open();
//Fill Data Adapter
sdaVulnerabilityHeader.Fill(dsVulnerabilityHeader);
//Fill in template
List<VulnerabilityTemplate> Template = new List<VulnerabilityTemplate>();
if (dsVulnerabilityHeader.Tables != null)
if (dsVulnerabilityHeader.Tables[0].Rows.Count == 0)
{
}
else
if (dsVulnerabilityHeader.Tables.Count > 0)
{
foreach (DataRow dr in dsVulnerabilityHeader.Tables[0].Rows)
{
string GroupID = dr["GroupSequence"].ToString();
//Declare Stored Procedue for Vulnerability Details and set Parameters
SqlCommand vulnerabilityDetail = new SqlCommand("[dbo].[_spGet_VulnerabilityDetail]", conn);
vulnerabilityDetail.CommandType = CommandType.StoredProcedure;
vulnerabilityDetail.Parameters.Add("#VulnerabilityReport", SqlDbType.VarChar).Value = "External IP Ranges";
vulnerabilityDetail.Parameters.Add("#GroupSequence", SqlDbType.VarChar).Value = GroupID;
// Declare SQL Data Adapter for Vulnerability Detail
SqlDataAdapter sdaVulnerabilityDetail = new SqlDataAdapter(vulnerabilityDetail);
DataSet dsVulnerabilityDetail = new DataSet();
// Fill Data Adapter
sdaVulnerabilityDetail.Fill(dsVulnerabilityDetail);
// Declare Stored Procedure for Vulnerability Summary and Set Paramters
SqlCommand vulnerabilitySummary = new SqlCommand("[dbo].[_spGet_VulnerabilitySummary]", conn);
vulnerabilitySummary.CommandType = CommandType.StoredProcedure;
vulnerabilitySummary.Parameters.Add("#VulnerabilityReport", SqlDbType.VarChar).Value = "External IP Ranges";
vulnerabilitySummary.Parameters.Add("#GroupSequence", SqlDbType.VarChar).Value = GroupID;
// Declare SQL Data Adapter for Vulnerability Detail
SqlDataAdapter sdaVulnerabilitySummary = new SqlDataAdapter(vulnerabilitySummary);
DataSet dsVulnerabilitySummary = new DataSet();
// Fill Data Adapter
sdaVulnerabilityDetail.Fill(dsVulnerabilityDetail);
sdaVulnerabilitySummary.Fill(dsVulnerabilitySummary);
foreach (DataRow row in dsVulnerabilityDetail.Tables[0].Rows)
{
if (HostNamePort != "")
HostNamePort += Environment.NewLine;
HostNamePort += row["HostnamePort"].ToString();
}
foreach (DataRow vulnerabilitySummaryRow in dsVulnerabilitySummary.Tables[0].Rows)
{
VulnerabilityDesc += vulnerabilitySummaryRow["VulnerabilityDesc"].ToString();
VulnerabilitySummary += vulnerabilitySummaryRow["VulnerabilitySummary"].ToString();
VulnerabilitySolution += vulnerabilitySummaryRow["VulnerabilitySolution"].ToString();
}
//myGrid.DataSource = dsVulnerabilityDetail.Tables[0];
//GridView myGrid = (GridView)lvVulnerabilityExternalIP.Items.FindControl("gvHostsAffected");
// Always returns null :(
GridView myGrid = (GridView)lvVulnerabilityExternalIP.FindControl("gvHostsAffected");
Template.Add(new VulnerabilityTemplate
{
MainVulnerabilityName = dr["MainVulnerabilityName"].ToString(),
Category = dr["Category"].ToString(),
Popularity = dr["Popularity"].ToString(),
Riskfactor = dr["RiskFactor"].ToString(),
HostNamePort = HostNamePort
//VulnerabilityDesc = VulnerabilityDesc,
//VulnerabilitySolution = VulnerabilitySolution,
//VulnerabilitySummary = VulnerabilitySummary
}
);
myGrid.DataBind();
}
}
lvVulnerabilityExternalIP.DataSource = Template;
lvVulnerabilityExternalIP.DataBind();
conn.Close();
}
// Below Does not work
protected void ListView_ItemDataBound(object sender, ListViewItemEventArgs e)
{
if (e.Item.ItemType == ListViewItemType.DataItem)
{
DataTable table = (DataTable)e.Item.DataItem;
GridView myGrid = (GridView)e.Item.FindControl("gvHostsAffected");
myGrid.DataSource = table;
myGrid.DataBind();
}
}
}
}
I cannot seem to find the gvHostsAffected grid view to bind it to the dsVulnerabilityDetail.Tables[0] value (which should be a single column called HostsAffected, this result could return 1 or more rows.
I have included two things that I have tried denoted by the comment //Below does not work.
The Template.Add method does work and it populates necessary information on the user control.
Is there any way I can find the Gridview control during the iteration and populate it with the results from the dsVulnerabilityDetail data set?
Thank you in advance.
Update 10 April 2017
Below is the Code Behind for the WebControl, I see I forgot to include it in the original Question.
namespace VulnerabilityAssesment.Controls
{
public partial class VulnerabilityExternalIP : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
}
public GridView myGridView
{
get
{
return gvHostsAffected;
}
set
{
gvHostsAffected = value;
}
}
}
}
The markup for Web Control include the answer by VDWWD.
First, add a public GridView property to the User Control
public partial class WebUserControl1 : System.Web.UI.UserControl
{
public GridView myGridView
{
get
{
return GridView1;
}
set
{
GridView1 = value;
}
}
protected void Page_Load(object sender, EventArgs e)
{
}
Then you can access it like yo would a GridView on the same page. The only thing left to do is to use FindControl to find the User Control inside the ListView
protected void Button1_Click(object sender, EventArgs e)
{
WebUserControl1 control = lvVulnerabilityExternalIP.Items[2].FindControl("vulnerabilityExtIP") as WebUserControl1;
control.myGridView.DataSource = mySource;
control.myGridView.DataBind();
}
I have an aspx page that displays a gridview of questions waiting on review with 10 questions shown per page. If a question is selected it is opened in a new page where the reviewer can either submit a review or cancel and return to the list of questions needing review.
Currently this works fine, but have a request from the reviewers so that if they are on page 4 of the gridview when they go to a question, they get returned to page 4 if they hit cancel and return to the list of questions (currently they are returned to page 1).
So I am setting a couple session variables to capture the question selected and to capture the pageindex of the gridview control for future use. Trying to use the session variable for the questionId on the page load of the detail page, but it is not being passed. On returning to the Review List page the pageindex that is being set on the gridview is always 0, not the session variable.
Updated Gridview control (note two controls, one hyperlink(which should go away once the other linkbutton control works):
<asp:GridView ID="GridView1" runat="server" Caption="Questions Awaiting Review" AllowSorting="True" PagerSettings-Mode="NumericFirstLast" OnPageIndexChanging="GridView1_PageIndexChanging"
CaptionAlign="Top" EmptyDataText="No Questions Pending Review." PageSize="10" AllowPaging="true" PagerStyle-HorizontalAlign="Center" PagerStyle-Font-Size="Large" DataKeyNames="QuestionID"
AutoGenerateColumns="false" AlternatingRowStyle-BackColor="#cccccc">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:Label ID="QuestionID" runat="server" Text='<%# Eval("QuestionID") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="KeyObjective" HeaderText="Key Objective" ItemStyle-Width="250" />
<asp:BoundField DataField="SubmitDate" HeaderText="Submitted Date" ItemStyle-Width="60" />
<asp:TemplateField>
<ItemTemplate>
<asp:HyperLink ID="Details" runat="server" NavigateUrl='<%#"~/Review/ReviewDetail.aspx?Id=" + Eval("QuestionID") +"&PageIndex=" + GridView1.PageIndex %>'>View Question</asp:HyperLink>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="Details2" runat="server" Text="Session" OnClick="Session_OnClick"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
OnClick Event for the second button:
protected void Session_OnClick(object sender, EventArgs e)
{
Session["PageIndex"] = GridView1.PageIndex;
Session["QuestionId"] = GridView1.SelectedDataKey;
Response.Redirect("~/Review/ReviewDetail.aspx", false;
}
Connection string on the detail page which is now not getting a value for the parameter "QuestionID"; ):
SqlCommand command = new SqlCommand("QuestionDetail", Conn);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(new SqlParameter("#QuestionID", SqlDbType.BigInt));
command.Parameters["#QuestionID"].Value = Convert.ToInt64(Session["QuestionId"]);
Conn.Open();
SqlDataReader reader = command.ExecuteReader();
PageLoad and gridview binding on the ReviewList page that should be using session variable to set page of grid control, but is always going to default of page 0:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
bindGridView();
}
else
{
if (Convert.ToInt32(Session["PageIndex"]) !=0)
{
GridView1.PageIndex = Convert.ToInt32(Session["PageIndex"]);
bindGridView();
}
}
}
private void bindGridView()
{
string connectionString = WebConfigurationManager.ConnectionStrings["CS1"].ConnectionString;
string selectSQL = String.Format("Select QuestionID, KeyObjective, SubmitDate from Questions where Author <> '{0}' and QuestionID not in(Select QuestionID from Review where Reviewer = '{0}')", User.Identity.Name);
SqlConnection con = new SqlConnection(connectionString);
SqlCommand cmd = new SqlCommand(selectSQL, con);
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
adapter.Fill(ds, "Review");
GridView1.DataSource = ds;
GridView1.DataBind();
}
Your error probably means that Request["Id"] is empty or does not exists. Always check if QueryStrings exist and do the conversions of user inputs that are likely to fail inside a try-catch block.
protected void Page_Load(object sender, EventArgs e)
{
long QuestionID = -1;
//check if the Id QueryString exists
if (Request.QueryString["Id"] != null)
{
//try to convert to int64
try
{
QuestionID = Convert.ToInt64(Request.QueryString["Id"]);
}
catch
{
}
}
//if valid QuestionID
if (QuestionID >= 0)
{
using (SqlConnection connection = new SqlConnection(Common.connectionString))
using (SqlCommand command = new SqlCommand("QuestionDetail", connection))
{
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add("#QuestionID", SqlDbType.BigInt).Value = QuestionID;
//try to execute the stored procedure
try
{
connection.Open();
command.ExecuteNonQuery();
}
catch (Exception ex)
{
//handle sql error
Literal1.Text = ex.Message;
}
}
}
}
And why do you do a PostBack on the first button? That is not needed just to redirect to a different url. Change it to:
<asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl='<%#"~/Review/ReviewDetail.aspx?Id=" + Eval("QuestionID") %>'>View Question</asp:HyperLink>
Or with the Page Index also in the QueryString:
<asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl='<%#"~/Review/ReviewDetail.aspx?Id=" + Eval("QuestionID") + "&Page=" + GridView2.PageIndex %>'>View Question</asp:HyperLink>
UPDATE
If you really want to do a PostBack to set the Sessions you can use the OnRowCommand:
<asp:LinkButton ID="LinkButton1" CommandArgument='<%# Eval("QuestionID") %>' runat="server" CommandName="viewQuestion">View Question</asp:LinkButton>
CS
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "viewQuestion")
{
Session["PageIndex"] = GridView1.PageIndex;
Session["QuestionId"] = e.CommandArgument.ToString();
Response.Redirect("~/Review/ReviewDetail.aspx?Id=" + Convert.ToString(Session["QuestionId"]));
}
}
I use asp.net, c# and mysql.
So how can I insert selected image from gridview to mysql table? Please show me some examples.
The inserted images will be displayed in the GridView control.
The GridView has a OnRowDataBound event handler assigned which will be used for displaying the Image inserted in MySql database.
HTML
<asp:FileUpload ID="FileUpload1"
runat="server" />
<asp:Button Text="Upload"
runat="server"
OnClick="UploadFile" />
<asp:GridView ID="gvImages"
runat="server"
AutoGenerateColumns="false"
OnRowDataBound="OnRowDataBound">
<Columns>
<asp:BoundField HeaderText="File Id"
DataField="FileId" />
<asp:BoundField HeaderText="File Name"
DataField="FileName" />
<asp:TemplateField HeaderText="Image">
<ItemTemplate>
<asp:Image ID="Image1"
runat="server"
Height="80"
Width="80" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
C#
protected void UploadFile(object sender, EventArgs e)
{
string filename = Path.GetFileName(FileUpload1.PostedFile.FileName);
string contentType = FileUpload1.PostedFile.ContentType;
using (Stream fs = FileUpload1.PostedFile.InputStream)
{
using (BinaryReader br = new BinaryReader(fs))
{
byte[] bytes = br.ReadBytes((Int32)fs.Length);
string constr = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
using (MySqlConnection con = new MySqlConnection(constr))
{
string query = "INSERT INTO Files(FileName, ContentType, Content) VALUES (#FileName, #ContentType, #Content)";
using (MySqlCommand cmd = new MySqlCommand(query))
{
cmd.Connection = con;
cmd.Parameters.AddWithValue("#FileName", filename);
cmd.Parameters.AddWithValue("#ContentType", contentType);
cmd.Parameters.AddWithValue("#Content", bytes);
con.Open();
cmd.ExecuteNonQuery();
con.Close();
}
}
}
}
Response.Redirect(Request.Url.AbsoluteUri);
}
The Above event handler gets executed when the Upload Button is clicked, it first converts the uploaded image file to BYTE array using BinaryReader class and then saves the Image file as Binary data (BLOB) in the MySql Database.
The name of the file, the content type (MIME type) and the actual file as array of bytes are inserted into the MySql database table.
Note: The Content type (MIME type) is very important while downloading the files as it notifies the browser about type of the File.
I've inherited this site and having issues with file downloads. Files such as .pdf, .doxs, .txt are saved in Sql as image. A datalist controls is used with a a href controls to view it/downloaded it but it's not working. And I realize that a href control is not a proper control to use but not sure what control to use.
Here is the aspx markup:
<asp:DataList ID="DataList2" runat="server" DataSourceID="SqlDataSource2" DataKeyField="fileId">
<ItemTemplate>
<a href='<%# "~/UserControls/FileFetch.ashx?fileId=" + Convert.ToString(Eval("fileId")) %>' target="_blank">
<%# Convert.ToString(Eval("fileName"))%></a>
</ItemTemplate>
</asp:DataList>
<asp:SqlDataSource ID="SqlDataSource2" runat="server" ConnectionString="<%$ ConnectionStrings:ClubSiteDB %>"
SelectCommand="SELECT [fileId], [fileName], [postedBy] FROM [FilesLibrary]">
</asp:SqlDataSource>
A helper file called FileFetch.ashx is used to get the file:
<%# WebHandler Language="C#" Class="FileFetch" %>
using System;
using System.Web;
using System.Data.SqlClient;
using System.Data;
using System.IO;
public class FileFetch : IHttpHandler
{
const int BUFFERSIZE = 1024;
public bool IsReusable
{
get
{
return true;
}
}
public void ProcessRequest(HttpContext context)
{
HttpResponse response = context.Response;
HttpRequest request = context.Request;
response.ContentType = "response.ContentType";
response.Cache.SetCacheability(HttpCacheability.Public);
response.BufferOutput = false;
writeSingleImage(Convert.ToInt32(request.QueryString["fileId"]), response.OutputStream);
response.End();
}
public void writeSingleImage(int fileId, Stream output)
{
string cxnstr = System.Configuration.ConfigurationManager.ConnectionStrings["ClubSiteDB"].ConnectionString;
SqlConnection connection = new SqlConnection(cxnstr);
string query;
query = "SELECT fileData FROM dbo.FilesLibrary where fileId=#fileId";
SqlCommand command = new SqlCommand(query, connection);
SqlParameter param0 = new SqlParameter("#fileId", SqlDbType.Int);
param0.Value = fileId;
command.Parameters.Add(param0);
connection.Open();
byte[] d = ((byte[])(command.ExecuteScalar()));
output.Write(d, 0, d.Length);
connection.Close();
}
}
I'm going to take a stab at this and say you need to change your Anchor tag to be the following:
<a href='<%# Page.ResolveUrl("~/UserControls/FileFetch.ashx?fileId=" + Convert.ToString(Eval("fileId"))) %>' target="_blank">
The MSDN link to the Page.ResolveUrl method is here. Page inherits from Control, hence why the link refers to Control.ResolveUrl.
I've just seen that another alternative is to add runat="server" to the Anchor tag to turn it into a server control.