I am working on a asp.net project and the main task involved is to generate a image div on button click.
as in retrieving image from database and showing it on screen(another div or table).
How can this task be accomplished?
I will be glad to know how to place an image on button click and then on next button click the next image should appear besides it.
By using the following code you can generate dynamic div's:
HtmlGenericControl div1 = new HtmlGenericControl("div");
Now that you want to show images from database use handler like the following. Make an ashx file, add the code and then take an image control dynamically and bind the output of the image handler to the imageURl property of the image. The code is :
<%# WebHandler Language="C#" Class="DisplayImg" %>
using System;
using System.Web;
using System.Configuration;
using System.IO;
using System.Data;
using System.Data.SqlClient;
public class DisplayImg : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
string theID;
if (context.Request.QueryString["id"] != null)
theID = context.Request.QueryString["id"].ToString();
else
throw new ArgumentException("No parameter specified");
context.Response.ContentType = "image/jpeg";
Stream strm = DisplayImage(theID);
byte[] buffer = new byte[2048];
int byteSeq = strm.Read(buffer, 0, 2048);
while (byteSeq > 0)
{
context.Response.OutputStream.Write(buffer, 0, byteSeq);
byteSeq = strm.Read(buffer, 0, 2048);
}
}
public Stream DisplayImage(string theID)
{
SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["SERVER"].ConnectionString.ToString());
string sql = "SELECT Server_image_icon FROM tbl_ServerMaster WHERE server_Code = #ID";
SqlCommand cmd = new SqlCommand(sql, connection);
cmd.CommandType = CommandType.Text;
cmd.Parameters.AddWithValue("#ID", theID);
connection.Open();
object theImg = cmd.ExecuteScalar();
try
{
return new MemoryStream((byte[])theImg);
}
catch
{
return null;
}
finally
{
connection.Close();
}
}
public bool IsReusable
{
get
{
return false;
}
}
}
Just add one line in CS code
UploadImg.ImageUrl = "~/DisplayImg.ashx?id=" + code;
and finally add the image in the div
div1.Controls.Add(YOUR IMAGE's ID);
Related
Here is what I'm doing:
public static MVC_Picture GetPictureRecord(int pictureID)
{
int pictureId = pictureID;
MVC_Picture _picture = new MVC_Picture(); //object that stores name and array
var connString = db.connString;
string cmdText = "SELECT PictureName, PictureImage FROM Picture WHERE CONVERT(INT, ID) =#pictureId;";
using (var connection = new SqlConnection(connString))
{
using (var sqlCmd = new SqlCommand(cmdText, connection))
{
SqlParameter param1 = new SqlParameter();
param1.ParameterName = "#pictureId";
param1.Value = pictureId;
sqlCmd.Parameters.Add(param1);
connection.Open();
SqlDataReader dr = sqlCmd.ExecuteReader();
while (dr.Read())
{
_picture.Id = pictureId;
_picture.PictureName = Convert.ToString(dr["PictureName"]);
_picture.PictureImage = (byte[])(dr["PictureImage"]); //Problem
}
connection.Close();
}
}
return _picture;
}
When I convert to byte[] I get something like: {byte[4354567]}
I'm then trying to convert array to Image like so:
Image img = (Image)converter.ConvertFrom(_picture.PictureImage);
ViewModel.FeaturedImage = img;
And in View I use:
<img src="#ViewModel.FeaturedImage" alt="Featured Image" />
What am I missing?
<img src=... has to point to an image file by its path, eg <img src="/myImage.jpg">. You can't stick a binary representation of the image in the src and have it work.
So you could either write those binary images out to disk somewhere (you probably don't want to do that, as then you're duplicating the data, and would have to manage synchronizing).
Or you could create some kind of image handler, so the <img src= would be something like: <img src="/myHandler/imageId", and then have the handler read the binary data from the database and respond with the image.
This is an MVC controller action that I've used in the past to read a binary PDF out of the DB, and return it as a file. This is in my Competition controller. If this was returning an image, you could call it something like:
<img src="Competition/ViewJobDescription?competitionId=1234" />
public ActionResult ViewJobDescription(int competitionId)
{
string errorMsg = "";
var competition = new DBModel.Competition();
try
{
competition = DBModel.Competition.GetCompetition(competitionId);
if (competition != null && competition.AttachmentContent != null)
{
byte[] fileData = competition.AttachmentContent;
string filename = competition.AttachmentTitle + ".pdf";
return File(fileData, "application/pdf", filename);
}
}
catch (Exception ex)
{
errorMsg += "An error occured: " + ex.Message;
LogFile err = new LogFile();
err.CreateErrorLog(errorMsg);
ModelState.AddModelError(string.Empty, errorMsg);
}
return RedirectToAction("Index", "Home");
}
I have code that I copied from the tutorial that I watch and our code is so similar in the tutorial.
When the presenter runs the code, it runs ok, but when I try to run my code which is the same as in the tutorial, I get an error "the parameter is not valid".
Please help
private void Viewbutton_Click(object sender, EventArgs e)
{
conection.Open();
string sqlQuery = "select studnum, course, f_name, l_name, color_image from table3 where studnum='" + textBox1.Text + "'";
cmd = new SqlCommand(sqlQuery, conection);
SqlDataReader dataread = cmd.ExecuteReader();
dataread.Read();
if (dataread.HasRows)
{
lblstudnum.Text = dataread[0].ToString();
lblcourse.Text = dataread[1].ToString();
lblfname.Text = dataread[2].ToString();
lbllname.Text = dataread[3].ToString();
byte[] images = (byte[])dataread[4];
if(images==null)
{
pictureBox1.Image = null;
}
else
{
MemoryStream mstreem = new MemoryStream(images);
pictureBox1.Image = Image.FromStream(mstreem);
}
}
else
{
MessageBox.Show("this data not available");
}
}
The error line is the
pictureBox1.Image = Image.FromStream(mstreem);
Better to use parametric query and column name instead of using [0],[1] etc.. The Memory Stream is used by Data reader.So you shall use as below, provided a valid Image is saved in database
var con = new SqlConnection("the connection string to database");
con.Open();
SqlCommand cmd = new SqlCommand(#"sql query",con);
byte[] images = null;
using (SqlDataReader dataread = cmd.ExecuteReader())
{
if (dataread.Read())
{
//lblstudnum.Text = dataread[0].ToString();
//lblcourse.Text = dataread[1].ToString();
//lblfname.Text = dataread[2].ToString();
//lbllname.Text = dataread[3].ToString();
images = (byte[])dataread["color_image"];// column name is recommended
}
}
con.Close();
if (images == null)
{
pictureBox1.Image = null;
}
else
{
MemoryStream mstreem = new MemoryStream(images);
pictureBox1.Image = Image.FromStream(mstreem);
}
Probably not a valid image. Add some debugging code to your program (or set up a watch) that will output the length of the memory stream and its first few bytes. Make sure the length is what you were expecting. Make sure the file prefix is there, if any, e.g. bitmap files have a two-letter alphanumeric prefix. Make sure it didn't get truncated. Make sure it is an allowed file format. The problem may be that your instructor's database has data in it while yours doesn't.
I have database with EmpNo(Int) and EmpImage(Image) columns.
I am using HttpHandler to display the Images.
I am storing Images both in database and folder.
Now I want to change the names of Images in folder as names of EmpNo whose I didn't change while uploading.
So need to fetch the Images names from database to compare them with the Image names in the folder and rename them.
How can i fetch or extract the image names from the binary data that i get from database using generic handler.
I have attached the code In handler for reference.
using System;
using System.Web;
using System.Data;
using System.Data.SqlClient;
public class Lab_14___ImageFetchingHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
SqlConnection vConn = new SqlConnection("server=localhost; database=Asp.netDemoWebsiteDatabase; Integrated Security = SSPI;");
vConn.Open();
String vQuery = "Select EmpImage from EmpImages where Empno=#id";
SqlCommand vComm = new SqlCommand(vQuery, vConn);
//Receive the Id from some Form
String vId = context.Request.QueryString["id"];
vComm.Parameters.AddWithValue("#id", vId);
SqlDataReader vDr = vComm.ExecuteReader();
while (vDr.Read())
{
context.Response.ContentType = "image/jpg";
context.Response.BinaryWrite((byte[])vDr["EmpImage"]);
[ Here I need the Images names to store in List or array.How?? ]
}
vConn.Close();
}
public bool IsReusable
{
get
{
return false;
}
}
}
Here are different ways to inspect image metadata.
Byte[] content = (Byte[])vDr["EmpImage"]
//Option 1
Image img = new Bitmap(new MemoryStream(content));
Encoding _Encoding = Encoding.UTF8;
var props = img.PropertyItems;
string propData;
foreach (var propertyItem in props)
{
propData = _Encoding.GetString(propertyItem.Value);
Debug.WriteLine("{0}[{1}]", propertyItem.Id, propData);
}
//option 2 - require reference of PresentationCore and WindowsBase and then using System.Windows.Media.Imaging
var imgFrame = BitmapFrame.Create(new MemoryStream(content));
var metadata = imgFrame.Metadata as BitmapMetadata;
//option 3 - require MetadataExtractor Nuget package
var mr = ImageMetadataReader.ReadMetadata(new MemoryStream(content));
foreach (var directory in mr)
{
foreach (var tag in directory.Tags)
{
Debug.WriteLine("{0} - {1} = {2}]", directory.Name, tag.Name, tag.Description);
}
}
I am trying to write a dashboard with information about the website's hits and where people come from etc.
I wrote the following page:
<%# Page Language="C#" Inherits="Daschboard.Board" MasterPageFile="~/site.master" %>
<asp:Content id="main" runat="server" ContentPlaceHolderID="main">
<asp:UpdatePanel runat="server" id="updateableWidgets">
<ContentTemplate>
<asp:ContentPlaceHolder id="WidgetsTable">
</asp:ContentPlaceHolder>
</ContentTemplate>
</asp:UpdatePanel>
</asp:Content>
With the following code behind:
using Widgets;
using System;
using System.Text;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Configuration;
using MySql.Data.MySqlClient;
namespace Daschboard
{
public partial class Board : System.Web.UI.Page
{
protected List<IWidget> widgets;
private MySqlConnection db = new MySqlConnection (ConfigurationManager.AppSettings ["mySql"]);
protected void Page_Load(object sender, EventArgs e)
{
widgets = new List<IWidget>();
BuildWidgtTable();
var WidgetThread = new System.Threading.Thread(new System.Threading.ThreadStart(this.InitWidgets));
WidgetThread.Start();
}
private string BuildWidgtTable ()
{
StringBuilder sb = new StringBuilder ();
db.Open ();
var tableName = ConfigurationManager.AppSettings ["DatabaseSiteName"];
var query = "SELECT * FROM " + tableName + ", Widget WHERE " + tableName + ".WidgetID = Widget.WidgetID";
var command = new MySqlCommand (query, db);
var result = command.ExecuteReader ();
while (result.Read()) {
widgets.Add(getWidget(result.GetString(4)));
}
db.Close ();
sb.Append("<table>\n");
sb.Append("</table>");
result.Close();
return sb.ToString();
}
private void InitWidgets ()
{
db.Open();
foreach (var widget in widgets) {
var siteId = ConfigurationManager.AppSettings["siteID"];
var query = "SELECT * FROM Values, Widget WHERE Widget.WidgetID = Values.WidgetID AND SiteID = " + siteId;
var command = new MySqlCommand(query, db);
var result = command.ExecuteReader();
while(result.Read()){
Console.WriteLine(result);
}
result.Close();
widget.Init ("1");
}
db.Close();
}
private IWidget getWidget (string fileName)
{
IWidget widget = null;
switch (fileName) {
case "PageHits":
widget = new PageHits();
break;
case "SiteHits":
widget = new SiteHits();
break;
}
return widget;
}
}
}
When I run this something goes wrong; the debugger stops working without a good error.
It does load the widgets from the database but it doesn't get the values from the database.
I am using Monodevelop on a Mac.
You are running the widget initialization method in a separate thread (InitWidgets method). The page might have already finished rendering when this method executes. If you want to use asynchronous operations in ASP.NET I would recommend you reading about Asynchronous Pages on MSDN. The idea is to mark your WebForm as asynchronous by setting Async="true" in your Page directive (<%# Page Async="true" ... %>) and then use the RegisterAsyncTask method on your web form.
I am having trouble using the output cache param in an aspnet 2.0 page directive. I am using a session variable to hold the value of the selected image. It seems that the dynamic control in a datalist, is not working when the output cache is set to true in the page directive. Is there a way to cache the images seperately to avoid using a page directive?
datalist code
" RepeatColumns="6" CellPadding="8" CellSpacing="8" GridLines="Both" SelectedItemStyle-BackColor="#33ff66" OnSelectedIndexChanged="dtlImages_SelectedIndexChanged" OnItemCommand="dtlImages_ItemCommand">
' Runat="server">
' ID="lblDescription" Font-Bold="True" Font-Size="12px" Font-Names="Arial">
code that retrieves the image from the database
protected void Page_Load(object sender, System.EventArgs e)
{
string strImageID = Request.QueryString["id"];
string wf4uConnect = System.Configuration.ConfigurationManager.ConnectionStrings["wf4uConnectionString"].ConnectionString;
System.Data.SqlClient.SqlConnection wf4uConn = new System.Data.SqlClient.SqlConnection(wf4uConnect);
System.Data.SqlClient.SqlCommand myCommand = new SqlCommand("Select ImageFile, ImageType from wf4u_ImageThumb Where ImageId =" + strImageID, wf4uConn);
wf4uConn.Open();
SqlDataReader byteReader = myCommand.ExecuteReader(CommandBehavior.CloseConnection);
while ((byteReader.Read()))
{
Response.BinaryWrite((byte [])byteReader.GetValue(0));
Response.ContentType = (string)byteReader.GetValue(1);
}
wf4uConn.Close();
}
I have implemented an http context object to cache the images as they're loaded into the webpage.
public ImageList (string clientName)
{
HttpContext context = HttpContext.Current;
if((context.Cache["ImageIdList" + clientName] == null))
{
string wf4uConnect = System.Configuration.ConfigurationManager.ConnectionStrings["wf4uConnectionString"].ConnectionString;
System.Data.SqlClient.SqlConnection wf4uConn = new System.Data.SqlClient.SqlConnection(wf4uConnect);
string queryStr = "SELECT ImageId FROM wf4u_imageThumb WHERE ClientName = #ClientName";
SqlCommand ImageIdComm = new System.Data.SqlClient.SqlCommand(queryStr, wf4uConn);
ImageIdComm.Parameters.Add("#ClientName", SqlDbType.VarChar).Value = clientName;
wf4uConn.Open();
SqlDataReader ImageIdReader = ImageIdComm.ExecuteReader();
if (ImageIdReader.Read())
{
_ImageId = ImageIdReader.GetInt32(0);
_ClientName = ImageIdReader.GetString(1);
context.Cache.Insert("ImageIdList" + clientName, this, null, DateTime.Now.AddSeconds(600), TimeSpan.Zero);
}
wf4uConn.Close();
}
else
{
ImageList list = (ImageList)context.Cache["ImageIdList" + clientName];
_ImageId = list.ImageId;
_ClientName = list.ClientName;
}
}
any suggestions would be welcomed.
You can use Cache object see: ASP.NET Caching: Techniques and Best Practices
You can implement an async handler like this:
using System;
using System.Web;
using System.Data.SqlClient;
public class FileHandler : IHttpAsyncHandler
{
#region Variables
private HttpContext _currentContext = null;
protected SqlCommand _command = null;
protected delegate void DoNothingDelegate();
#endregion
public void ProcessRequest(HttpContext context)
{
}
public void DoNothing()
{
}
public bool IsReusable
{
get { return false; }
}
#region IHttpAsyncHandler Members
public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
{
_currentContext = context;
int imageId;
if (int.TryParse(context.Request.QueryString["imageId"], out imageId))
{
// begin get file - make you own
// return FileController.BeginGetFile(out _command, cb, extraData, imageId);
}
else
{
DoNothingDelegate doNothingDelegate = new DoNothingDelegate(DoNothing);
return doNothingDelegate.BeginInvoke(cb, extraData);
}
}
public void EndProcessRequest(IAsyncResult result)
{
File file = null;
if (null != _command)
{
try
{
// end get file - make your own
// file = FileController.EndGetFile(_command, result);
}
catch { }
}
if (null != file)
{
// in my case File entity may be stored as a binary data
//or as an URL
// here is URL processing - redirect only
if (null == file.Data)
{
_currentContext.Response.Redirect(file.Path);
}
else
{
_currentContext.Response.ContentType = file.ContentType;
_currentContext.Response.BinaryWrite(file.Data);
_currentContext.Response.AddHeader("content-disposition", "filename=\"" + file.Name + (file.Name.Contains(file.Extension) ? string.Empty : file.Extension) + "\"" );
_currentContext.Response.AddHeader("content-length", (file.Data == null ? "0" : file.Data.Length.ToString()));
}
_currentContext.Response.Cache.SetCacheability(HttpCacheability.Private);
_currentContext.Response.Cache.SetExpires(DateTime.Now);
_currentContext.Response.Cache.SetSlidingExpiration(false);
_currentContext.Response.Cache.SetValidUntilExpires(false);
_currentContext.Response.Flush();
}
else
{
throw new HttpException(404, HttpContext.GetGlobalResourceObject("Image", "NotFound") as string);
}
}
#endregion
}
And set necessary values to the cache headers.
EDIT: Guess, in this case it would be better to use headers instead of using Cache object.
The way I do the images-from-the-database thing is to use a HTTP handler which reads the bits from the database, and sets the appropriate client-side caching headers in the response. I also support the If-Modified-Since header to suppress sending the blob if not required.
Then the page just has links to the handler with an image ID (must be careful to validate that the ID is an integer or whatever ID format you want to use - public sites get numerous SQL injection-style hack attempts.
For my current design the ID changes if the image is modified, so the caching time can be set to something long, e.g. a month or a year.