C# Table Adapter Update Not Working - c#

I am trying to serialize an object to a sql compact database. I am using VCS Express 2008. Every time I run a test to see if my data is sent to the database, nothing is in the database. My code:
string inputForDB = null;
QuizCategoryTableAdapter quizCategoryAdapter = new QuizCategoryTableAdapter();
QuizApp._QuizApp_DataSet.QuizCategoryDataTable quizCategoryTable = new QuizApp._QuizApp_DataSet.QuizCategoryDataTable();
quizCategoryAdapter.Fill(quizCategoryTable);
//Check to see if quizCategory exists
if (quizCategoryTable.Rows.Contains(quizCategory._categoryID)) {
//overwrite (update)
//Serialize the object and put in db
MemoryStream MemStream = new MemoryStream();
IFormatter formatter = new BinaryFormatter();
formatter.Serialize(MemStream, quizCategory);
inputForDB = Convert.ToBase64String(MemStream.ToArray());
quizCategoryAdapter.Insert(quizCategory._categoryName, quizCategory._categoryDescription, inputForDB);
//send update to database
MemStream.Close();
} else {
//append (insert)
MemoryStream MemStream2 = new MemoryStream();
IFormatter formatter2 = new BinaryFormatter();
formatter2.Serialize(MemStream2, quizCategory);
inputForDB = Convert.ToBase64String(MemStream2.ToArray());
quizCategoryAdapter.Insert(quizCategory._categoryName, quizCategory._categoryDescription, inputForDB);
MemStream2.Close();
}
It compiles fine, but for some reason does not work.

You have to call the Adapter Update method as well as AcceptChanges on the DataSet

Related

How to output Metafile (emf) into stream (or byte[])

For an application I'm currently developing, I need to create a .emf file.
I've got it working when I output the result directly to a file, but I can't get it to output into a stream, which is essential to what I'm trying to do.
This code correctly generates the file, but it's outputted directly to the harddisk.
var sizedImage = new Bitmap(103, 67);
using(var graphicsFromSizedImage = Graphics.FromImage(sizedImage))
using(var metafile = new Metafile("result.emf", graphicsFromSizedImage.GetHdc()))
using(var graphics = Graphics.FromImage(metafile))
{
graphics.DrawStuff()
graphicsFromSizedImage.ReleaseHdc();
}
Here's my attempt to output it to a memorystream, so I could get a byte[] from that stream:
byte[] resultingBytes;
var sizedImage = new Bitmap(103, 67);
using(var stream = new MemoryStream())
using(var graphicsFromSizedImage = Graphics.FromImage(sizedImage))
using(var metafile = new Metafile(stream, graphicsFromSizedImage.GetHdc()))
using(var graphics = Graphics.FromImage(metafile))
{
graphics.DrawStuff()
graphicsFromSizedImage.ReleaseHdc();
resultingBytes = stream.GetBuffer();
}
File.WriteAllBytes("result.emf", resultingBytes);
But all this does is create an empty file. When I run through it with the debugger, I can see the stream remain empty.
What am I missing here..?
I found the answer thanks to #Selvin
It turns out, the changes are only written to the MemoryStream when the "graphics" object is disposed. So, just by adding an extra set of brances, the problem is resolved.
Here's my working code:
byte[] resultingBytes;
var sizedImage = new Bitmap(103, 67);
using(var stream = new MemoryStream())
using(var graphicsFromSizedImage = Graphics.FromImage(sizedImage))
using(var metafile = new Metafile(stream, graphicsFromSizedImage.GetHdc()))
{
using(var graphics = Graphics.FromImage(metafile))
{
graphics.DrawStuff()
graphicsFromSizedImage.ReleaseHdc();
}
resultingBytes = stream.ToArray();
}
File.WriteAllBytes("result.emf", resultingBytes);
Edit: As some have pointed out, stream.GetBuffer() will return the entire buffer. I changed it to stream.ToArray(), which should be better.

Retrieve C# object from binary that saved in SQL Server database

I want save and retrieve an object from a database. I write C# code to save it as below, and it worked fine. Now I can save an object into the database.
ReportObject ro = new ReportObject()
{
Name = ctrl.Name,
BackColor = ctrl.BackColor,
ForeColor = ctrl.BackColor,
Fonts = ctrl.Font,
TypeofControl = ctrl.GetType()
};
MemoryStream memStream = new MemoryStream();
StreamWriter sw = new StreamWriter(memStream);
sw.Write(ro);
string sql = "INSERT INTO [TemplateDetails] ([Object]) VALUES (#Object)";
SqlCommand cmd = new SqlCommand(sql, con, tran);
cmd.Parameters.Add("#Object", SqlDbType.VarBinary, Int32.MaxValue);
cmd.Parameters["#Object"].Value = memStream.GetBuffer();
cmd.ExecuteNonQuery();
I am already saved a C# object ReportObject in SQL Server database. I want to retrieve it back to a C# object.
string sql = "SELECT [Object] FROM [TemplateDetails]"
SqlDataReader dr = db.Reader(sql);
if (dr.Read())
{
byte[] arrays = (byte[])dr["Object"];
}
I Solved problem myself.
first Serialize to a byte array and save in database.
enter ReportObject ro = new ReportObject()
{
Name = ctrl.Name,
BackColor = ctrl.BackColor,
ForeColor = ctrl.BackColor,
Fonts = ctrl.Font,
TypeofControl = ctrl.GetType()
};
MemoryStream memorystream = new MemoryStream();
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(memorystream, ro);
byte[] yourBytesToDb = memorystream.ToArray();
after retrieving from the database as a byte array. Deserialize and convert to object.
MemoryStream memorystreamd = new MemoryStream(arrBytes);
BinaryFormatter bfd = new BinaryFormatter();
ReportObject deserializedReportObject = bfd.Deserialize(memorystreamd) as ReportObject;

How to store and retrieve Chromium Web Browser object

I'm developing an application using cefSharp, all is good now i need to maintain history for all browser tabs opened and closed by user and providing a option for opening closed tabs.
Is there a way to store Chromium Web Browser object into memory or database and retrieve it from there.
I've used below code to store objects into database
var objBrowserTest = (ChromiumWebBrowser)browserControl;
MemoryStream memStream = new MemoryStream();
StreamWriter sw = new StreamWriter(memStream);
sw.Write(objBrowserTest);
string sql = #"
INSERT INTO tblBrowserObj(cromObj)
VALUES(#VarBinary);
SELECT ##identity";
string connectionstring;
connectionstring = ConfigurationManager.ConnectionStrings[0].ConnectionString;
SqlConnection objConn = new SqlConnection(connectionstring);
if (objConn.State == ConnectionState.Open)
{
objConn.Close();
}
objConn.Open();
SqlCommand sqlCmd = new SqlCommand(sql, objConn);
sqlCmd.Parameters.Add("#VarBinary", SqlDbType.VarBinary, Int32.MaxValue);
sqlCmd.Parameters["#VarBinary"].Value = memStream.GetBuffer();
string strID = sqlCmd.ExecuteScalar().ToString();
if (objConn.State == ConnectionState.Open)
{
objConn.Close();
}
Table structure
CREATE TABLE [dbo].[tblBrowserObj](
[id] [int] IDENTITY(1,1) NOT NULL,
[cromObj] [varbinary](max) NULL
) ON [PRIMARY]
My problem is that the memStream.GetBuffer() always shows byte[0].
Can any one tell me how can i store and retrieve Chromium Web Browser object from memory or database, or is there another way to do this type of stuff.
1 - Read/Write from memory
From Writing to then reading from a MemoryStream I extract some steps you should follow:
Don't forget to flush after sw.Write(objBrowserTest);
You have to reset the position of the stream with memStream.Position = 0; before read.
Wrap the stream with a StreamWriter and use the ReadToEnd() method to read all bytes of the stream.
Don't use GetBuffer(), it doesn't get the content of the stream, it takes the buffer of a buffered stream.
2 - Read/Write an Object from Byte[]
When you want to serialeze and object you have 2 classes to do it DataContractSerializer (DCS) and BinaryFormatter (BF).
2.1 - Serialize
When you want to serialize to a byte[] you can use the DCS 'WriteObtect' or the BF 'Serialize'. Both methods uses an stream (your memory stream) and an object.
2.2 - Deserialize
To deserialize an stored byte[] from it, you can use the DCS ReadObject and BF Deserialize (casting to the class). Both methods argument is the Stream to read from.
What you need to do
Serialize with one
Use the memStream.ToArray() to get the byte[] to store it.
When retrieving, use a a memory stream to write the array
Tips
Use the MemoryStream constructor with a byte[] argument and then Position = 0.
This code maybe helps you:
public byte[] ObjectToBytes(Object obj)
{
try
{
using (MemoryStream memStream = new MemoryStream())
{
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(memStream, obj);
return memStream.ToArray();
}
}
catch (Exception) { } // do what you want
return null;
}
public T BytesToObject<T>(byte[] array) where T : class
{
try
{
using (MemoryStream memStream = new MemoryStream(array) { Position = 0 })
{
BinaryFormatter formatter = new BinaryFormatter();
T obj = formatter.Deserialize(memStream) as T;
return obj;
}
}
catch (Exception) { } // do what you want
return null;
}
Simply use sqlCmd.Parameters["#VarBinary"].Value = ObjectToBytes(objBrowserTest ); and when retrieving use BytesToObject<ChromiumWebBrowser>(bytes);
Sources
http://www.digitalcoding.com/Code-Snippets/C-Sharp/C-Code-Snippet-Byte-array-to-object.html
How deserialize Byte array to object - Windows 8 / WP 8
https://msdn.microsoft.com/en-us/library/4abbf6k0(v=vs.110).aspx

Binary stream '0' does not contain a valid BinaryHeader error while Deserialization custom object

I faced this error while deserialization a custom object
I am trying to insert a collection of custom class into sql database & retrieve it the insertion going well but retrieving the data & deserialize give me this error
My code sample:
private void InsertObject()
{
ReceiptCollection items = SqlDataRepository.ReceiptProvider.GetAll();
string connectionString = "my connection";
System.Data.SqlClient.SqlConnection connection = new System.Data.SqlClient.SqlConnection(connectionString);
string sql = "INSERT INTO [dbo].[LogHeader]([MasterObject]) VALUES (#MasterObject)";
BinaryFormatter binaryFormatter = new BinaryFormatter();
MemoryStream memoryStream = new MemoryStream();
binaryFormatter.Serialize(memoryStream, items);
using (System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand(sql, connection))
{
byte[] bytes = new byte[memoryStream.Length];
memoryStream.Write(bytes, 0, bytes.Length);
connection.Open();
cmd.Parameters.AddWithValue("#MasterObject", bytes);
cmd.ExecuteNonQuery();
}
}
private void RetrieveObjects()
{
string connectionString = "my connection";
System.Data.SqlClient.SqlConnection connection = new System.Data.SqlClient.SqlConnection(connectionString);
string sql = "Select MasterObject From [dbo].[LogHeader] WHERE LogHeaderID=2";
using (System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand(sql, connection))
{
connection.Open();
byte[] bytes = (byte[])cmd.ExecuteScalar();
BinaryFormatter binaryFormatter = new BinaryFormatter();
MemoryStream memoryStream = new MemoryStream(bytes);
memoryStream.Position = 0;
ReceiptCollection items = (ReceiptCollection)binaryFormatter.Deserialize(memoryStream); // the error happened here
}
}
I was facing the same problem in the serialization and deserialization of a custom class. Everywhere I looked around, they have the same code marked as the solution (as your code presented on the top) but I couldn't make it run correctly. All I was recieving after the memoryStream.Write() method, was an array of zeroes. I changed my code and got it to work.
What I did was (implemented in your code):
BinaryFormatter binaryFormatter = new BinaryFormatter();
MemoryStream memoryStream = new MemoryStream();
binaryFormatter.Serialize(memoryStream, items);
using (System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand(sql, connection))
{
byte[] bytes = new byte[memoryStream.Capacity];
bytes = memoryStream.GetBuffer();
connection.Open();
cmd.Parameters.AddWithValue("#MasterObject", bytes);
cmd.ExecuteNonQuery();
}
This is for sending a byte array to the data base. For retrieving it, I did the following:
connection.Open();
byte[] bytes = (byte[])cmd.ExecuteScalar();
BinaryFormatter binaryFormatter = new BinaryFormatter();
using (MemoryStream memoryStream = new MemoryStream(bytes))
{
memoryStream.Position = 0;
ReceiptCollection items = (ReceiptCollection)binaryFormatter.Deserialize(memoryStream);
}
Try it! It really worked for me.
Start by checking what actually got stored in that column, and also check if the column's type is varbinary or similar. The error suggests that the serialized object's data stream got badly corrupted or truncated. If the row/column does not contain a long "hexstring", then there's a write problem with inserting/updating and search further there.

C# Object Binary Serialization

I want to make a binary serialize of an object and the result to save it in a database.
Person person = new Person();
person.Name = "something";
MemoryStream memorystream = new MemoryStream();
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(memorystream, person);
How can I transform memorystream in a string type to be saved in database, and after this to be able to deserialize the object?
What you're really asking for is a safe way of representing arbitrary binary data as text and then converting it back again. The fact that it stores a serialized object is irrelevant.
The answer is almost to use Base 64 (e.g. Convert.ToBase64String and Convert.FromBase64String). Do not use Encoding.UTF8.GetString or anything similar - your binary data is not encoded text data, and shouldn't be treated as such.
However, does your database not have a data type for binary data? Check for BLOB, IMAGE and BINARY types...
Here's the sample. TData must be marked [Serializable] and all fields type also.
private static TData DeserializeFromString<TData>(string settings)
{
byte[] b = Convert.FromBase64String(settings);
using (var stream = new MemoryStream(b))
{
var formatter = new BinaryFormatter();
stream.Seek(0, SeekOrigin.Begin);
return (TData)formatter.Deserialize(stream);
}
}
private static string SerializeToString<TData>(TData settings)
{
using (var stream = new MemoryStream())
{
var formatter = new BinaryFormatter();
formatter.Serialize(stream, settings);
stream.Flush();
stream.Position = 0;
return Convert.ToBase64String(stream.ToArray());
}
}
//-------write to database-------------------------
Person person = new Person();
person.name = "Firstnm Lastnm";
MemoryStream memorystream = new MemoryStream();
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(memorystream, person);
byte[] yourBytesToDb = memorystream.ToArray();
//here you write yourBytesToDb to database
//----------read from database---------------------
//here you read from database binary data into yourBytesFromDb
MemoryStream memorystreamd = new MemoryStream(yourBytesFromDb);
BinaryFormatter bfd = new BinaryFormatter();
Person deserializedperson = bfd.Deserialize(memorystreamd) as Person;
I used something like this
MemoryStream memoryStream = new MemoryStream();
BinaryFormatter binaryFormatter = new BinaryFormatter();
binaryFormatter.Serialize(memoryStream, Person);
memoryStream.Flush();
memoryStream.Position = 0;
string value = Convert.ToBase64String(memoryStream.ToArray());
Basically, don't save the data as string to the database, there are blob fields available to store binary data.
If you really need to have the data as string, you'll need to convert your byte[] to a string using base64 encoding, and to grab the byte[] from a string use decoding.
Have you not looked into converting the memorystream into a base64hex string to be put into the database?
byte[] mStream = memorystream.ToArray();
string sConvertdHex = System.Convert.ToBase64String(mStream)
Then you can dump the contents sConvertdHex to the database. To deserialize it you need to do the reverse
byte[] mData = System.Convert.FromBase64String(...)
then deserialize mData back to your object.

Categories