I am using asp.net to create a mobile web application to manage bike parts
I have gotten the file upload working but now I need to figure out how to get an image control to display the image from its new location on a server.
I will be saving the image file path in a database I just need to figure out how to get that new file path for the image.
this is the code I am using for the file upload
if (this.FileUpload1.HasFile)
{
this.FileUpload1.SaveAs(Server.MapPath("~/Mobile/" + FileUpload1.FileName));
}
I can likely figure this out but just in case I can't figured I would post the question now than later as it can take a while to get an answer and I have a dead line
You are going to have to use an "ImageHandler" to read the image properly.
This is how I did my handler.
public class ImageHandler : IHttpHandler
{
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["dboBlog"].ConnectionString);
public void ProcessRequest(HttpContext context)
{
try
{
string messageid = context.Request.QueryString["mid"];
conn.Open();
SqlCommand command = new SqlCommand("SELECT Image from BlogMessages WHERE Image IS NOT NULL AND MessageID=" + messageid, conn);
SqlDataReader dr = command.ExecuteReader();
if (dr.Read())
{
context.Response.BinaryWrite((Byte[])dr[0]);
conn.Close();
context.Response.End();
}
}
catch (Exception ex)
{
return;
}
}
public bool IsReusable
{
get
{
return false;
}
}
}
As you can tell, I use a QueryString. I use this querystring to call the image back. I call my image back in a gridview but this is how it looks...
<asp:Image ID="postImage" runat="server" ImageUrl='<%# "ImageHandler.ashx?mid="+ Eval("MessageID") %>' Width="400px" AlternateText="No Image" ImageAlign="Middle" Visible="false" />
I do set the visibility to false because it's a blog and sometimes people don't upload an image. As you can tell, the image url calls the ImageHandler where the querystring is equal to the MessageID.
This works for me, so hopefully it will help you out.
Related
I have a FileUpload control and I am trying to upload an image to server with it but it fails. My view:
<asp:FileUpload ID="FileUploadImage" runat="server" />
And my c#:
try
{
HttpPostedFile yuklenecekDosya = FileUploadImage.PostedFile;
if (yuklenecekDosya != null)
{
FileInfo dosyaBilgisi = new FileInfo(yuklenecekDosya.FileName);
string yuklemeYeri =
Server.MapPath("~/Images/NewUrunler/" + dosyaBilgisi);
FileUploadImage.SaveAs(Path.Combine(yuklemeYeri));
}
}
//some code for catch
It does not give any error but also it doesn't upload image. I spend hours on it and only thing I get is 'yuklenecekDosya' come as null when I debug it. Why is it null ?
I'm using byte[] symbols to store images data in a database like this:
ITEM_IMAGE VARBINARY(MAX),
And then when I retrieve the image and display it, I proceed like this:
<img src="data:image/png;base64, #(Convert.ToBase64String(Model.mChildCard.NormalImage))" alt="#Model.mChildCard.mCardName" title="#Model.mChildCard.mCardName" class="nullify"/>
I do this because I cannot guarantee that our application will have write access on the server it will be deployed and, instead of storing the images in normal files (and there are a LOT of images, talking about 70k and more), we choose to store them in database and retrieve them as such.
Now I want to make sure this is the best way of handling those files in razor views as there may be a lot of images displayed at once. Will it have an impact on the speed it is rendered? What "weight" will have the database? Is there a better way to do things?
public FileStreamResult GetDBImage(string imageId)
{
using (var conn = GetConnection())
{
conn.Open();
using (var cmd = conn.CreateCommand)
{
cmd.CommandText = "SELECT ITEM_IMAGE FROM ... WHERE id=#id";
cmd.Parameters.Add("#id", imageId);
using (var rdr = cmd.ExecuteReader())
return File(rdr.GetStream(0), "image/png")
}
}
}
Also, consider using async.
To serve images:
Your new controller action:
public ActionResult GetImage(string imageID)
{
byte[] imgArray;
//call your db and get your byte array.
if(imgArray != null)
{
return File(imageArray, "image/png");
}
else
{
throw new HttpException(404);
}
}
Add a route:
routes.MapRoute("Images", "images/{imageId}", New With {.controller = "yourImageController", .action = "GetImage")
And from your HTML:
<img src="#Url.Action("GetImage", "YourImageController", new{ #imageId=Model.mChildCard.imageId})" alt="#Model.mChildCard.mCardName" title="#Model.mChildCard.mCardName" class="nullify"/>
I am able to select multiple files using fileupload control but when I try to save it to a database it's giving me an "Object reference not set to an instance of an object" error.
if (FileUpload1.HasFiles)
{
foreach (HttpPostedFile uploaded in FileUpload1.PostedFiles)
{
bindata = new BinaryReader(uploaded.InputStream);
ImageByteArray = bindata.ReadBytes(uploaded.ContentLength);
// byte array is sent to a method
dbmt.SaveImageToDB(ImageByteArray);
}
}
And the following is my code for the SaveImageToDB method
public void SaveImageToDB(byte[] ImageByteArray)
{
try
{
scon.Open();
scm.Connection = scon;
scm.CommandType = CommandType.StoredProcedure;
scm.CommandText = "SaveProfileImage";
SqlParameter paramImgArray = scm.Parameters.Add("#ImgBody", SqlDbType.Image,0);
paramImgArray.Direction = ParameterDirection.Input;
paramImgArray.Value = ImageByteArray;
scm.ExecuteNonQuery();
}
catch( SqlException sqx )
{
throw sqx;
}
}
Set The Property AllowMultiple = True in fileupload control.
protected void uploadFile_Click(object sender, EventArgs e)
{
if (UploadImages.HasFiles)
{
foreach (HttpPostedFile uploadedFile in UploadImages.PostedFiles)
{
uploadedFile.SaveAs(System.IO.Path.Combine(Server.MapPath("~/Images/"),
uploadedFile.FileName));
listofuploadedfiles.Text += String.Format("{0}<br/>", uploadedFile.FileName);
}
}
}
I understand that it is giving an error in the said method, but on which line inside that method is giving this error?
I assume that the method you have given here is complete (i.e. there is no code which you have deleted before pasting it here), so i guess there are only 2 objects which could be null and those are "scon" and "scm". Put a breakpoint on the line "scon.Open();" and on line "scm.Connection = scon;". Once the execution stops on each of these lines, hover your mouse over "scon" and then over "scm". I guess either one of them will be null.
Hope this helps.
The problem was my object. It was not instantiated correctly. I was accessing a class within appcode called DBmiddleTier to access a database and write the image file. Here is what I did wrong: DBMiddleTier dbmt; <-----"WRONG". Here is what I did to correct the problem DBMiddleTier dbmt = new DBMiddleTier();
Good night-morning-evening-etc ^_^
I'm getting problems while trying to display an image in asp:Image (using Web Forms), stored in a db as byte[] - found a lot of rather clear answers, how to do it, so now I have a handler:
public class ShowImageHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
//creating object, working with db
var core = new CoreHolder();
var picture = core.PictureRepository.Read(Convert.ToInt32(context.Request.QueryString["id"]))
context.Response.Clear();
context.Response.ContentType = picture.PictureMimeType;
//trying to write byte[]
context.Response.BinaryWrite(picture.PictureData);
context.Response.End();
}
public bool IsReusable
{
get
{
return false;
}
}
}
...and such strings in my .aspx page:
<asp:Image ID="Image1" runat="server" ImageUrl="~/ShowImageHandler.ashx?id=<%#:Item.ID %>" />
<asp:Image ID="Image1" runat="server" ImageUrl="~/ShowImageHandler.ashx?id=1>" />
The problems are: ok, the program enters the ProcessRequest with id, and in case of the second asp-image string it finds the pic with data, but even before trying to BinaryWrite I can see, that there are exeptions in context.Response.OutputStream: length,position - System.NotSupportedExeption, Read/WriteTimeout - System.InvalidOperationExeption. In case of the first string (it's used in ListView ItemTemplate) the OutputStream problem stays + all crushes on trying to get the id from the query string.
Help, please)
The errors you see in the debugger for context.Response.OutputStream.Length and Position don't matter. You can only write to that stream so the exceptions you see in the debugger display are expected.
Your code looks fine so my guess is that if you look at the URL, the value for your id querystring argument will not be an integer. You are probably getting a FormatException when you try to convert it to an integer.
You should test the handler by putting the url "ShowImageHandler.ashx?id=1" in your browser's address bar instead of using an <img /> tag. That way if there is an exception you can get a real stack trace instead of just seeing a broken image.
What i am trying to do is, i am getting file name/path using asp.net uploader control and then saving its path it grid view. e.g
String path = String.Empty;
path = FileUploader.FileName;
and then saving this path in grid view column.
savefiletoGrid(path);
After uploading all required files i am saving these file on server. like this
while( // condition )
{
string tempfilename = ""; // file name/path from gridview
string path2 = Server.MapPath("Dir\\" + tempfilename);
FileUploader.SaveAs(path2);
}
But, problem is that file is being saved on server with correct name but with size 0 byte.
Please let me know how to solve this issue ?
Actually i want something like client upload in asp.net, i 'll upload more than one file and show them in gridview ( or in something else ) so that user can see files to be selected and can delete from listed files.
File 'll be saved to server only when user click some other button say 'Update'. could you please help me , how to accomplish this ?
You have to catch the event generated in GridView in its RowCommand event also set a CommandName property for upload button.
Following is the detailed code through which you can accomplish this:
<asp:GridView ID="GridView1" runat="server" OnRowCommand="GridView1_RowCommand">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:FileUpload ID="FileUpload1" runat="server" />
<asp:Button ID="Button1" runat="server" Text="Upload" CommandName="Upload"/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
And in you code behind:
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Upload")
{
FileUpload FileUp = (FileUpload)e.Item.FindControl("FileUpload1");
string UploadedFileName = FileUp.FileName;
string Path = Server.MapPath("Documents");
FileUpload.SaveAs(Path + "\\" + UploadedFileName);
}
}
Hope it helps.
To accomplish this functionality, you'll have to let the user upload the files. You must save them temporarily to display them.
Then, upon the user clicking an 'Update' button, you will transfer the temporary files to your permanent storage.
Do you keep the FileUploaders in a GridView?
Problem has been solved by creating a DataTable with one column for control (with column data Type FileUpload) for example :
private DataTable CreateDtDocs(string name, string path, FileUpload FileUploader)
{
DataTable dt1 = new DataTable();
dt1.Columns.Add("SR_NO");
dt1.Columns.Add("Name");
dt1.Columns.Add("Path");
Type col_type = fubrowse.GetType();
DataColumn dt_col = new DataColumn("Control", col_type);
dt1.Columns.Add(dt_col);
DataRow dr = dt1.NewRow();
dr["SR_NO"] = "1";
dr["NAME"] = name;
dr["Path"] = path;
dr["Control"] = FileUploader;
dt1.Rows.Add(dr);
return dt1;
}
And then Populate table like below :
private DataTable AddDtDocs(string name, string path, FileUpload FileUploader)
{
DataTable dt1 = (DataTable)Session["AttachFilesdt"];
int count = dt1.Rows.Count;
DataRow dr = dt1.NewRow();
dr["SR_NO"] = count + 1;
dr["NAME"] = name;
dr["Path"] = path;
dr["Control"] = FileUploader;
dt1.Rows.Add(dr);
return dt1;
}
And then i am adding path name and control in Dictionary and passing them to a different function to save them on server.
Dictionary<string, FileUpload> DocsPathAndControl = new Dictionary<string, FileUpload>();
if (Session["AttachFilesdt"] != null)
{
tempdt = (DataTable)Session["AttachFilesdt"];
for (int i = 0; i < tempdt.Rows.Count; i++)
{
DocsPathAndControl.Add(tempdt.Rows[i]["Path"].ToString(), (FileUpload)tempdt.Rows[i]["Control"]);
}
Session["AttachFilesdt"] = null;
}
Function to save Files
private void AddDocuments(int jurisdictionID, Dictionary<string,FileUpload> docPathsAndControl)
{
foreach (var item in docPathsAndControl)
{
string tempfilename = jurisdictionID + "_" + item.Key.ToString();
string path = Server.MapPath("Dir\\" + tempfilename);
FileUpload FileUploaderControl = (FileUpload)item.Value;
FileUploaderControl.PostedFile.SaveAs(path);
}
}
Hope, it 'll help.