I upload doc,xls files but i dont understand how upload html files. This code upload file but dont preview file. Its say- "We apologize Preview not available". Whats mime type i must set ?
if (extension == ".htm" || extension == ".html")
{
File body = new File();
body.Title = Path.GetFileNameWithoutExtension(item);
//body.Description = "A test document";
body.MimeType = "text/HTML";
byte[] byteArray = System.IO.File.ReadAllBytes(item);
System.IO.MemoryStream stream = new System.IO.MemoryStream(byteArray);
FilesResource.InsertMediaUpload request = service.Files.Insert(body, stream,
"application/vnd.google-apps.file");
request.Convert = true;
I had some problems uploading files using the Gmail API. I don't know if the Files API works the same but, you could try encoding the byteArray before you call the Insert method. Implement these methods:
protected static string Base64ForUrlEncode(string str)
{
StringBuilder result = new StringBuilder(Convert.ToBase64String(Encoding.ASCII.GetBytes(str)).TrimEnd('='));
result.Replace('+', '-');
result.Replace('/', '_');
return result.ToString();
}
protected static byte[] GetBytes(string str)
{
byte[] bytes = new byte[str.Length * sizeof(char)];
System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
return bytes;
}
Then, call it before the Insert method:
byte[] byteArray = System.IO.File.ReadAllBytes(item);
string base64 = Base64ForUrlEncode(System.Text.Encoding.UTF8.GetString(byteArray));
System.IO.MemoryStream stream = new System.IO.MemoryStream(GetBytes(base64));
FilesResource.InsertMediaUpload request = service.Files.Insert(body, stream, "application/vnd.google-apps.file");
You could also try to set the mime type to "text/html", in lowercase letters.
Related
I am trying to create a web service that returns a pdf file as a byte[] and then the app that consumes it grabs the byte[] and saves it as a pdf file and then opens it. The file fails to open at the end.
Here is the Web Service that returns a byte[]
[WebMethod]
public byte[] XXXX(int fileID)
{
try
{
using (EntitiesModel dbContext = new EntitiesModel())
{
string fileFullPath = .....
.......
if (fileFullNamePath != null)
{
FileStream fileStream = new FileStream(fileFullNamePath, FileMode.Open, System.IO.FileAccess.Read);
int len = fileStream.Length.ToInt();
Byte[] documentContents = new byte[len];
fileStream.Read(documentContents, 0, len);
fileStream.Close();
return documentContents;
Then it is called from an app with the following code
string soap = "<?xml version=\"1.0\" encoding=\"utf - 8\"?>" +
"<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
"<soap:Body>" +
"<XXXX xmlns=\"http://tempuri.org/\">" +
"<fileID>XXXXX</fileID>" +
"</XXXX>" +
"</soap:Body>" +
"</soap:Envelope>";
string localhostContext = #"http://localhost:3381/";
string webserviceAddress = #"XXXX/XXXX/XXXXX.asmx";
string url = localhostContext + webserviceAddress ;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.ContentType = "text/xml";
request.ContentLength = soap.Length;
request.Timeout = 20000;
request.Method = "POST";
using (Stream stream = request.GetRequestStream())
{
using (StreamWriter streamWriter = new StreamWriter(stream))
{
streamWriter.Write(soap); }
}
}
byte[] bytes;
try
{
WebResponse response = request.GetResponse();
bytes = ReadFully(response.GetResponseStream());
}
catch (Exception exception)
{
throw;
}
private byte[] ReadFully(Stream input)
{
byte[] buffer = new byte[16*1024];
using (MemoryStream memoryStream = new MemoryStream())
{
int read;
while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
{
memoryStream.Position = 0;
memoryStream.Write(buffer, 0, read);
}
return memoryStream.ToArray();
}
}
FileStream objfilestream =
new FileStream(fileName, FileMode.Create,FileAccess.ReadWrite);
objfilestream.Write(bytes, 0, bytes.Length);
objfilestream.Close();
var process = Process.Start(fileName);
The code runs fine and creates a pdf and then tries to open that pdf. But the file can not be opened. Adobe Acrobat gives the error
Adobe Acrobat Reader could not open XXX.pdf because it is either not a
supported file type or because the file has been damaged (for example, it
was sent as an email attachment and wasn't correctly decoded).
Because I am not getting an error in the code I am at a loss to know where the error is that is not creating the proper file.
There was an issue with the Stream variable called input was not giving length so I used Jon Skeet's suggestion here Stackoverflow:Creating a byte array from a stream
new byte[16*1024];
rather than
new byte[input.length]
There were three things wrong.
memoryStream.Position = 0;
in the while loop was problematic so I removed it.
Secondly when reading the stream. What it returned was the SOAP XMl message with the encoded base64 string in the the XXXXResult XML tag. So I had to extract that.
Finally I had to use
byte[] fileResultBytes = Convert.FromBase64String(resultString);
to get the byte[] from the resultString extracted from the SOAP message. In the test SOAP message, that can be generated locally, it tells you the type of this result string. I missed that initially.
Thanks to VC.One and CodeCaster for their correct suggestions.
i am sending an image in byte[] and 3 strings to a webservice usingksoap but its not working for me , i am not sure where i am wrong, in sending image from Android and at receiving end, i am putting the code here kindly check it
Here is how i am converting image to byte[] at client (Android) side
Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
myBitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream);
byte[] byteArray = byteArrayOutputStream .toByteArray();
String encoded = Base64.encodeToString(byteArray, Base64.DEFAULT);
and here is the code where i am sending it to webservice via Ksoap
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
request.addProperty("Name", name);
request.addProperty("Email", email);
request.addProperty("Picture", encoded );
request.addProperty("Date", date);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(request);
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
androidHttpTransport. call(SOAP_ACTION, envelope);
SoapPrimitive result = (SoapPrimitive) envelope.getResponse();
String str = result.toString();
and here is the webMethod where i am receiving this soap envelop
[WebMethod]
public String PutFile(String Name, String Email, String Picture, String Date)
{
String PictureByteString = Picture;
Image imgFromString = SaveByteArrayAsImage(PictureByteString);
DateTime.Now.ToShortDateString() + ".jpg"));
string serverpath = Server.MapPath("~/" + Email + "-" + DateTime.Now.ToShortDateString());
imgFromString.Save(serverpath, System.Drawing.Imaging.ImageFormat.Jpeg);
String Path = serverpath + ".Jpeg";
return Name;
}
private Image SaveByteArrayAsImage(string base64String)
{
byte[] bytes = Convert.FromBase64String(base64String);
image;
using (MemoryStream ms = new MemoryStream(bytes))
{
image = Image.FromStream(ms);
}
return image;
}
when i send data to webservice android LogCat shows me
java.io.IOException: HTTP request failed, HTTP status: 500
i think so which means that the data i am sending to webservice is not of correct type, so i tried to make String Picture to byte[] Picture in webmethod but result was same. I am not being able to figure out where i am wrong ...
Update:
now sending image in a Base64 string and java exception is gone but the webmethod is still not converting that Base64 string into image...
This is how i did it.
parameter passed to function is Base64 string
public string SendImage(string data)
{
byte[] myarray = Convert.FromBase64String(data);
MemoryStream memStream = new MemoryStream(myarray);
Image myimage = Image.FromStream(memStream);
myimage.Save("G:\\image.png", ImageFormat.Png);
return "succeeded";
}
This is working perfectly for me, Hope it helps.
Sorry for the long post, will try to make this as short as possible.
I'm consuming a json API (which has zero documentation of course) which returns something like this:
{
uncompressedlength: 743637,
compressedlength: 234532,
compresseddata: "lkhfdsbjhfgdsfgjhsgfjgsdkjhfgj"
}
The data (xml in this case) is compressed and then base64 encoded data which I am attempting to extract. All I have is their demo code written in perl to decode it:
use Compress::Zlib qw(uncompress);
use MIME::Base64 qw(decode_base64);
my $uncompresseddata = uncompress(decode_base64($compresseddata));
Seems simple enough.
I've tried a number of methods to decode the base64:
private string DecodeFromBase64(string encodedData)
{
byte[] encodedDataAsBytes = System.Convert.FromBase64String(encodedData);
string returnValue = System.Text.Encoding.Unicode.GetString(encodedDataAsBytes);
return returnValue;
}
public string base64Decode(string data)
{
try
{
System.Text.UTF8Encoding encoder = new System.Text.UTF8Encoding();
System.Text.Decoder utf8Decode = encoder.GetDecoder();
byte[] todecode_byte = Convert.FromBase64String(data);
int charCount = utf8Decode.GetCharCount(todecode_byte, 0, todecode_byte.Length);
char[] decoded_char = new char[charCount];
utf8Decode.GetChars(todecode_byte, 0, todecode_byte.Length, decoded_char, 0);
string result = new String(decoded_char);
return result;
}
catch (Exception e)
{
throw new Exception("Error in base64Decode" + e.Message);
}
}
And I have tried using Ionic.Zip.dll (DotNetZip?) and zlib.net to inflate the Zlib compression. But everything errors out. I am trying to track down where the problem is coming from. Is it the base64 decode or the Inflate?
I always get an error when inflating using zlib: I get a bad Magic Number error using zlib.net and I get "Bad state (invalid stored block lengths)" when using DotNetZip:
string decoded = DecodeFromBase64(compresseddata);
string decompressed = UnZipStr(GetBytes(decoded));
public static string UnZipStr(byte[] input)
{
using (MemoryStream inputStream = new MemoryStream(input))
{
using (Ionic.Zlib.DeflateStream zip =
new Ionic.Zlib.DeflateStream(inputStream, Ionic.Zlib.CompressionMode.Decompress))
{
using (StreamReader reader =
new StreamReader(zip, System.Text.Encoding.UTF8))
{
return reader.ReadToEnd();
}
}
}
}
After reading this:
http://george.chiramattel.com/blog/2007/09/deflatestream-block-length-does-not-match.html
And listening to one of the comments. I changed the code to this:
MemoryStream memStream = new MemoryStream(Convert.FromBase64String(compresseddata));
memStream.ReadByte();
memStream.ReadByte();
DeflateStream deflate = new DeflateStream(memStream, CompressionMode.Decompress);
string doc = new StreamReader(deflate, System.Text.Encoding.UTF8).ReadToEnd();
And it's working fine.
This was the culprit:
http://george.chiramattel.com/blog/2007/09/deflatestream-block-length-does-not-match.html
With skipping the first two bytes I was able to simplify it to:
MemoryStream memStream = new MemoryStream(Convert.FromBase64String(compresseddata));
memStream.ReadByte();
memStream.ReadByte();
DeflateStream deflate = new DeflateStream(memStream, CompressionMode.Decompress);
string doc = new StreamReader(deflate, System.Text.Encoding.UTF8).ReadToEnd();
First, use System.IO.Compression.DeflateStream to re-inflate the data. You should be able to use a MemoryStream as the input stream. You can create a MemoryStream using the byte[] result of Convert.FromBase64String.
You are likely causing all kinds of trouble trying to convert the base64 result to a given encoding; use the raw data directly to Deflate.
C#'s uploadData method doesn't encode the data that is being sent. So, if I send a file over (after converting it into bytes) using this method, and the receiving side is looking for a multiform/form-data post, then it will obviously not work. Will adding a header like :
WebClient c = new WebClient();
c.Headers.Add("Content-Type", "multipart/form-data");
make it send the data encrypted as multiform, or will the data be still not encrypted (and hence unparseable by servers expecting multiform data) ?
Note that I can't use WebClient's uploadFile, as I don't have permission to get the file path location on the client side (I just have a stream, that I can convert to bytes)
Why don't you use UploadFile of WebClient over https if you want it to be secure? and that will automatically take care of adding multipart/form-data.
Example using UploadFile
http://msdn.microsoft.com/en-us/library/36s52zhs.aspx
And one more thing, encoding and encrypting are 2 different things.
Edit:
You should probably tag your question as Silverlight if you you are using WebClient in your WebClient project. Anyways, WebClient class in SL doesn't have any UploadData method. See this for more info:
http://msdn.microsoft.com/en-us/library/system.net.webclient%28v=vs.95%29.aspx
Anyways, here is the working solution to your problem:
In your button click, have this code:
OpenFileDialog dialog = new OpenFileDialog();
bool? retVal = dialog.ShowDialog();
if (retVal.HasValue && retVal == true)
{
using (Stream stream = dialog.File.OpenRead())
{
MemoryStream memoryStream = new MemoryStream();
stream.CopyTo(memoryStream);
WebClient webClient = new WebClient();
webClient.Headers["Content-type"] = "multipart/form-data; boundary=---------------------------" + _boundaryNo;
webClient.OpenWriteAsync(new Uri("http://localhost:1463/Home/File", UriKind.Absolute), "POST", new { Stream = memoryStream, FileName = dialog.File.Name });
webClient.OpenWriteCompleted += new OpenWriteCompletedEventHandler(webClient_OpenWriteCompleted);
}
}
and the event itself:
void webClient_OpenWriteCompleted(object sender, OpenWriteCompletedEventArgs e)
{
if (e.Error == null)
{
Stream responseStream = e.Result as Stream;
dynamic obj = e.UserState;
MemoryStream memoryStream = obj.Stream as MemoryStream;
string fileName = obj.FileName;
if (responseStream != null && memoryStream != null)
{
string headerTemplate = string.Format("-----------------------------{0}\r\n", _boundaryNo);
memoryStream.Position = 0;
byte[] byteArr = memoryStream.ToArray();
string data = headerTemplate + string.Format("Content-Disposition: form-data; name=\"pic\"; filename=\"{0}\"\r\nContent-Type: application/octet-stream\r\n\r\n", fileName);
byte[] header = Encoding.UTF8.GetBytes(data);
responseStream.Write(header, 0, header.Length);
responseStream.Write(byteArr, 0, byteArr.Length);
header = Encoding.UTF8.GetBytes("\r\n");
responseStream.Write(byteArr, 0, byteArr.Length);
byte[] trailer = System.Text.Encoding.UTF8.GetBytes(string.Format("-----------------------------{0}--\r\n", _boundaryNo));
responseStream.Write(trailer, 0, trailer.Length);
}
memoryStream.Close();
responseStream.Close();
}
}
where _boundaryNo is private string _boundaryNo = DateTime.Now.Ticks.ToString("x");
I had it working with Asp.Net MVC 4 and Silverlight 5.
Good luck :)
Background
I'm setting up a generic handler to:
Combine & compress Javascript and CSS files
Cache a GZip version & a Non-GZip version
Serve the appropriate version based on the request
I'm working in MonoDevelop v2.8.2 on OSX 10.7.2
Problem
Since I want to Cache the GZipped version, I need to GZip without using a response filter
Using this code, I can compress and decompress a string on the server successfully, but when I serve it to the client I get:
Error 330 (net::ERR_CONTENT_DECODING_FAILED): Unknown error. (Chrome)
Cannot decode raw data (Safari)
The page you are trying to view cannot be shown because it uses an invalid or unsupported form of compression. (Firefox)
Relevant Code
string sCompiled =null;
if(bCanGZip)
{
context.Response.AddHeader("Content-Encoding", "gzip");
bHasValue = CurrentCache.CompiledScripts.TryGetValue(context.Request.Url.ToString() + "GZIP", out sCompiled);
}
//...
//Process files if bHasVale is false
//Compress result of file concatination/minification
//Compression method
public static string CompressString(string text)
{
UTF8Encoding encoding = new UTF8Encoding(false);
byte[] buffer = encoding.GetBytes(text);
using(MemoryStream memoryStream = new MemoryStream()){
using (GZipStream gZipStream = new GZipStream(memoryStream, CompressionMode.Compress, true))
{
gZipStream.Write(buffer, 0, buffer.Length);
}
memoryStream.Position = 0;
byte[] compressedData = new byte[memoryStream.Length];
memoryStream.Read(compressedData, 0, compressedData.Length);
byte[] gZipBuffer = new byte[compressedData.Length + 4];
Buffer.BlockCopy(compressedData, 0, gZipBuffer, 4, compressedData.Length);
Buffer.BlockCopy(BitConverter.GetBytes(buffer.Length), 0, gZipBuffer, 0, 4);
return Convert.ToBase64String(gZipBuffer);
}
}
//...
//Return value
switch(Type){
case FileType.CSS:
context.Response.ContentType = "text/css";
break;
case FileType.JS:
context.Response.ContentType = "application/javascript";
break;
}
context.Response.AddHeader("Content-Length", sCompiled.Length.ToString());
context.Response.Clear();
context.Response.Write(sCompiled);
Attempts to Resolve
Since I'm not sure what the lines:
byte[] gZipBuffer = new byte[compressedData.Length + 4];
Buffer.BlockCopy(compressedData, 0, gZipBuffer, 4, compressedData.Length);
Buffer.BlockCopy(BitConverter.GetBytes(buffer.Length), 0, gZipBuffer, 0, 4);
are accomplishing, I tried removing them.
I tried playing with different Encodings/options.
At this point I'm really not sure how to attack the problem since I don't know the source of the error (Encoding/Compression/other).
Any help would be very appreciated!
Other Resources I've found on the subject
http://beta.blogs.microsoft.co.il/blogs/mneiter/archive/2009/03/24/how-to-compress-and-decompress-using-gzipstream-object.aspx
http://madskristensen.net/post/Compress-and-decompress-strings-in-C.aspx
http://www.codeproject.com/KB/files/GZipStream.aspx
http://www.codeproject.com/KB/aspnet/HttpCombine.aspx
http://webreflection.blogspot.com/2009/01/quick-tip-c-gzip-content.html
http://www.dominicpettifer.co.uk/Blog/17/gzip-compress-your-websites-html-css-script-in-code
This is one of those things where once you explain you problem, you quickly find the answer.
I need to write out the response as Binary. So modifying the compression algorithum to return a byte array:
public static byte[] CompressStringToArray(string text){
UTF8Encoding encoding = new UTF8Encoding(false);
byte[] buffer = encoding.GetBytes(text);
using(MemoryStream memoryStream = new MemoryStream()){
using (GZipStream gZipStream = new GZipStream(memoryStream, CompressionMode.Compress, true))
{
gZipStream.Write(buffer, 0, buffer.Length);
}
memoryStream.Position = 0;
byte[] compressedData = new byte[memoryStream.Length];
memoryStream.Read(compressedData, 0, compressedData.Length);
return compressedData;
}
}
and then calling:
//Writes a byte buffer without encoding the response stream
context.Response.BinaryWrite(GZipTools.CompressStringToArray(sCompiled));
Solves the issue. Hopefully this helps others who will face the same problem.