Upload BASE64 binary file to SharePoint document library - sharepoint

I have been looking for ways to upload BASE64 binary files days and I am stuck.
First of all a do not know how to convert BASE64 binary file to array buffer, blob, ... Everything is about BASE64 string but I have BASE64 binary file.
Do you have any solution?

You need to convert this Base64 string to byte array. C# Programming provide several approaches to do this without trouble. Following Upload large files sample SharePoint Add-in and Convert.FromBase64String(String) Method, both at Microsoft Docs, the final code that meet your requirements will be like this:
//This approach is useful for short files, less than 2Mb:
public void UploadFileContentFromBase64(ClientContext ctx, string libraryName, string fileName, string base64Str)
{
Web web = ctx.Web;
// Ensure that target library exists. Create if it is missing.
if (!LibraryExists(ctx, web, libraryName))
{
CreateLibrary(ctx, web, libraryName);
}
FileCreationInformation newFile = new FileCreationInformation();
// The next line of code causes an exception to be thrown for files larger than 2 MB.
newFile.Content = Convert.FromBase64String(base64Str);
newFile.Url = fileName;
// Get instances to the given library.
List docs = web.Lists.GetByTitle(libraryName);
// Add file to the library.
Microsoft.SharePoint.Client.File uploadFile = docs.RootFolder.Files.Add(newFile);
ctx.Load(uploadFile);
ctx.ExecuteQuery();
}
//This other approach provides you to Upload large files, more than 2Mb:
public void UploadDocumentContentStreamFromBase64(ClientContext ctx, string libraryName, string fileName, string base64Str)
{
Web web = ctx.Web;
// Ensure that the target library exists. Create it if it is missing.
if (!LibraryExists(ctx, web, libraryName))
{
CreateLibrary(ctx, web, libraryName);
}
byte[] fileContent = Convert.FromBase64String(base64Str);
using (MemoryStream memStream = new MemoryStream(fileContent))
{
FileCreationInformation flciNewFile = new FileCreationInformation();
// This is the key difference for the first case - using ContentStream property
flciNewFile.ContentStream = memStream;
flciNewFile.Url = fileName;
flciNewFile.Overwrite = true;
List docs = web.Lists.GetByTitle(libraryName);
Microsoft.SharePoint.Client.File uploadFile = docs.RootFolder.Files.Add(flciNewFile);
ctx.Load(uploadFile);
ctx.ExecuteQuery();
}
}

Related

Best way to export CSV string through JSON via WebAPI?

Have been stringbuilding CSV files for ages on MVC applications just fine, until now.
One mistake made me generate a CSV string bigger then the system can handle in memory, so i have been searching the web for any solution on minifing a string that could be reconstructed back on client.
So far i have been doing this:
StringBUilder sb = new StringBuilder();
foreach(stuff in manyEnumerableStuff)
sb.Append(stuff);
return csv.ToString().ToBase64();
public static string ToBase64(this string value) => Convert.ToBase64String(Encoding.Default.GetBytes(value));
The application can handle .ToString() in this HUGE case just "fine", but it fails without creating excpetions at .ToBase64String(Encoding.Default.GetBytes(value));
This only happens on huge strings because from what i know, base64 will make the string 33% bigger.
Compressed json can't solve this problem, since this happens on server side.
So I have gonne on search to minify or compress this string, but it still need to be a string and can be converted on client site Angular application.
I have found this:
public static string compress(this string big) {
var bytes = Encoding.Default.GetBytes(big);
using (var msi = new MemoryStream(bytes))
using (var mso = new MemoryStream()) {
using (var gs = new GZipStream(mso, CompressionMode.Compress)) {
//msi.CopyTo(gs);
CopyTo(msi, gs);
}
return mso.ToArray().ToString();
}
}
private static void CopyTo(Stream src, Stream dest) {
byte[] bytes = new byte[4096];
int cnt;
while ((cnt = src.Read(bytes, 0, bytes.Length)) != 0) {
dest.Write(bytes, 0, cnt);
}
}
but I think there is no sense at all, because i can't put byte[] on json value as string without converting it back.
Is it possible to compress plain Pipe separated values that represents a .CSV file after getting the string from StringBuilder()?
I have tried GC.collect() right after parsing SB to string but still broke the application.
I'm on .Net Core 2.1, Linux server.

c# Ftpclient not working and python can retrive the data

I'm trying to use the c# library to download a file from an FTP. The code we are using is straight forward.
static void Main(string[] args)
{
Connect(true, true, true);
}
private static void Connect(bool keepAlive, bool useBinary, bool usePassive)
{
string RemoteFtpPath = "ftp://ftp.xxxx.ac.uk/incoming/testExtractCSVcoursesContacts.csv";
const string Username = "anonymous";
const string Password = "anonymous#xxxx.ac.uk";
var request = (FtpWebRequest)WebRequest.Create(new Uri(RemoteFtpPath));
request.Method = WebRequestMethods.Ftp.DownloadFile;
request.KeepAlive = keepAlive;
request.UsePassive = usePassive;
request.UseBinary = useBinary;
request.Credentials = new NetworkCredential(Username, Password);
request.Timeout = 30000;
try
{
var response = (FtpWebResponse)request.GetResponse();
var responseStream = response.GetResponseStream();
var reader = new StreamReader(responseStream);
var fileString = reader.ReadToEnd();
Console.WriteLine(
$"Success! keepAlive={keepAlive}, useBinary={useBinary}, usePassive={usePassive} Length={fileString.Length}");
reader.Close();
response.Close();
}
catch (Exception e)
{
Console.WriteLine(
$"Failed! keepAlive={keepAlive}, useBinary={useBinary}, usePassive={usePassive}, message={e.Message}");
}
}
`
we also tried to set passive = true with identical results.
When we run it, using wireshark we are getting : Wireshark log c#
Now we tried the same with Python and it's working just fine:
import urllib.request
data = urllib.request.urlretrieve('path')
print(data)
the wireshark log looks quite different:
So tried different things, but not able to sort this out.
Some ftp servers don't support OPTS UTF8 but still transmit file names in UTF8. (Note that 'OPTs UTF8' is NOT required by the FTP Internationalization Standard, although supporting UTF8 file names is.) The .NET Ftp classes will use the default code page if they don't get an OK response to OPTS UTF8... It's unfortunate that MS didn't provide some way to use UTF8 anyway, since this leaves you unable to transmit international file names to and from otherwise UTF8-compliant servers.
The issue is sorted after using a different library as FtpWebRequest doesn't support it

Downloading bulk files from sharepoint library

I want to download the files from a sharepoint document library through code as there are thousand of files in the document library.
I am thinking of creating console application, which I will run on sharepoint server and download files. Is this approach correct or, there is some other efficient way to do this.
Any help with code will be highly appreciated.
Like SigarDave said, it's perfectly possible to achieve this without writing a single line of code. But if you really want to code the solution for this, it's something like:
static void Main(string[] args)
{
// Change to the URL of your site
using (var site = new SPSite("http://MySite"))
using (var web = site.OpenWeb())
{
var list = web.Lists["MyDocumentLibrary"]; // Get the library
foreach (SPListItem item in list.Items)
{
if (item.File != null)
{
// Concat strings to get the absolute URL
// to pass to an WebClient object.
var fileUrl = string.Format("{0}/{1}", site.Url, item.File.Url);
var result = DownloadFile(fileUrl, "C:\\FilesFromMyLibrary\\", item.File.Name);
Console.WriteLine(result ? "Downloaded \"{0}\"" : "Error on \"{0}\"", item.File.Name);
}
}
}
Console.ReadKey();
}
private static bool DownloadFile(string url, string dest, string fileName)
{
var client = new WebClient();
// Change the credentials to the user that has the necessary permissions on the
// library
client.Credentials = new NetworkCredential("Username", "Password", "Domain");
var bytes = client.DownloadData(url);
try
{
using (var file = File.Create(dest + fileName))
{
file.Write(bytes, 0, bytes.Length); // Write file to disk
return true;
}
}
catch (Exception)
{
return false;
}
}
another way without using any scripts is by opening the document library using IE then in the ribbon you can click on Open in File Explorer where you can then drag and drop the files right on your desktop!

Retrieve Image from Picture Library - REST

I am looking for some suggestion or sample around retrieving images (actual file, not URL), from a picture library using REST API.
Thanks for any input.
Task 1: Getting a List of Image libs on a given site
public static XmlNode GetPicLibListingXML(string imagingServiceURL)
{
Imaging wsImaging = new Imaging();
wsImaging.UseDefaultCredentials = true;
wsImaging.Url = imagingServiceURL;
XmlNode xnPicLibs = wsImaging.ListPictureLibrary();
return xnPicLibs;
}
Sample return XML:
<Library name="{3C1D52F5-5387-490A-9A2D-A9C99A208C00}" title="Tech Images" guid="3c1d52f5-5387-490a-9a2d-a9c99a208c00" url="Tech Images" xmlns="http://schemas.microsoft.com/sharepoint/soap/ois/" />
Task 2: Listing Images in a given library
public static XmlNode GetImageFileListing(string imagingServiceURL, string imageFileLibraryName)
{
Imaging wsImaging = new Imaging();
ImageInfo curImageInfo = new ImageInfo();
wsImaging.UseDefaultCredentials = true;
wsImaging.Url = imagingServiceURL;
XmlNode xnListItems = wsImaging.GetListItems(imageFileLibraryName, "");
return xnListItems;
}
Task 3: Download Image(s)
private const string ATTR_FILENAME = "name";
private const string FILENAMESPACEURI = "http://schemas.microsoft.com/sharepoint/soap/ois/";
public static bool DownloadImageFiles(string imagingServiceURL, string imageFileLibraryName, string[] fileNames, string saveToFolder)
{
Imaging wsImaging = new Imaging();
wsImaging.UseDefaultCredentials = true;
wsImaging.Url = imagingServiceURL;
XmlElement parent = (XmlElement)wsImaging.Download(imageFileLibraryName, string.Empty, fileNames, 0, true);
XmlNodeList files = parent.GetElementsByTagName("File", FILENAMESPACEURI);
foreach (XmlNode file in files)
{
if (Directory.Exists(saveToFolder) == false)
{
Directory.CreateDirectory(saveToFolder);
}
byte[] fileBytes = Convert.FromBase64String(file.InnerText);
using (FileStream fs = File.OpenWrite(saveToFolder + file.Attributes[ATTR_FILENAME].Value))
{
BinaryWriter writer = new BinaryWriter(fs);
writer.Write(fileBytes);
writer.Close();
}
}
return true;
}
Note:
Imaging() class is a web reference to imagining.asmx
The Download call natively returns XML so yo uneed to run it through a conversion to byte
If you need to get a reference on the Imagine web service check this on out on MSDN:
http://msdn.microsoft.com/en-us/library/imaging.imaging.aspx
source:
http://gourangaland.wordpress.com/2008/05/30/using-the-moss-imaging-web-service-to-download-imagesimaging-asmx/

How to zip and unzip folders and its sub folders in Silverlight?

I have a Windows Phone application. I am using SharpZipLib to zip folders and its sub folders. This is zipping only the folder but the data inside the folders is not getting zipped. Can anyone guide me how to do this?
My code:
private void btnZip_Click(object sender, RoutedEventArgs e)
{
using (IsolatedStorageFile appStore = IsolatedStorageFile.GetUserStoreForApplication())
{
foreach (string filename in appStore.GetFileNames(directoryName + "/" + "*.txt"))
{
GetCompressedByteArray(filename);
}
textBlock2.Text = "Created file has Zipped Successfully";
}
}
public byte[] GetCompressedByteArray(string content)
{
byte[] compressedResult;
using (MemoryStream zippedMemoryStream = new MemoryStream())
{
using (ZipOutputStream zipOutputStream = new ZipOutputStream(zippedMemoryStream))
{
zipOutputStream.SetLevel(9);
byte[] buffer;
using (MemoryStream file = new MemoryStream(Encoding.UTF8.GetBytes(content)))
{
buffer = new byte[file.Length];
file.Read(buffer, 0, buffer.Length);
}
ZipEntry entry = new ZipEntry(content);
zipOutputStream.PutNextEntry(entry);
zipOutputStream.Write(buffer, 0, buffer.Length);
zipOutputStream.Finish();
}
compressedResult = zippedMemoryStream.ToArray();
}
WriteToIsolatedStorage(compressedResult);
return compressedResult;
}
public void WriteToIsolatedStorage(byte[] compressedBytes)
{
IsolatedStorageFile appStore = IsolatedStorageFile.GetUserStoreForApplication();
appStore.CreateDirectory(ZipFolder);
using (IsolatedStorageFileStream zipTemplateStream = new IsolatedStorageFileStream(ZipFolder+"/"+directoryName + ".zip", FileMode.OpenOrCreate, appStore))
using (BinaryWriter streamWriter = new BinaryWriter(zipTemplateStream))
{
streamWriter.Write(compressedBytes);
}
}
I think you'll find this guide helpful.
An excerpt from the above link
The ZipFile object provides a method called AddDirectory() that
accepts a parameter directoryName. The problem with this method is
that it doesn't add the files inside the specified directory but
instead just creates a directory inside the zip file. To make this
work, you need to get the files inside that directory by looping thru
all objects in that directory and adding them one at a time. I was
able to accomplish this task by creating a recursive function that
drills through the whole directory structure of the folder you want to
zip. Below is a snippet of the function.
I guess you too are facing the same problem where the folder is added to the zip file, but the contents and sub folders are not zipped.
Hope this helps.
Have a look over here for a code sample on how to use SharpZipLib to zip a root folder including nested folders.

Resources