iTextSharp.text.Document to byte[] - serializable

Hi,
I have created a pdf document using iTextSharp, While the document is in memory, I want to make it as byte[] so that i can convert it as attachment to mail. I tried with the following code.
private byte[] ObjectToByteArray(Object obj)//passed iTextSharp document as object
{
if (obj == null)
return null;
BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
bf.Serialize(ms, obj);
return ms.ToArray();
}
I am getting the following error.
Type 'iTextSharp.text.Document' in Assembly 'itextsharp, Version=5.4.4.0, Culture=neutral, PublicKeyToken=8354ae6d2174ddca' is not marked as serializable.
How to overcome this?

Related

How do I use a String as a Stream in .Net?

I need to call a method that accepts a stream argument. The method loads text into the stream, which would normally be a file. I'd like to simply populate a string with the contents of the stream, instead of writing it to a file. How do I do this?
Use a MemoryStream with a StreamReader. Something like:
using (MemoryStream ms = new MemoryStream())
using (StreamReader sr = new StreamReader(ms))
{
// pass the memory stream to method
ms.Seek(0, SeekOrigin.Begin); // added from itsmatt
string s = sr.ReadToEnd();
}
Use the StringWriter to act as a stream onto a string:
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
CallYourMethodWhichWritesToYourStream(sw);
return sb.ToString();
Look up MemoryStream class
MemoryStream ms = new MemoryStream();
YourFunc(ms);
ms.Seek(0, SeekOrigin.Begin);
StreamReader sr = new StreamReader(ms);
string mystring = sr.ReadToEnd();
is one way to do it.
you can do something like:
string s = "Wahoo!";
int n = 452;
using( Stream stream = new MemoryStream() ) {
// Write to the stream
byte[] bytes1 = UnicodeEncoding.Unicode.GetBytes(s);
byte[] bytes2 = BitConverter.GetBytes(n);
stream.Write(bytes1, 0, bytes1.Length);
stream.Write(bytes2, 0, bytes2.Length);

Generate PDF for Download using iText 7 in MVC and .NET

I have been trying to get an MVC application to generate a PDF(populated with data) and prompt to download it to the user. I've setup a test method just to see how it would be done, and I'm trying to create the document in memory since I know browsers don't always know what to do if you just pass it a byte stream.
Here is the method I'm using:
//Test Report
public ActionResult Report()
{
MemoryStream stream = new MemoryStream();
PdfWriter wri = new PdfWriter(stream);
PdfDocument pdf = new PdfDocument(wri);
Document doc = new Document(pdf);
doc.Add(new Paragraph("Hello World!"));
doc.Close();
return new FileStreamResult(stream, "application/pdf");
}
Every time I attempt to load the Report() method, I get an error saying that the stream cannot be accessed because it's closed. I've looked into a few different explanations into why this is, but all of them seem to be for iTextSharp and iText 5, so the solutions don't work.
What am I doing wrong, here?
try to dispose any IDisposable object and return a raw array
public ActionResult Report()
{
byte[] pdfBytes;
using (var stream = new MemoryStream())
using (var wri = new PdfWriter(stream))
using (var pdf = new PdfDocument(wri))
using (var doc = new Document(pdf))
{
doc.Add(new Paragraph("Hello World!"));
doc.Flush();
pdfBytes = stream.ToArray();
}
return new FileContentResult(pdfBytes, "application/pdf");
}

How do I deserialize an a list of objects from a Memory Stream through WCF

MVC 4.0
I have the following running on a service:
[OperationContract(Name = "GetHierarchyReportContents")]
[FaultContract(typeof(InvalidHierarchyNameException))]
[ServiceKnownType(typeof(Node))]
MemoryStream GetContents();
This function provides a memory stream which contains a list of Node (APINode because of an alias). Essentially, all it does is the following:
BinaryFormatter formatter = new BinaryFormatter();
MemoryStream stream = new MemoryStream();
formatter.Serialize(stream, data.ToList<APINode>());
stream.Seek(0, SeekOrigin.Begin);
return stream;
The following is the definition of Node, which is defined in a namespace to prevent conflict with another node.
[DataContract (Name="Node",Namespace="API")]
[Serializable]
public class Node
{
public Node()
{
}
[DataMember]
public string Name { get; private set; }
}
On my client app, I do the following:
BinaryFormatter bf = new BinaryFormatter();
List<Node> nodes = (List<Node>) bf.Deserialize(client.GetContents());
I am getting the error that says:
Unable to find assembly 'API, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=null'.
I am using a wsHttpBinding for the client connection.
I must be missing something, perhaps the namespace screws something up. Any ideas?
If the version of the .NET runtime on your client is any different from that which is on your server, binary serialization will likely fail. I would recommend using DataContractSerializer and writing as binary using XmlDictionaryWriter:
var stream = new MemoryStream();
var writer = XmlDictionaryWriter.CreateBinaryWriter(stream);
var serializer = new DataContractSerializer(List<APINode>);
serializer.WriteObject(writer, data.ToList<APINode>());
writer.Flush();
stream.Position = 0;
return stream;
on the client side:
using (var reader = XmlDictionaryReader.CreateBinaryReader(client.GetContents(), XmlDictionaryReaderQuotas.Max))
{
var serializer = new DataContractSerializer(List<Node>);
return (List<Node>)serializer.ReadObject(reader, true);
}

Serializing and Unserializing

I have serialised an object using http://www.codeproject.com/Articles/10429/Convert-XML-data-to-object-and-back-using-serializ as a basis for advice and got the XML. I stored the XML in a text field in a 2008 database. When I deserialize it, I get InvalidOperationException. Any had experience of deserialising an object and finding out its badly serialized in the first place?
public static Request ToObject(string xml)
{
StringReader stream = null;
XmlTextReader reader = null;
try
{
// serialise to object
XmlSerializer serializer = new XmlSerializer(typeof(Request));
stream = new StringReader(xml); // read xml data
reader = new XmlTextReader(stream); // create reader
// covert reader to object
return (Request)serializer.Deserialize(reader);
}
catch
{
return null;
}
finally
{
if (stream != null) stream.Close();
if (reader != null) reader.Close();
}
}
public static string ToXML(Request oRequest)
{
MemoryStream stream = null;
TextWriter writer = null;
try
{
stream = new MemoryStream(); // read xml in memory
writer = new StreamWriter(stream, Encoding.Unicode);
// get serialise object
XmlSerializer serializer = new XmlSerializer(typeof(Request));
serializer.Serialize(writer, oRequest); // read object
int count = (int)stream.Length; // saves object in memory stream
byte[] arr = new byte[count];
stream.Seek(0, SeekOrigin.Begin);
// copy stream contents in byte array
stream.Read(arr, 0, count);
UnicodeEncoding utf = new UnicodeEncoding(); // convert byte array to string
return utf.GetString(arr).Trim();
}
catch
{
return string.Empty;
}
finally
{
if (stream != null) stream.Close();
if (writer != null) writer.Close();
}
}
This should answer your question.
In short, you are using Unicode to serialize, but not deserialize.
So your fix is - In the ToObject Method, change:
MemoryStream stream;
stream = new MemoryStream(Encoding.Unicode.GetBytes(xml));

Storing binary objects in SQL Server with LINQ

I'm trying to do the same thing as in this question, but am having problems.
Can you share with me how you prepared your objects prior to inserting and updating the database?
I have a List<myObject> that I want to store as a VarBinary(max) in SQL Server 2008.
You will need to convert your List<object> to a byte[]. You don't need Linq specifically but I assume you are using Linq To Sql? Before storing your object in the property that should contain the binary you need to convert it to a byte[]. Here is some example code to do what you need (Source Link):
// Convert an object to a byte array
private byte[] ObjectToByteArray(Object obj)
{
if(obj == null)
return null;
BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
bf.Serialize(ms, obj);
return ms.ToArray();
}
// Convert a byte array to an Object
private Object ByteArrayToObject(byte[] arrBytes)
{
MemoryStream memStream = new MemoryStream();
BinaryFormatter binForm = new BinaryFormatter();
memStream.Write(arrBytes, 0, arrBytes.Length);
memStream.Seek(0, SeekOrigin.Begin);
Object obj = (Object) binForm.Deserialize(memStream);
return obj;
}

Resources