Serializing XML Document through application domains - xml-serialization

I'm trying to serialize an XML file between two software components, with a client-server fashioned code.
First of all, i'll show how i solved the same issue for Bitmaps (code has been simplified for writting this):
Initially, this code serializes me Bitmaps at the server side:
public String ImageToString(Bitmap img)
{
byte[] byteArray = new byte[0];
using (MemoryStream stream = new MemoryStream())
{
img.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
stream.Close();
byteArray = stream.ToArray();
}
return Convert.ToBase64String(byteArray);
}
And this deserializes the Bitmap at the client side:
public Bitmap StringToImage(string imageString)
{
byte[] array = Convert.FromBase64String(imageString);
Bitmap image = (Bitmap)Bitmap.FromStream(new MemoryStream(array));
return image;
}
What i really want to do now is do the same, but with XML files. I have at the server side:
public XmlDocument RemoteXMLfile()
{
XmlDocument doc = new XmlDocument();
doc.Load("myXMLFile.xml");
return doc;
}
But this makes the compiler to complain because it finds the XML document unmarked as serializable.
My question is: how do i solve this? Thanks!

I answer my own question:
The XMLDocuments is loaded and converted to a byte array at the server side:
public byte[] RemoteXMLfile()
{
XmlDocument doc = new XmlDocument();
doc.Load("myLocalXMLfile.xml");
byte[] byteArray = new byte[0];
using (MemoryStream stream = new MemoryStream())
{
doc.Save(stream);
stream.Close();
byteArray = stream.ToArray();
}
return byteArray;
}
And at the client side, we convert again to an XML document from its byte array shape:
byte[] docbytearray = RemoteXMLfile();
XmlDocument doc = new XmlDocument();
MemoryStream ms = new MemoryStream(docbytearray);
doc.Load(ms);

Related

How do you convert an RTF file to a PDF file using iTextSharp

I have searched and I could not find an answer. For example, this doesn't work. My port:
static byte[] RtfToPdf(string rtf)
{
byte[] pdf = null;
using (var inputStream = GenerateStreamFromString(rtf))
using (var outputStream = new MemoryStream())
{
var pdfDocument = new iTextSharpDocument();
var pdfWriter = PdfWriter.GetInstance(pdfDocument, outputStream);
pdfDocument.Open();
RtfParser rtfParser = new RtfParser(null);
rtfParser.ConvertRtfDocument(inputStream, pdfDocument);
pdfDocument.Close();
pdfWriter.Close();
pdf = outputStream.ToArray();
}
return pdf;
}
public static MemoryStream GenerateStreamFromString(string value)
{
return new MemoryStream(Encoding.UTF8.GetBytes(value));
}
That simply copies the text of the RTF to a PDF without any of the formatting that was in the RTF. I am using iTextSharp-LGPL which is version 4.1.6 of iTextSharp.
I personally can't find any useful documentation. iText itself isn't intuitive so I'm having a hard time even guessing about what to try.

How to convert an array of stream in Contents to PRIndirectRefernce?

I am trying to read pdf and get the text present in it. Using Nugget iTextSharp -LGPL v4.1.5 . (I am not allowed to use ITextsharp v5.5.13 and it makes life difficult)
private string GetTextFromPage(PdfReader pdfReader, int page)
{
StringBuilder pageText = new StringBuilder();
var cpage = pdfReader.GetPageN(page);
var content = cpage.Get(PdfName.CONTENTS);
//Error for casting Pdfarray to PRIndirectReference
var indirectReference = (PRIndirectReference)content;
}
Getting Exception
System.InvalidCastException : Unable to cast object of type 'iTextSharp.text.pdf.PdfArray' to type 'iTextSharp.text.pdf.PRIndirectReference'.
Kindly suggest how to handle PdfArray object (multiple streams in contents)
I am not too versed in c# but the java code should be easily transferable to c#
I would do it like this:
private byte[] getTextFromPage(PdfReader pdfReader, int page){
PdfDictionary cpage = pdfReader.GetPageN(page);
PdfObject content = cpage.get(PdfName.CONTENTS);
return getContent(content);
}
private byte[] getContent(PdfObject content) throws IOException {
byte[] result=null;
switch (content.type()){
case PdfObject.INDIRECT:
PRIndirectReference ref = (PRIndirectReference) content;
PdfObject directObject = PdfReader.getPdfObject(ref);
result = getContent(directObject);
break;
case PdfObject.ARRAY:
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PdfArray cArray = (PdfArray) content;
for(Object object : cArray.getArrayList()) {
baos.write(getContent((PdfObject) object));
}
result = baos.toByteArray();
break;
case PdfObject.STREAM:
PRStream stream = (PRStream) PdfReader.getPdfObject(content);
result = PdfReader.getStreamBytes(stream);
break;
default:
throw new IllegalStateException("Unsupported content type");
}
return result;
}
But this is only a small step in retrieving the text. You need the whole operator processing, leading, spacing, scaling, font handling etc. So to completely write it from scratch is a big task...

iTextSharp - Create new document as Byte[]

Have a little method which goes to the database and retrieves a pdf document from a varbinary column and then adds data to it. I would like to add code so that if this document (company stationery ) is not found then a new blank document is created and returned. The method could either return a Byte[] or a Stream.
Problem is that the variable "bytes" in the else clause is null.
Any ideas what's wrong?
private Byte[] GetBasePDF(Int32 AttachmentID)
{
Byte[] bytes = null;
DataTable dt = ServiceFactory
.GetService().Attachments_Get(AttachmentID, null, null);
if (dt != null && dt.Rows.Count > 0)
{
bytes = (Byte[])dt.Rows[0]["Data"];
}
else
{
// Create a new blank PDF document and return it as Byte[]
ITST.Document doc =
new ITST.Document(ITST.PageSize.A4, 50f, 50f, 25f, 25f);
MemoryStream ms = new MemoryStream();
PdfCopy copy = new PdfCopy(doc, ms);
ms.Position = 0;
bytes = ms.ToArray();
}
return bytes;
}
You are trying to use PdfCopy but that's intended for existing documents, not new ones. You just need to create a "blank" document using PdfWriter and Document. iText won't let you create a 100% empty document but the code below essentially does that by just adding a space.
private static Byte[] CreateEmptyDocument() {
using (var ms = new System.IO.MemoryStream()) {
using (var doc = new Document()) {
using (var writer = PdfWriter.GetInstance(doc, ms)) {
doc.Open();
doc.Add(new Paragraph(" "));
doc.Close();
}
}
return ms.ToArray();
}
}
I think you may need to use
bytes = ms.GetBuffer();
not
bytes = ms.ToArray();

want to store images to gridfs from a given URL

Is it possible to store images to mongo GridFS directly form URL, which I get from API? or I have to store it locally and then insert it into mongo?
I tried to insert directly from URL, but C# driver gave me an error that URI is not supported..
The MongoGridFS class implements .NET's stream API so you should be able to use a MemoryStream to save the web response and insert into GridFS.
try
{
var server = MongoServer.Create("mongodb://192.168.1.8:27017/imgdb?safe=true");
var db = server.GetDatabase("imgdb");
string fileName = "logo-mongodb.png";
// Get image from URL or API
WebRequest req = WebRequest.Create("http://media.mongodb.org/" + fileName);
WebResponse response = req.GetResponse();
Console.WriteLine("Response length is " + response.ContentLength + " bytes");
// Copy from WebResponse to MemoryStream
MemoryStream memStream;
using (Stream responseStream = response.GetResponseStream())
{
memStream = new MemoryStream();
byte[] buffer = new byte[1024];
int byteCount;
do
{
byteCount = responseStream.Read(buffer, 0, buffer.Length);
memStream.Write(buffer, 0, byteCount);
} while (byteCount > 0);
responseStream.Close();
}
// Reset to beginning of stream
memStream.Seek(0, SeekOrigin.Begin);
// Save to GridFS
var gridFsInfo = db.GridFS.Upload(memStream, fileName);
// Success!
Console.WriteLine("Success!");
}
catch (Exception err)
{
Console.WriteLine("Something went wrong: "+err.Message);
}

upload image to Database by using WCF Restful service

I am using WCF restful service to upload image to my databse
Code:
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "AddDealImage/{id}")]
long AddDealImage(string id, Stream image);
public long AddDealImage(string id, Stream image)
{
//add convert Stram to byte[]
byte[] buffer = UploadFile.StreamToByte(image);
//create image record for database
Img img = ImgService.NewImage(DateTime.Now.ToFileTime().ToString(), "", buffer, "image/png");
ImgService.AddImage(img);
//return image id
return img.ImageId;
}
public static byte[] StreamToByte(Stream stream)
{
byte[] buffer = new byte[16 * 1024];
using (MemoryStream ms = new MemoryStream())
{
int read;
while ((read = stream.Read(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, read);
}
return ms.ToArray();
}
}
Problem:
When i upload my photo via iPhone the POST was Successful. New image id is returned, and I can see the new record created in the database.
However when I try to convert binary from DB record to Image Stream: I got error:
"No imaging component suitable to complete this operation was found."
it seems that the MemoryStream is corrupted.
//photoBytes from database
MemoryStream photoStream = new MemoryStream(photoBytes)
//Error happened here
var photoDecoder = BitmapDecoder.Create(
photoStream,
BitmapCreateOptions.PreservePixelFormat,
BitmapCacheOption.None);
Plus, the error only happens when image is uploaded via WCF Restful service.
It works perfectly if the image is uploaded via web form.
Question:
Where did i do wrong or missed?
how can i write a test client to test this upload api?
many thanks
the code above actually works.
the part I missed is the transferModel you need to set it to "Streamed" in web.config
Code for testing:
static void Main()
{
string filePath = #"C:\Users\Dizzy\Desktop\600.png";
string url = "http://localhost:13228/ApiRestful.svc/AddDealImage/96";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Accept = "text/xml";
request.Method = "POST";
using (Stream fileStream = File.OpenRead(filePath))
using (Stream requestStream = request.GetRequestStream())
{
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
int byteCount = 0;
while ((byteCount = fileStream.Read(buffer, 0, bufferSize)) > 0)
{
requestStream.Write(buffer, 0, byteCount);
}
}
string result;
using (WebResponse response = request.GetResponse())
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
result = reader.ReadToEnd();
}
Console.WriteLine(result);
}