The problem is with built ASP.NET MVC solution uploaded on IIS in local network.
When I'm trying to upload file from other device than host, the target page is not loading.
When I'm trying to upload file from host is loading page without data from files.
All works fine when i'm running it in Visual Studio on my pc. The problem was made when i tried to run built solution o Windows Server.
What should I do? It is problem with IIS settings or with wrong code?
private void ReadFileFromStream(DateChoice datechoice, DateTime dateStartobj, DateTime dateEndobj, string FirstParameter_name, string SecondParameter_name, string ThirdParameter_name, string FourthParameter_name, string FivethParameter_name)
{
using (MemoryStream memoryStream = new MemoryStream())
{
datechoice.File.InputStream.CopyTo(memoryStream);
memoryStream.Seek(0, SeekOrigin.Begin);
using (var streamReader = new StreamReader(memoryStream))
{
var csvConfig = new CsvConfiguration(CultureInfo.InvariantCulture)
{
Delimiter = ";",
HasHeaderRecord = false
};
ReadCSV(dateStartobj, dateEndobj, streamReader, csvConfig, FirstParameter_name, SecondParameter_name, ThirdParameter_name, FourthParameter_name, FivethParameter_name);
}
}
}
private void ReadCSV(DateTime dateStartobj, DateTime dateEndobj, StreamReader streamReader, CsvConfiguration csvConfig, string FirstParameter_name, string SecondParameter_name, string ThirdParameter_name, string FourthParameter_name, string FivethParameter_name)
{
using (var csvReader = new CsvReader(streamReader, csvConfig))
{
var records = csvReader.GetRecords<Read>().ToList();
List<DataPoint> Parametry_A, Parametry_B, Parametry_C, Parametry_D, Parametry_E;
NewListDeclarate(out Parametry_A, out Parametry_B, out Parametry_C, out Parametry_D, out Parametry_E);
foreach (var record in records)
{
if (DateVerification(record))
{
DateTime label_date;
DataPoint dataPointA, dataPointB, dataPointC, dataPointD, dataPointE;
NewPointsGenerate(record, out label_date, out dataPointA, out dataPointB, out dataPointC, out dataPointD, out dataPointE, FirstParameter_name, SecondParameter_name, ThirdParameter_name, FourthParameter_name, FivethParameter_name);
if (UserDateCheck(dateStartobj, dateEndobj, label_date))
{
AddPointsToList(Parametry_A, Parametry_B, Parametry_C, Parametry_D, Parametry_E, dataPointA, dataPointB, dataPointC, dataPointD, dataPointE);
}
}
}
ReturnListsToViewBag(Parametry_A, Parametry_B, Parametry_C, Parametry_D, Parametry_E);
}
}
Related
I need to copy a VBA macro project from a template file into several office files. I tried using an approach similar to the one found in OpenXML SDK Inject VBA into excel workbook, and here, https://social.msdn.microsoft.com/Forums/lync/en-US/ab65277e-f0fb-4f2b-bfdc-e141abb8404f/copy-macros-document-to-another-document?forum=oxmlsdk.
However, I cannot make the following code work.
private static void cloneVbaPart(string src, string dst)
{
using (WordprocessingDocument srcDoc = WordprocessingDocument.Open(src, false))
{
var vbaPart = srcDoc.MainDocumentPart.VbaProjectPart;
using (WordprocessingDocument dstDoc = WordprocessingDocument.Open(dst, true))
{
var partsToRemove = new List<OpenXmlPart>();
foreach (var part in dstDoc.MainDocumentPart.GetPartsOfType<VbaProjectPart>()) {
partsToRemove.Add(part);
}
foreach (var part in dstDoc.MainDocumentPart.GetPartsOfType<CustomizationPart>())
{
partsToRemove.Add(part);
}
foreach (var part in partsToRemove)
{
dstDoc.MainDocumentPart.DeletePart(part);
}
var vbaProjectPart = dstDoc.MainDocumentPart.AddNewPart<VbaProjectPart>();
using (Stream data = vbaPart.GetStream())
{
vbaProjectPart.FeedData(data);
}
using (Stream data = vbaPart.VbaDataPart.GetStream())
{
vbaProjectPart.FeedData(data);
}
}
}
}
When I copy the VbaDataPart, the target file becomes unreadable by Word. If I don't, the macro project and code seem to be there, but they don't actually work.
Found the problem. I was feeding the VbaDataPart into the target's vbaProjectPart and not into its vbaDataPart.
Final code is the following:
private static void cloneVbaPart(string src, string dst)
{
using (WordprocessingDocument srcDoc = WordprocessingDocument.Open(src, false))
{
var vbaPart = srcDoc.MainDocumentPart.VbaProjectPart;
using (WordprocessingDocument dstDoc = WordprocessingDocument.Open(dst, true))
{
var partsToRemove = new List<OpenXmlPart>();
foreach (var part in dstDoc.MainDocumentPart.GetPartsOfType<VbaProjectPart>()) {
partsToRemove.Add(part);
}
foreach (var part in dstDoc.MainDocumentPart.GetPartsOfType<CustomizationPart>())
{
partsToRemove.Add(part);
}
foreach (var part in partsToRemove)
{
dstDoc.MainDocumentPart.DeletePart(part);
}
var vbaProjectPart = dstDoc.MainDocumentPart.AddNewPart<VbaProjectPart>();
var vbaDataPart = vbaProjectPart.AddNewPart<VbaDataPart>();
using (Stream data = vbaPart.GetStream())
{
vbaProjectPart.FeedData(data);
}
using (Stream data = vbaPart.VbaDataPart.GetStream())
{
vbaDataPart.FeedData(data);
}
}
}
}
I am doing a project in C# using Winforms, and I want to create a Podcast RSS reader. So I have a XmlSerializer that saves a podcast entity to a podcastlist and I should then get a podcast.xml file in my project files that it then reads ( I guess). I got it to do exactly that, but with adding Categories. But when I want to read a URL that contains a RSS-file, it wont Save(Serialize) it using the XmlReader. Ive been staring at this for most of the day and I cant just figure out whats going wrong.
Here is my serializer and saved list of Podcasts.
protected string fileOfPodcasts = #"Podcasts.xml";
public List<Podcast> listOfPodcasts = new List<Podcast>();
public void SavePodcastList(List<Podcast> podcastList)
{
XmlSerializer xmlSerializer = new XmlSerializer(podcastList.GetType());
using (FileStream outFile = new FileStream(fileOfPodcasts, FileMode.Create,
FileAccess.Write))
{
xmlSerializer.Serialize(outFile, podcastList);
}
}
public List<Podcast> ReturnPodcasts()
{
List<Podcast> listOfPodcastsToBeReturned;
XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<Podcast>));
using (FileStream inFile = new FileStream(fileOfPodcasts, FileMode.Open,
FileAccess.Read))
{
listOfPodcastsToBeReturned = (List<Podcast>)xmlSerializer.Deserialize(inFile);
}
return listOfPodcastsToBeReturned;
}
public void CreatePodcastObject ( string url, string interval, string category) // 3 parametrar
{
Podcast newPodcast = null;
{
newPodcast = new Podcast(url, interval, category);
}
podcastRepository.Create(newPodcast);
}
public void Create(Podcast entity)
{
podcastList.Add(entity);
SaveChanges();
}
I am attempting to create a Web API that can convert a styled HTML file into a PDF.
I am using TuesPechkin and have installed my application into IIS (as a 32-bit app: I have modified the application pool to run in 32bit mode).
IIS 8.5 is running on Windows Server 2012 R2.
PDFConversion class in C#:
using System.Drawing.Printing;
using System.IO;
using TuesPechkin;
namespace PDFApi
{
public class PDFcreator
{
public void convert(string path, string uri)
{
IConverter converter = new StandardConverter(
new RemotingToolset<PdfToolset>(
new Win64EmbeddedDeployment(
new TempFolderDelpoyment())));
var document = new HtmlToPdfDocument
{
GlobalSettings =
{
ProduceOutline = true,
DocumentTitle = "Converted Form",
PaperSize = PaperKind.A4,
Margins =
{
All = 1.375,
Unit = Unit.Centimeters
}
},
Objects =
{
new ObjectSettings { RawData = File.ReadAllBytes(uri) }
}
};
byte[] pdfBuf = converter.Convert(document);
FileStream fs = new FileStream(path, FileMode.Create);
fs.Write(pdfBuf, 0, pdfBuf.Length);
fs.Close();
}
}
}
The Controller is as follows:
[Route("converthtml")]
[HttpPost]
[MIMEContentFilter]
public async Task<HttpResponseMessage> ConvertHtml()
{
string temppath = System.IO.Path.GetTempPath();
var streamProvider = new MultipartFormDataStreamProvider(temppath);
await Request.Content.ReadAsMultipartAsync(streamProvider);
string filepath = streamProvider.FileData.Select(entry => entry.LocalFileName.Replace(temppath + "\\", "")).First<string>();
string pdfpath = System.IO.Path.GetTempFileName();
pdfpath = pdfpath.Substring(0, pdfpath.LastIndexOf('.')) + ".pdf";
new PDFcreator().convert(pdfpath, filepath);
var stream = new FileStream(pdfpath, FileMode.Open);
var result = new HttpResponseMessage(HttpStatusCode.OK);
result.Content = new StreamContent(stream);
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
return result;
}
Here's where it gets a little odd: Experimenting in Fiddler, sending a file once will return the PDF immediately. However, all subsequent POSTs will leave Fiddler hanging.
Examining Task Manager shows the CPU and Memory for this task to jump up to 13.5% and ~96MB respectively.
The Temp folder (where the files are stored), on a successful run, will have three files in it: the original uploaded file (stored with a GUID-like name), the file generated via wkHtmlToPdf (in the form "wktemp-"), and the generated pdf (as tempXXXX.pdf).
In the case of it hanging, only the first file can be found, indicating that the problem is somewhere in wkHtmlToPdf itself.
However, the real kicker is when the process is manually killed in Task Manager, the API completes successfully, returns the pdf, fully created!
If IIS is reset, the process returns to the original state; a new attempt will work without issue.
Obviously, resetting IIS after every call is hardly viable, nor is manually killing the process each time...
Is this a bug / are there any solutions to this issue?
EDIT: Very important - this answer had a lot of votes, but is not complete. Check the marked solution
var tempFolderDeployment = new TempFolderDeployment();
var win32EmbeddedDeployment = new Win32EmbeddedDeployment(tempFolderDeployment);
var remotingToolset = new RemotingToolset<PdfToolset>(win32EmbeddedDeployment);
var converter =
new ThreadSafeConverter(remotingToolset);
byte[] pdfBuf = converter.Convert(document);
remotingToolset.Unload();
Unload remotingToolset will prevent hanging
RemotingToolset.Unload();
Very important-
#toshkata-tonev answer helped me, but when a lot of sessions used this function our server crushed because over CPU!
The point is that the process should be shared by all sessions as static shared function.
So this was the solution for me:
Implementation:
Create a static class in your application:
public static class TuesPechkinInitializerService {
private static string staticDeploymentPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "wkhtmltopdf");
public static void CreateWkhtmltopdfPath()
{
if (Directory.Exists(staticDeploymentPath) == false)
{
Directory.CreateDirectory(staticDeploymentPath);
}
}
public static IConverter converter =
new ThreadSafeConverter(
new RemotingToolset<PdfToolset>(
new Win64EmbeddedDeployment(
new StaticDeployment(staticDeploymentPath)
)
)
);
}
In GLOBAL.asax, I initialize that class on project start:
TuesPechkinInitializerService.CreateWkhtmltopdfPath();
And to use it:
HtmlToPdfDocument pdfDocument = new HtmlToPdfDocument
{
GlobalSettings = new GlobalSettings(),
Objects =
{
new ObjectSettings
{
ProduceLocalLinks = true,
ProduceForms = true,
HtmlText = htmlContent
}
}
};
byte[] pdfDocumentData = TuesPechkinInitializerService.converter.Convert(pdfDocument);
Thanks to:
https://github.com/tuespetre/TuesPechkin/issues/152
It seems you are using WkHtmlToPdf 64 bits and you've installed the 32 bits one.
You should change :
IConverter converter = new StandardConverter(
new RemotingToolset<PdfToolset>(
new Win64EmbeddedDeployment(
new TempFolderDelpoyment())));
to
IConverter converter = new StandardConverter(
new RemotingToolset<PdfToolset>(
new Win32EmbeddedDeployment(
new TempFolderDelpoyment())));
I am developing a Win8 (WinRT, C#, XAML) client application (CSOM) that needs to download/upload files from/to SharePoint 2013.
How do I do the Download/Upload?
Upload a file
Upload a file to a SharePoint site (including SharePoint Online) using File.SaveBinaryDirect Method:
using (var clientContext = new ClientContext(url))
{
using (var fs = new FileStream(fileName, FileMode.Open))
{
var fi = new FileInfo(fileName);
var list = clientContext.Web.Lists.GetByTitle(listTitle);
clientContext.Load(list.RootFolder);
clientContext.ExecuteQuery();
var fileUrl = String.Format("{0}/{1}", list.RootFolder.ServerRelativeUrl, fi.Name);
Microsoft.SharePoint.Client.File.SaveBinaryDirect(clientContext, fileUrl, fs, true);
}
}
Download file
Download file from a SharePoint site (including SharePoint Online) using File.OpenBinaryDirect Method:
using (var clientContext = new ClientContext(url))
{
var list = clientContext.Web.Lists.GetByTitle(listTitle);
var listItem = list.GetItemById(listItemId);
clientContext.Load(list);
clientContext.Load(listItem, i => i.File);
clientContext.ExecuteQuery();
var fileRef = listItem.File.ServerRelativeUrl;
var fileInfo = Microsoft.SharePoint.Client.File.OpenBinaryDirect(clientContext, fileRef);
var fileName = Path.Combine(filePath,(string)listItem.File.Name);
using (var fileStream = System.IO.File.Create(fileName))
{
fileInfo.Stream.CopyTo(fileStream);
}
}
This article describes various options for accessing SharePoint content. You have a choice between REST and CSOM. I'd try CSOM if possible. File upload / download specifically is nicely described in this article.
Overall notes:
//First construct client context, the object which will be responsible for
//communication with SharePoint:
var context = new ClientContext(#"http://site.absolute.url")
//then get a hold of the list item you want to download, for example
var list = context.Web.Lists.GetByTitle("Pipeline");
var query = CamlQuery.CreateAllItemsQuery(10000);
var result = list.GetItems(query);
//note that data has not been loaded yet. In order to load the data
//you need to tell SharePoint client what you want to download:
context.Load(result, items=>items.Include(
item => item["Title"],
item => item["FileRef"]
));
//now you get the data
context.ExecuteQuery();
//here you have list items, but not their content (files). To download file
//you'll have to do something like this:
var item = items.First();
//get the URL of the file you want:
var fileRef = item["FileRef"];
//get the file contents:
FileInformation fileInfo = File.OpenBinaryDirect(context, fileRef.ToString());
using (var memory = new MemoryStream())
{
byte[] buffer = new byte[1024 * 64];
int nread = 0;
while ((nread = fileInfo.Stream.Read(buffer, 0, buffer.Length)) > 0)
{
memory.Write(buffer, 0, nread);
}
memory.Seek(0, SeekOrigin.Begin);
// ... here you have the contents of your file in memory,
// do whatever you want
}
Avoid working with the stream directly, read it into the memory first. Network-bound streams are not necessarily supporting stream operations, not to mention performance. So, if you are reading a pic from that stream or parsing a document, you may end up with some unexpected behavior.
On a side note, I have a related question re: performance of this code above, as you are taking some penalty with every file request. See here. And yes, you need 4.5 full .NET profile for this.
File.OpenBinaryDirect may cause exception when you are using Oauth accestoken
Explained in This Article
Code should be written as below to avoid exceptions
Uri filename = new Uri(filepath);
string server = filename.AbsoluteUri.Replace(filename.AbsolutePath,
"");
string serverrelative = filename.AbsolutePath;
Microsoft.SharePoint.Client.File file =
this.ClientContext.Web.GetFileByServerRelativeUrl(serverrelative);
this.ClientContext.Load(file);
ClientResult<Stream> streamResult = file.OpenBinaryStream();
this.ClientContext.ExecuteQuery();
return streamResult.Value;
A little late this comment but I will leave here my results working with the library of SharePoin Online and it is very easy to use and implement in your project, just go to the NuGet administrator of .Net and Add Microsoft.SharePoint.CSOM to your project .
[https://developer.microsoft.com/en-us/office/blogs/new-sharepoint-csom-version-released-for-office-365-may-2017/][1]
The following code snippet will help you connect your credentials to your SharePoint site, you can also read and download files from a specific site and folder.
using System;
using System.IO;
using System.Linq;
using System.Web;
using Microsoft.SharePoint.Client;
using System.Security;
using ClientOM = Microsoft.SharePoint.Client;
namespace MvcApplication.Models.Home
{
public class SharepointModel
{
public ClientContext clientContext { get; set; }
private string ServerSiteUrl = "https://somecompany.sharepoint.com/sites/ITVillahermosa";
private string LibraryUrl = "Shared Documents/Invoices/";
private string UserName = "someone.surname#somecompany.com";
private string Password = "********";
private Web WebClient { get; set; }
public SharepointModel()
{
this.Connect();
}
public void Connect()
{
try
{
using (clientContext = new ClientContext(ServerSiteUrl))
{
var securePassword = new SecureString();
foreach (char c in Password)
{
securePassword.AppendChar(c);
}
clientContext.Credentials = new SharePointOnlineCredentials(UserName, securePassword);
WebClient = clientContext.Web;
}
}
catch (Exception ex)
{
throw (ex);
}
}
public string UploadMultiFiles(HttpRequestBase Request, HttpServerUtilityBase Server)
{
try
{
HttpPostedFileBase file = null;
for (int f = 0; f < Request.Files.Count; f++)
{
file = Request.Files[f] as HttpPostedFileBase;
string[] SubFolders = LibraryUrl.Split('/');
string filename = System.IO.Path.GetFileName(file.FileName);
var path = System.IO.Path.Combine(Server.MapPath("~/App_Data/uploads"), filename);
file.SaveAs(path);
clientContext.Load(WebClient, website => website.Lists, website => website.ServerRelativeUrl);
clientContext.ExecuteQuery();
//https://somecompany.sharepoint.com/sites/ITVillahermosa/Shared Documents/
List documentsList = clientContext.Web.Lists.GetByTitle("Documents"); //Shared Documents -> Documents
clientContext.Load(documentsList, i => i.RootFolder.Folders, i => i.RootFolder);
clientContext.ExecuteQuery();
string SubFolderName = SubFolders[1];//Get SubFolder 'Invoice'
var folderToBindTo = documentsList.RootFolder.Folders;
var folderToUpload = folderToBindTo.Where(i => i.Name == SubFolderName).First();
var fileCreationInformation = new FileCreationInformation();
//Assign to content byte[] i.e. documentStream
fileCreationInformation.Content = System.IO.File.ReadAllBytes(path);
//Allow owerwrite of document
fileCreationInformation.Overwrite = true;
//Upload URL
fileCreationInformation.Url = ServerSiteUrl + LibraryUrl + filename;
Microsoft.SharePoint.Client.File uploadFile = documentsList.RootFolder.Files.Add(fileCreationInformation);
//Update the metadata for a field having name "DocType"
uploadFile.ListItemAllFields["Title"] = "UploadedCSOM";
uploadFile.ListItemAllFields.Update();
clientContext.ExecuteQuery();
}
return "";
}
catch (Exception ex)
{
throw (ex);
}
}
public string DownloadFiles()
{
try
{
string tempLocation = #"c:\Downloads\Sharepoint\";
System.IO.DirectoryInfo di = new DirectoryInfo(tempLocation);
foreach (FileInfo file in di.GetFiles())
{
file.Delete();
}
FileCollection files = WebClient.GetFolderByServerRelativeUrl(this.LibraryUrl).Files;
clientContext.Load(files);
clientContext.ExecuteQuery();
if (clientContext.HasPendingRequest)
clientContext.ExecuteQuery();
foreach (ClientOM.File file in files)
{
FileInformation fileInfo = ClientOM.File.OpenBinaryDirect(clientContext, file.ServerRelativeUrl);
clientContext.ExecuteQuery();
var filePath = tempLocation + file.Name;
using (var fileStream = new System.IO.FileStream(filePath, System.IO.FileMode.Create))
{
fileInfo.Stream.CopyTo(fileStream);
}
}
return "";
}
catch (Exception ex)
{
throw (ex);
}
}
}
}
Then to invoke the functions from the controller in this case MVC ASP.NET is done in the following way.
using MvcApplication.Models.Home;
using System;
using System.Web.Mvc;
namespace MvcApplication.Controllers
{
public class SharepointController : MvcBoostraBaseController
{
[HttpPost]
public ActionResult Upload(FormCollection form)
{
try
{
SharepointModel sharepointModel = new SharepointModel();
return Json(sharepointModel.UploadMultiFiles(Request, Server), JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{
return ThrowJSONError(ex);
}
}
public ActionResult Download(string ServerUrl, string RelativeUrl)
{
try
{
SharepointModel sharepointModel = new SharepointModel();
return Json(sharepointModel.DownloadFiles(), JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{
return ThrowJSONError(ex);
}
}
}
}
If you need this source code you can visit my github repository
https://github.com/israelz11/MvcBoostrapTestSharePoint/
Private Sub DownloadFile(relativeUrl As String, destinationPath As String, name As String)
Try
destinationPath = Replace(destinationPath + "\" + name, "\\", "\")
Dim fi As FileInformation = Microsoft.SharePoint.Client.File.OpenBinaryDirect(Me.context, relativeUrl)
Dim down As Stream = System.IO.File.Create(destinationPath)
Dim a As Integer = fi.Stream.ReadByte()
While a <> -1
down.WriteByte(CType(a, Byte))
a = fi.Stream.ReadByte()
End While
Catch ex As Exception
ToLog(Type.ERROR, ex.Message)
End Try
End Sub
Though this is an old post and have many answers, but here I have my version of code to upload the file to sharepoint 2013 using CSOM(c#)
I hope if you are working with downloading and uploading files then you know how to create Clientcontext object and Web object
/* Assuming you have created ClientContext object and Web object*/
string listTitle = "List title where you want your file to upload";
string filePath = "your file physical path";
List oList = web.Lists.GetByTitle(listTitle);
clientContext.Load(oList.RootFolder);//to load the folder where you will upload the file
FileCreationInformation fileInfo = new FileCreationInformation();
fileInfo.Overwrite = true;
fileInfo.Content = System.IO.File.ReadAllBytes(filePath);
fileInfo.Url = fileName;
File fileToUpload = fileCollection.Add(fileInfo);
clientContext.ExecuteQuery();
fileToUpload.CheckIn("your checkin comment", CheckinType.MajorCheckIn);
if (oList.EnableMinorVersions)
{
fileToUpload.Publish("your publish comment");
clientContext.ExecuteQuery();
}
if (oList.EnableModeration)
{
fileToUpload.Approve("your approve comment");
}
clientContext.ExecuteQuery();
And here is the code for download
List oList = web.Lists.GetByTitle("ListNameWhereFileExist");
clientContext.Load(oList);
clientContext.Load(oList.RootFolder);
clientContext.Load(oList.RootFolder.Files);
clientContext.ExecuteQuery();
FileCollection fileCollection = oList.RootFolder.Files;
File SP_file = fileCollection.GetByUrl("fileNameToDownloadWithExtension");
clientContext.Load(SP_file);
clientContext.ExecuteQuery();
var Local_stream = System.IO.File.Open("c:/testing/" + SP_file.Name, System.IO.FileMode.CreateNew);
var fileInformation = File.OpenBinaryDirect(clientContext, SP_file.ServerRelativeUrl);
var Sp_Stream = fileInformation.Stream;
Sp_Stream.CopyTo(Local_stream);
Still there are different ways I believe that can be used to upload and download.
Just a suggestion SharePoint 2013 online & on-prem file encoding is UTF-8 BOM.
Make sure your file is UTF-8 BOM, otherwise your uploaded html and scripts may not rendered correctly in browser.
I would suggest reading some Microsoft documentation on what you can do with CSOM. This might be one example of what you are looking for, but there is a huge API documented in msdn.
// Starting with ClientContext, the constructor requires a URL to the
// server running SharePoint.
ClientContext context = new ClientContext("http://SiteUrl");
// Assume that the web has a list named "Announcements".
List announcementsList = context.Web.Lists.GetByTitle("Announcements");
// Assume there is a list item with ID=1.
ListItem listItem = announcementsList.Items.GetById(1);
// Write a new value to the Body field of the Announcement item.
listItem["Body"] = "This is my new value!!";
listItem.Update();
context.ExecuteQuery();
From: http://msdn.microsoft.com/en-us/library/fp179912.aspx
I'm developing a web app with mongodb as my back-end. I'd like to have users upload pictures to their profiles like a linked-in profile pic. I'm using an aspx page with MVC2 and I read that GridFs library is used to store large file types as binaries. I've looked everywhere for clues as how this is done, but mongodb doesn't have any documentation for C# api or GridFs C#. I'm baffled and confused, could really use another set of brains.
Anyone one know how to actually implement a file upload controller that stores an image uploaded by a user into a mongodb collection? Thanks a million!
I've tried variations of this to no avail.
Database db = mongo.getDB("Blog");
GridFile file = new GridFile(db);
file.Create("image.jpg");
var images = db.GetCollection("images");
images.Insert(file.ToDocument());
Following example show how to save file and read back from gridfs(using official mongodb driver):
var server = MongoServer.Create("mongodb://localhost:27020");
var database = server.GetDatabase("tesdb");
var fileName = "D:\\Untitled.png";
var newFileName = "D:\\new_Untitled.png";
using (var fs = new FileStream(fileName, FileMode.Open))
{
var gridFsInfo = database.GridFS.Upload(fs, fileName);
var fileId = gridFsInfo.Id;
ObjectId oid= new ObjectId(fileId);
var file = database.GridFS.FindOne(Query.EQ("_id", oid));
using (var stream = file.OpenRead())
{
var bytes = new byte[stream.Length];
stream.Read(bytes, 0, (int)stream.Length);
using(var newFs = new FileStream(newFileName, FileMode.Create))
{
newFs.Write(bytes, 0, bytes.Length);
}
}
}
Results:
File:
Chunks collection:
Hope this help.
The answers above are soon to be outdated now that the 2.1 RC-0 driver has been released.
The way to work with files in v2.1 MongoDB with GridFS can now be done this way:
using MongoDB.Bson;
using MongoDB.Driver;
using MongoDB.Driver.GridFS;
using System.IO;
using System.Threading.Tasks;
namespace MongoGridFSTest
{
class Program
{
static void Main(string[] args)
{
var client = new MongoClient("mongodb://localhost");
var database = client.GetDatabase("TestDB");
var fs = new GridFSBucket(database);
var id = UploadFile(fs);
DownloadFile(fs, id);
}
private static ObjectId UploadFile(GridFSBucket fs)
{
using (var s = File.OpenRead(#"c:\temp\test.txt"))
{
var t = Task.Run<ObjectId>(() => { return
fs.UploadFromStreamAsync("test.txt", s);
});
return t.Result;
}
}
private static void DownloadFile(GridFSBucket fs, ObjectId id)
{
//This works
var t = fs.DownloadAsBytesByNameAsync("test.txt");
Task.WaitAll(t);
var bytes = t.Result;
//This blows chunks (I think it's a driver bug, I'm using 2.1 RC-0)
var x = fs.DownloadAsBytesAsync(id);
Task.WaitAll(x);
}
}
}
This is taken from a diff on the C# driver tests here
This example will allow you to tie a document to an object
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MongoDB.Driver;
using MongoDB.Driver.Linq;
using MongoDB.Bson;
using MongoDB.Driver.Builders;
using MongoDB.Driver.GridFS;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
MongoServer ms = MongoServer.Create();
string _dbName = "docs";
MongoDatabase md = ms.GetDatabase(_dbName);
if (!md.CollectionExists(_dbName))
{
md.CreateCollection(_dbName);
}
MongoCollection<Doc> _documents = md.GetCollection<Doc>(_dbName);
_documents.RemoveAll();
//add file to GridFS
MongoGridFS gfs = new MongoGridFS(md);
MongoGridFSFileInfo gfsi = gfs.Upload(#"c:\mongodb.rtf");
_documents.Insert(new Doc()
{
DocId = gfsi.Id.AsObjectId,
DocName = #"c:\foo.rtf"
}
);
foreach (Doc item in _documents.FindAll())
{
ObjectId _documentid = new ObjectId(item.DocId.ToString());
MongoGridFSFileInfo _fileInfo = md.GridFS.FindOne(Query.EQ("_id", _documentid));
gfs.Download(item.DocName, _fileInfo);
Console.WriteLine("Downloaded {0}", item.DocName);
Console.WriteLine("DocName {0} dowloaded", item.DocName);
}
Console.ReadKey();
}
}
class Doc
{
public ObjectId Id { get; set; }
public string DocName { get; set; }
public ObjectId DocId { get; set; }
}