EWS - Image size/measurements - c#

I need to check if the image has special messurements like 25px25p so i do not save all images from our mailsigniture (Xing, LinkedIn, Twitter, etc.). Retrieveing the images from the mail works how it should.
I have a little program which retrieves emails from the server and saves them to database. It also saves all Attachments. The necessary code part looks like this:
else if (attachment is FileAttachment || attachment.IsInline)
{
FileAttachment fileAttachment = attachment as FileAttachment;
fileAttachment.Load();
string sfilename = fileAttachment.Name;
string sContentType = fileAttachment.ContentType;
using (var fs = new MemoryStream(fileAttachment.Content))
{
using (BinaryReader br = new BinaryReader(fs))
{
byte[] bytes = br.ReadBytes((int)fs.Length);
var oSQLConnection = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["..."].ConnectionString);
var cmd = new SqlCommand();
cmd.Connection = oSQLConnection;
cmd.CommandType = CommandType.Text;
string sTicketID = gTicketID.ToString() ?? string.Empty;
cmd.CommandText = "INSERT INTO TBL_Attachment (fkTicketID, fkMailID, FileName, ContentType, Data)VALUES('"+sTicketID+"', '"+snFile+"', '"+sfilename+"', '"+sContentType+"', #Data)";
var DataParameter = new SqlParameter("#Data", SqlDbType.Binary);
cmd.Parameters.Add(DataParameter);
DataParameter.Value = bytes;
.
.
.
I convert the file to byte and save it to the database.
Is it possible to get the file/image messurements for an if statement?

I found an obvious solution. I just had to convert my MemoryStream to Image and check with and hight.
using (var fs = new MemoryStream(fileAttachment.Content))
{
Image image = System.Drawing.Image.FromStream(fs);
if (!(image.Width == 190 && image.Height == 45) )
{
using (BinaryReader br = new BinaryReader(fs))
{
...

Related

How to retrieve image from database of image datatype to the PhotoBox in c#

The code below is my photo selecting selector (the other button I have in my project is just sending the picArray to the table in the column of image datatype):
private void FileSelectorButton_Click(object sender, EventArgs e)
{
OpenFileDialog ImageSelectorWindow = new OpenFileDialog();
ImageSelectorWindow.Filter = "JPG |*.jpg|PNG |*.png|Bitmap |*.bmp";
ImageSelectorWindow.Title = "Choose an Image";
if (ImageSelectorWindow.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
fileName = ImageSelectorWindow.FileName;
FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
picArray = new byte[fs.Length];
fs.Read(picArray, 0, Convert.ToInt32(fs.Length));
fs.Close();
}
TBFilePath.Text = fileName;
}
Below is my image retrieval code:
SqlCommand cmd2 = new SqlCommand("SELECT avatar FROM Members WHERE Id = '" + value + "'", con);
SqlDataReader dr = cmd2.ExecuteReader();
MemoryStream ms = new MemoryStream((byte[])dr[0]);
PBMemberImage.BackgroundImage = new Bitmap(ms);
This is giving me the following exception:
Can someone help me figure out why?
Retrieve Images from sql server database
Take a look at that and try the code below for retrieving your image. Let me know if that works or not.
byte[] img = (byte[])cmd2.ExecuteScalar();
MemoryStream ms = new MemoryStream();
ms.Write(img, 0, img.Length);
PBMemberImage.BackgroundImage = new Bitmap(ms);

How to process uploaded files in ASP.NET core 2.0

We are trying to migrate our code from ASP.NET that was written some time ago to ASP.NET Core 2.0.
This piece of code stores a document in SQL Server and retrieves it.
***Original Code:***
protected void btnUpload_Click(object sender, EventArgs e)
{
foreach (HttpPostedFile postedFile in multipleUpload.PostedFiles)
{
string filename = Path.GetFileName(postedFile.FileName);
string contentType = postedFile.ContentType;
using (Stream fs = postedFile.InputStream)
{
using (BinaryReader br = new BinaryReader(fs))
{
byte[] bytes = br.ReadBytes((Int32)fs.Length);
string constr = ConfigurationManager.ConnectionStrings["ab"].ConnectionString;
using (SqlConnection con = new SqlConnection(constr))
{
string query = "insert into ftr_UploadMultiple (name,contentType,data) values (#Name, #ContentType, #Data)";
using (SqlCommand cmd = new SqlCommand(query))
{
cmd.Connection = con;
cmd.Parameters.AddWithValue("#Name", filename);
cmd.Parameters.AddWithValue("#ContentType", contentType);
cmd.Parameters.AddWithValue("#Data", bytes);
con.Open();
cmd.ExecuteNonQuery();
con.Close();
We did try with the following code, it only stores 0 bytes in the DB:
Any suggestions around this should be really helpful.
Our Code in ASP.NET Core 2.0
if (file.Length > 0)
{
using (var stream = new
FileStream(filePath, FileMode.Create))
{
await file.CopyToAsync(stream);
using (BinaryReader br = new BinaryReader(stream))
{
byte[] bytes = br.ReadBytes((Int32)stream.Length);
string constr = "<Connection String";
using (SqlConnection con = new SqlConnection(constr))
{
string query = "insert into ftr_UploadMultiple (data) values (#Data)";
using (SqlCommand cmd = new SqlCommand(query))
{
cmd.Connection = con;
cmd.Parameters.AddWithValue("#Data", bytes);
con.Open();
cmd.ExecuteNonQuery();
con.Close();
I have deliberately removed the closing }s. Also, facing an issue in Downloading already uploaded file as Response.Binarywrite() is not available in ASP.NET Core 2.0.
After you call CopyToAsync to copy the bytes from the upload file to the filestream, the filestream's position is at the end. When you then attempt to read from the filestream, you're only reading the null byte at the end, resulting in 0 bytes being read.
The simplest solution is to just add the following before you read:
stream.Position = 0;
However, unless you actually need to write the file to the filesystem as well, this is just extraneous work. It would be better to copy the upload file's stream to a MemoryStream and then simply use ToArray to get the bytes from that: no need for additional reader.
Try get bytes array from InputStream
// Read bytes from http input stream
BinaryReader b = new BinaryReader(file.InputStream);
byte[] binData = b.ReadBytes(file.ContentLength);
ASP.NET Core
if (file.Length > 0)
{
using (BinaryReader br = new BinaryReader(file.InputStream))
{
/* ... use file.Length or file.ContentLength */
byte[] bytes = br.ReadBytes(file.Length);
/* ... File Processing (bytes) */
}
}
.

How to make use of memorystream instead of filestream

So what im trying to do is read a Select store procedure from my database save the data in a csv file and make it that the user is able to download it through the web application. I was able to get the requested result by saving the file temporary into my program foldel and using filestream. What i want to do now is skip the part where the file is saved onto my computer and temporary save it in the RAM memory instead. From what i understood i have to make use of memory stream instead of file stream but i dont really understand how i can do that. From what i understood from what i read is that instead of me making use of a file i need to convert my data to bytes make a memorystream out of it and then use it in my FileStreamResult. Am i correct here?
Method when i read from procedure and save to a csvfile:
public static String StoreApproved ()
{
string path1 = HttpRuntime.AppDomainAppPath + "Report.csv";
SqlConnection sqlConnection1 = new SqlConnection("CONNECTIONSTRING");
SqlCommand cmd = new SqlCommand();
SqlDataReader reader;
cmd.CommandText = "ExportApproved";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Connection = sqlConnection1;
sqlConnection1.Open();
reader = cmd.ExecuteReader();
List<ModelStoreProcedureApproved> TestList = new List<ModelStoreProcedureApproved>();
ModelStoreProcedureApproved test ;
while (reader.Read())
{
test = new ModelStoreProcedureApproved();
// test.Id = int.Parse(reader["IdTimeTracker"].ToString());
test.Month = reader["Month"].ToString();
test.EmailUser = reader["Email"].ToString();
test.Project = reader["Name"].ToString();
test.Approved = reader["Description"].ToString();
test.Month = reader["Month"].ToString();
test.Year = reader["Year"].ToString();
TestList.Add(test);
}
File.Create(path1).Close();
var i = TestList.FirstOrDefault();
using (TextWriter fileReader = new StreamWriter(path1))
{
var csv = new CsvWriter(fileReader);
csv.Configuration.Encoding = Encoding.UTF8;
foreach (var value in TestList)
{
csv.WriteRecord(value);
}
fileReader.Close();
}
sqlConnection1.Close();
return path1;
}
Controller code:
public ActionResult ExportToCSV()
{
string path = Repositories.UserRepository.StoreApproved();
var fileStream = new FileStream(path,
FileMode.Open,
FileAccess.Read);
return new FileStreamResult(fileStream, "text/csv") { FileDownloadName = "export.csv" };
}
Can someone explain me what the best way to do this is?
Other posts i have read
Serialize and Deserialize using BinaryFormatter
BinaryFormatter and Deserialization Complex objects
Using CSVHelper to output stream to browser
You can make it like this:
public static byte[] StoreApproved ()
{
string path1 = HttpRuntime.AppDomainAppPath + "Report.csv";
SqlConnection sqlConnection1 = new SqlConnection("CONNECTIONSTRING");
SqlCommand cmd = new SqlCommand();
SqlDataReader reader;
cmd.CommandText = "ExportApproved";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Connection = sqlConnection1;
sqlConnection1.Open();
reader = cmd.ExecuteReader();
List<ModelStoreProcedureApproved> TestList = new List<ModelStoreProcedureApproved>();
ModelStoreProcedureApproved test ;
while (reader.Read())
{
test = new ModelStoreProcedureApproved();
// test.Id = int.Parse(reader["IdTimeTracker"].ToString());
test.Month = reader["Month"].ToString();
test.EmailUser = reader["Email"].ToString();
test.Project = reader["Name"].ToString();
test.Approved = reader["Description"].ToString();
test.Month = reader["Month"].ToString();
test.Year = reader["Year"].ToString();
TestList.Add(test);
}
var i = TestList.FirstOrDefault();
var mem = new MemoryStream();
using (TextWriter fileReader = new StreamWriter(mem))
{
var csv = new CsvWriter(fileReader);
csv.Configuration.Encoding = Encoding.UTF8;
foreach (var value in TestList)
{
csv.WriteRecord(value);
}
}
sqlConnection1.Close();
return mem.ToArray();
}
public ActionResult ExportToCSV()
{
byte[] bytes = Repositories.UserRepository.StoreApproved();
Stream stream = new MemoryStream(bytes);
return new FileStreamResult(stream, "text/csv") { FileDownloadName = "export.csv" };
}
I suggest you make clean separation of concerns since you are also using Asp.Net MVC. Instead of reading and creating memory stream inside same method, first read/get the data collection you need and just return the data out of the method. Then inside the action method you can decorate it with required format(binding to UI or returning a file etc.) based on your requirement
Though this is not be a straight answer to your question, and if all that you are looking for is using a memory stream, there are plenty of examples available to use for example as shown here and the answer you accepted etc.
Hope this help you.
using (var ms = new MemoryStream())
{
using (var writer = new StreamWriter(ms))
using (var csv = new CsvWriter(writer))
{
csv.WriteRecords({A list here});
}
ms.ToArray() // here is your actual data in memory stream
}

Browser not displaying base64 images

I want to display images on browser by converting them to base64 string.
Method of conversion is very simple as follows
string convertedfile = Convert.ToBase64String(fileData);
base64 string
<img src="data:image/jpeg;base64,DQoaCgAAAA1JSERSAAAAFAAAABQIBgAAAI2JHQ0AAAABc1JHQgCuzhzpAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAOxAAADsQBlSsOGwAAAAl2cEFnAAAAgAAAAIAAMOExmgAAAAZiS0dEAAAAAAAA+UO7fwAAACJ6VFh0U29mdHdhcmUAAHjaKy8v18vMyy5OTixI1csvSgcANtgGWBBTylwAAADzSURBVDhPY/wPBAxUBExUNAts1KiBlIfoaBhiD8N1NycwHLi/mqgAJhiGp15uYtj1aCbD5OMZDDdenSJsKCjr4QJvfzz977GZAS5t2Mvw//P3j/i0/EeoRlP299/v/667UaX//vv7X6MOpxawCThlw04z/H//8zmGa158fPDfsBq3oYzYSpusW8IMPgJVDEa8gQxff31k+P8PaPE/Bob/fxkYuNkEGfZeXskwZ1cnw6Hm9xhhimHgn/8/Gea9SGP485OR4fu37wx/fzIw/PkBwTA2818OIP8fQ0P4XAY2FjYUQ7G6kHBU4lZBMNmQavjgNxAArnYq4oN7ItkAAAAASUVORK5CYII=" alt="Original File"/>
For some reason my browser is not able to display it. Is there any MIME type I have to set in IIS? or what could be the problem?
Edit:
To write file data to SQL
Stream fs = imgUpload.PostedFile.InputStream;
BinaryReader br = new BinaryReader(fs);
Byte[] bytes = br.ReadBytes((Int32)fs.Length);
//string base64String = Convert.ToBase64String(bytes);
//imgPicture.Src = "data:image/png;base64," + base64String;
SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["connectionString"].ToString());
conn.Open();
using (SqlCommand cmd = new SqlCommand("update tbEHUsers set photo=#binaryValue where UserID=101", conn))
{
// Replace 8000, below, with the correct size of the field
cmd.Parameters.Add("#binaryValue", SqlDbType.VarBinary, -1).Value = bytes;
cmd.ExecuteNonQuery();
}
conn.Close();
My method to get image data from SQL(column datatype varbinary)
byte[] fileData =null;
using (SqlDataReader rdr = CMD.ExecuteReader(CommandBehavior.SequentialAccess))
{
if (rdr.Read())
{
// For some reason the data being returned is blank
// When I run it in SQL I get data being returned.
fileData = (byte[])rdr.GetValue(0);
using (System.IO.FileStream fs = new System.IO.FileStream("D:\\Testing.jpg", System.IO.FileMode.Create, System.IO.FileAccess.ReadWrite))
{
using (System.IO.BinaryWriter bw = new System.IO.BinaryWriter(fs))
{
bw.Write(fileData);
bw.Close();
}
}
}
rdr.Close();
}
The data that you have isn't a PNG image at all. Exchange it for a real PNG image, and it will work.
Example, a 10x10 red square:
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAXSURBVChTY/jPwPCfGDyqEC+mtkKG/wCSw8c5Wcde4gAAAABJRU5ErkJggg==">
Here is your original image in base64 form:
<img src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAAUABQDASIAAhEBAxEB/8QAGAABAAMBAAAAAAAAAAAAAAAAAAQFBgf/xAAiEAABBAEDBQEAAAAAAAAAAAABAAIDBBEFEkETITFDUbH/xAAWAQEBAQAAAAAAAAAAAAAAAAAAAgP/xAAZEQEBAQADAAAAAAAAAAAAAAAAAQIDERL/2gAMAwEAAhEDEQA/AO/oot+62jW6hALnO2MDjgFx+ngck/pwFUQaxFSuwwyaky7HaeGEtxuilPjDR6ye3JacZJBJbneXM15TdyXpoURFooREQEREH//Z">

How to store the file in the database?

How to store the file which is uploaded by the user to the database ? I want to store the file in the database how can we do that ? In the back-end I am using sql with c#.net application.
This solution works for SQL SERVER 2005/2008.
You have to create table with VARBINARY(MAX) as one of the columns. In my case I've created Table Raporty with column RaportPlik being VARBINARY(MAX) column.
Below there are couple of support functions you can modify for your needs:
public static void databaseFilePut(string varFilePath) {
byte[] file;
using (var stream = new FileStream(varFilePath, FileMode.Open, FileAccess.Read)) {
using (var reader = new BinaryReader(stream)) {
file = reader.ReadBytes((int) stream.Length);
}
}
using (var varConnection = Locale.sqlConnectOneTime(Locale.sqlDataConnectionDetails))
using (var sqlWrite = new SqlCommand("INSERT INTO Raporty (RaportPlik) Values(#File)", varConnection)) {
sqlWrite.Parameters.Add("#File", SqlDbType.VarBinary, file.Length).Value = file;
sqlWrite.ExecuteNonQuery();
}
}
public static void databaseFileRead(string varID, string varPathToNewLocation) {
using (var varConnection = Locale.sqlConnectOneTime(Locale.sqlDataConnectionDetails))
using (var sqlQuery = new SqlCommand(#"SELECT [RaportPlik] FROM [dbo].[Raporty] WHERE [RaportID] = #varID", varConnection)) {
sqlQuery.Parameters.AddWithValue("#varID", varID);
using (var sqlQueryResult = sqlQuery.ExecuteReader())
if (sqlQueryResult != null) {
sqlQueryResult.Read();
var blob = new Byte[(sqlQueryResult.GetBytes(0, 0, null, 0, int.MaxValue))];
sqlQueryResult.GetBytes(0, 0, blob, 0, blob.Length);
using (var fs = new FileStream(varPathToNewLocation, FileMode.Create, FileAccess.Write)) fs.Write(blob, 0, blob.Length);
}
}
}
public static MemoryStream databaseFileRead(string varID) {
MemoryStream memoryStream = new MemoryStream();
using (var varConnection = Locale.sqlConnectOneTime(Locale.sqlDataConnectionDetails))
using (var sqlQuery = new SqlCommand(#"SELECT [RaportPlik] FROM [dbo].[Raporty] WHERE [RaportID] = #varID", varConnection)) {
sqlQuery.Parameters.AddWithValue("#varID", varID);
using (var sqlQueryResult = sqlQuery.ExecuteReader())
if (sqlQueryResult != null) {
sqlQueryResult.Read();
var blob = new Byte[(sqlQueryResult.GetBytes(0, 0, null, 0, int.MaxValue))];
sqlQueryResult.GetBytes(0, 0, blob, 0, blob.Length);
//using (var fs = new MemoryStream(memoryStream, FileMode.Create, FileAccess.Write)) {
memoryStream.Write(blob, 0, blob.Length);
//}
}
}
return memoryStream;
}
First method is to put file into database from drive, second method is to get file and save it on drive, and 3rd method is to get file from database and put it as MemoryStream so you can some other stuff with it then just writing it to drive.
This 4th method is to put MemoryStream into database:
public static int databaseFilePut(MemoryStream fileToPut) {
int varID = 0;
byte[] file = fileToPut.ToArray();
const string preparedCommand = #"
INSERT INTO [dbo].[Raporty]
([RaportPlik])
VALUES
(#File)
SELECT [RaportID] FROM [dbo].[Raporty]
WHERE [RaportID] = SCOPE_IDENTITY()
";
using (var varConnection = Locale.sqlConnectOneTime(Locale.sqlDataConnectionDetails))
using (var sqlWrite = new SqlCommand(preparedCommand, varConnection)) {
sqlWrite.Parameters.Add("#File", SqlDbType.VarBinary, file.Length).Value = file;
using (var sqlWriteQuery = sqlWrite.ExecuteReader())
while (sqlWriteQuery != null && sqlWriteQuery.Read()) {
varID = sqlWriteQuery["RaportID"] is int ? (int) sqlWriteQuery["RaportID"] : 0;
}
}
return varID;
}
MS SQL Server 2008 (and above, I guess) offers FileStream data type. Just Google for it (or Bing it, whatever :-)), I think you'll find what you need.
Assuming SQL 2005 or later, I would use a VarBinary(MAX) field. Pass the uploaded file as a byte[] to the insert statement. According to Microsoft, since SQL 2005, storing large chunks of data (files and images) in the DB no longer decreases performance to a great extent.
eg:
public void SaveFileToDB(string description, byte[] file)
{
using (SqlConnection con = new SqlConnection(conStr)
{
con.Open();
using (SqlCommand cmd = con.CreateCommand())
{
cmd.Parameters.Add("#Description", SqlDbType.VarChar, description);
cmd.Parameters.Add("#File", SqlDbType.VarBinary, file);
cmd.CommandText = "UploadedFileUpdate";
cmd.CommandType = CommandType.StoredProcedure;
cmd.ExecuteNonQuery();
}
}
}
If you have SQL 2008, see Ron Klein's suggestion.
One solution that will keep your db size down is to store the location of the file on the server. IE a file path.
However you will have to make a manager if you ever want to move files about.
You can use a blob field type. When you read the file in from a StreamReader convert it to a byte array and then insert that into the blob field.
The reverse procedure when you want to read it, get the blob as a byte array, read it into a streamreader and write that to the response buffer.

Categories