VS Xamarin Android SQLite-net crashing the app in Android v7.x - c#

I am trying to make a cross platform app using Visual Studio 2015, Xamarin and SQLite. Everything is working fine until Android v6.0. But, when I test my app in android 7.x (7.0 and 7.1.1) emulators, my app crashed without even starting up. I read on xamarin forum about this crash under these links - Link 1 and Link 2 and came to know that since 7.0 native sqlite can't be used, but the answer there mentioned that -
First I deleted the libraries from 'Manage NuGet Packages for
Solutions...' - library 'sqlite-net-pcl' and the connected one
'SQLitePCL.raw'. Then I installed the new version of through the
PackageManager Console, in my case the command was 'Install-Package
sqlite-net-pcl'. Now the versions are 'sqlite-net-pcl' --> 1.2.0 |
'SQLitePCL.raw' --> 1.0.1. Also it downloaded others dependencies like
SQLitePCLRaw.bundle_green.
But, my project already has the updated version of sqlite-net-pcl and related packages.
sqlite-net-pcl => 1.2.0
SQLitePCL.bundle_green => 0.9.3
SQLitePCL.raw => 0.9.3
SQLitePCLRaw.bundle_green => 1.1.0
SQLitePCLRaw.core => 1.1.0
I am stuck here, they all are updated to the latest what should I change?
Relevant codes -
SqliteService.cs
using System;
using Medical_Study;
using Xamarin.Forms;
using Medical_Study.Droid;
using System.IO;
[assembly: Dependency(typeof(SqliteService))]
namespace Medical_Study.Droid
{
public class SqliteService : ISQLite
{
public SqliteService()
{
}
#region ISQLite implementation
public SQLite.SQLiteConnection GetConnection()
{
var sqliteFilename = "QBank.db";
string documentsPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal); // Documents folder
var path = Path.Combine(documentsPath, sqliteFilename);
// This is where we copy in the prepopulated database
Console.WriteLine(path);
if (!File.Exists(path))
{
var s = Forms.Context.Resources.OpenRawResource(Resource.Raw.QBank); // RESOURCE NAME ###
// create a write stream
FileStream writeStream = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write);
// write to the stream
ReadWriteStream(s, writeStream);
}
var conn = new SQLite.SQLiteConnection(path);
// Return the database connection
return conn;
}
#endregion
/// <summary>
/// helper method to get the database out of /raw/ and into the user filesystem
/// </summary>
void ReadWriteStream(Stream readStream, Stream writeStream)
{
int Length = 256;
Byte[] buffer = new Byte[Length];
int bytesRead = readStream.Read(buffer, 0, Length);
// write the required bytes
while (bytesRead > 0)
{
writeStream.Write(buffer, 0, bytesRead);
bytesRead = readStream.Read(buffer, 0, Length);
}
readStream.Close();
writeStream.Close();
}
}
}
DataAccess.cs
using System;
using SQLite;
using System.Collections.Generic;
using System.Linq;
using Xamarin.Forms;
using System.Text;
using System.Threading.Tasks;
using Medical_Study.Models;
namespace Medical_Study
{
public class DataAccess
{
static object locker = new object();
SQLiteConnection database;
public DataAccess()
{
database = DependencyService.Get<ISQLite>().GetConnection();
// create the tables
database.CreateTable<QBank>();
}
public IEnumerable<QBank> GetAllQuestions()
{
lock (locker)
{
return (from i in database.Table<QBank>() select i).ToList();
}
//return database.Query<QBank>("Select * From [QBank] where [qid]");
}
public IEnumerable<QBank> GetSpecialQuestions()
{
lock (locker)
{
return database.Query<QBank>("SELECT * FROM [QBank] WHERE [question_text] = 0");
}
}
public QBank GetQuestion(int id)
{
lock (locker)
{
return database.Table<QBank>().FirstOrDefault(x => x.qid == id);
}
}
public int SaveQuestion(QBank question)
{
lock (locker)
{
if (question.qid != 0)
{
database.Update(question);
return question.qid;
}
else
{
return database.Insert(question);
}
}
}
public int DeleteQuestion(int id)
{
lock (locker)
{
return database.Delete<QBank>(id);
}
}
}
}

Related

C#: copying Assets on Android

I try to use Xamarin for the development of an Android app. I built APK but can't get access to Assets where are saved some folders and files.
I need to copy these folders and files from Assets to an application directory of an android device and have access to them any time.
Please, help( I need a simple CSharp function of copy Assets files to an android device. I will grateful for any support.
You could look at File Storage and Access with Xamarin.Android and Using Android Assets first.
And here is a simple sample :
public static async Task CopyFile(Activity activity)
{
var filePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "YOUR_FILENAME");
if (!File.Exists(filePath))
{
try
{
using (var fileAssetsStream = activity.Assets.Open("YOUR_FILENAME"))
using (var fileStream = new FileStream(filePath, FileMode.OpenOrCreate))
{
var buffer = new byte[1024];
int b = buffer.Length;
int length;
while ((length = await fileAssetsStream.ReadAsync(buffer, 0, b)) > 0)
{
await fileStream.WriteAsync(buffer, 0, length);
}
}
}
catch (Exception ex)
{
//Handle exceptions
}
}
}
Don't forget to request WRITE_EXTERNAL_STORAGE runtime permissions.
[assembly: Dependency(typeof(FileCopyingService))]
namespace Mypp.Droid.Services
{
public class FileCopyingService : IFileCopyingService
{
Context _context;
public FileCopyingService()
{
this._context = Android.App.Application.Context;
}
public string CopyFiles(string folderName)
{
string path = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
var fileFolder = Path.Combine(path, folderName);
if (Directory.Exists(fileFolder))
Directory.Delete(fileFolder, true);
Directory.CreateDirectory(fileFolder);
foreach (var fItemName in this._context.Assets.List(folderName))
{
var dbFile = Path.Combine(fileFolder, fItemName);
if (File.Exists(dbFile))
{
File.Delete(dbFile);
}
if (!File.Exists(dbFile))
{
using (FileStream writeStream = new FileStream(dbFile, FileMode.OpenOrCreate, FileAccess.Write))
{
var assetsMapFile = folderName + "/" + fItemName;
this._context.Assets.Open(assetsMapFile).CopyTo(writeStream);
}
}
}
return fileFolder;
}
}
}
Add permission in AndroidManifest.xml source
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

Wopi Office Online proof keys process

I'm trying to Verifying that requests originate from Office Online by using proof keys
i'm implementing the wopi host with nodejs, and there are samples of code in the link above that implements the proof keys process using .NET
so i'm using the edge package to be able to run the .NET code with nodejs.
the problem is that the code is running fine, but it always returning that the proof keys in the request are not valid even when the requests are coming from the wopi client.
explanation: there are 3 functions:
validateProofKey - the main function - get all the requierd params to validate the proof key and return bool if they are valid using the functions : constructProofKey and TryProofkeyVerification
constructProofKey - declare .NET function (constructProofKey from sample code ) , run it and return the result of the constructed proofkey
TryProofkeyVerification - declare .NET function (TryProofkeyVerification from .NET sample code), run it and return the Boolean result
the code :
static async validateProofKey(access_token: string, request_url: string, X_WOPI_TimeStamp: string, X_WOPI_Proof: string, X_WOPI_Proof_old: string): Promise<boolean> {
//get public key provided in WOPI discovery:
if (!wopiDiscovery) { wopiDiscovery = await this.getWopiDiscovery() }
const public_Keys: iWopiDiscoveryProofKey = wopiDiscovery["wopi-discovery"]["proof-key"];
const public__Key: string = public_Keys.value;
const old_public_Key: string = public_Keys.oldvalue;
this.printProofkeyArgs(access_token, request_url, X_WOPI_TimeStamp, X_WOPI_Proof, X_WOPI_Proof_old, public__Key, old_public_Key, modulus_b64, exp_b64);
//1. Create the expected value of the proof headers.
let expectedProofKey: Buffer = await this.constructProofKey(access_token, request_url, X_WOPI_TimeStamp);
//2.Use the public key provided in WOPI discovery to decrypt the proof provided in the X-WOPI-Proof header.
const verified: boolean = await this.TryProofkeyVerification(expectedProofKey, X_WOPI_Proof, public__Key) ||
await this.TryProofkeyVerification(expectedProofKey, X_WOPI_Proof_old, public__Key) ||
await this.TryProofkeyVerification(expectedProofKey, X_WOPI_Proof, old_public_Key)
return verified;
}
constructProofKey
private static constructProofKey(access_token: string, request_url: string, X_WOPI_TimeStamp: string): Promise<Buffer> {
return new Promise((resolve, reject) => {
const proofParams = {
access_token: access_token,
request_url: request_url,
X_WOPI_TimeStamp: X_WOPI_TimeStamp
}
const constructProofKey = edge.func(`
using System.Threading.Tasks;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
public class Startup
{
public async Task<object> Invoke(dynamic proofParams)
{
return Helper.constructProofKey(proofParams);
}
}
static class Helper
{
public static byte[] constructProofKey(dynamic proofParams)
{
// Encode values from headers into byte[]
long timestamp = Convert.ToInt64(proofParams.X_WOPI_TimeStamp);
var accessTokenBytes = Encoding.UTF8.GetBytes(proofParams.access_token);
var hostUrlBytes = Encoding.UTF8.GetBytes(proofParams.request_url.ToUpperInvariant());
var timeStampBytes = EncodeNumber(timestamp);
// prepare a list that will be used to combine all those arrays together
List < byte > expectedProof = new List<byte>(
4 + accessTokenBytes.Length +
4 + hostUrlBytes.Length +
4 + timeStampBytes.Length);
expectedProof.AddRange(EncodeNumber(accessTokenBytes.Length));
expectedProof.AddRange(accessTokenBytes);
expectedProof.AddRange(EncodeNumber(hostUrlBytes.Length));
expectedProof.AddRange(hostUrlBytes);
expectedProof.AddRange(EncodeNumber(timeStampBytes.Length));
expectedProof.AddRange(timeStampBytes);
// create another byte[] from that list
byte[] expectedProofArray = expectedProof.ToArray();
return expectedProofArray;
}
private static byte[] EncodeNumber(long value)
{
return BitConverter.GetBytes(value).Reverse().ToArray();
}
}
`)
constructProofKey(proofParams, (error, result) => {
if (error) {
reject(error);
}
resolve(result);
});
})
}
TryProofkeyVerification
private static TryProofkeyVerification(expectedProofKey: Buffer, private_proofkey: string, public_proofkey: string): Promise<boolean> {
return new Promise((resolve, reject) => {
const proofParams = {
expectedProofKey: expectedProofKey,
private_proofkey: private_proofkey,
public_proofkey: public_proofkey
}
//declare .NET code
const TryVerification = edge.func(`
using System.Threading.Tasks;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
public class Startup
{
public async Task<object> Invoke(dynamic proofParams)
{
return Helper.TryVerification(proofParams);
}
}
static class Helper
{
public static bool TryVerification(dynamic proofParams)
{
byte[] expectedProofKey = (byte[])proofParams.expectedProofKey;
using(RSACryptoServiceProvider rsaAlg = new RSACryptoServiceProvider())
{
byte[] publicKey = Convert.FromBase64String(proofParams.public_proofkey);
byte[] signedProofBytes = Convert.FromBase64String(proofParams.private_proofkey);
try
{
rsaAlg.ImportCspBlob(publicKey);
return rsaAlg.VerifyData(expectedProofKey, "SHA256", signedProofBytes);
}
catch(FormatException)
{
Console.WriteLine("Format Exception");
return false;
}
catch(CryptographicException e)
{
Console.WriteLine("CryptographicException Exception");
return false;
}
}
}
}
`);
//Invoke .NET code
TryVerification(proofParams, (error, result) => {
if (error) {
reject(error);
}
resolve(result);
});
})
}
NOTE - I've already log the parameters to console to make sure the parameters transferred correctly through all the process

ASP.NET Web API: Video steaming not working on chrome and very slow on other browsers

What I am trying to do?
I am trying to create a video streaming website using ASP.net web API.
Problem
The api is working fine when running on local but when uploaded on live server then it does not play on chrome at all and too slow on firefox, opera
Live Demo of Problem
Please open this link in Chrome, firefox and you will see the difference.
Note: Live Demo link will be available till the problem is solved then I will remove it
GitHub link of source code
Please download the code from Github and in its videos folder please put a mp4 file of size at least 700mb or more
Please name it avan.mp4
Here is the code that I am using:
Coding part here
Code Credits: Robert Vandenberg Huang: Codeproject
Those who can not download the code from GitHub, I am providing everything here
Index.html
<video id="mainPlayer" width="640" height="360"
autoplay="autoplay" controls="controls" onloadeddata="onLoad()">
<source src="api/media/play?f=avan.mp4" />
</video>
Web API Code
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Net.Mime;
using System.Web.Configuration;
using System.Web.Http;
namespace VideoLIb.Controllers
{
//http://www.codeproject.com/Articles/820146/HTTP-Partial-Content-In-ASP-NET-Web-API-Video
public class MediaController : ApiController
{
#region Fields
// This will be used in copying input stream to output stream.
public const int ReadStreamBufferSize = 1024 * 512;//* 1024;
// We have a read-only dictionary for mapping file extensions and MIME names.
public static readonly IReadOnlyDictionary<string, string> MimeNames;
// We will discuss this later.
public static readonly IReadOnlyCollection<char> InvalidFileNameChars;
// Where are your videos located at? Change the value to any folder you want.
public static readonly string InitialDirectory;
#endregion
#region Constructors
static MediaController()
{
var mimeNames = new Dictionary<string, string>();
mimeNames.Add(".mp3", "audio/mpeg"); // List all supported media types;
mimeNames.Add(".mp4", "video/mp4");
mimeNames.Add(".ogg", "application/ogg");
mimeNames.Add(".ogv", "video/ogg");
mimeNames.Add(".oga", "audio/ogg");
mimeNames.Add(".wav", "audio/x-wav");
mimeNames.Add(".webm", "video/webm");
MimeNames = new ReadOnlyDictionary<string, string>(mimeNames);
InvalidFileNameChars = Array.AsReadOnly(Path.GetInvalidFileNameChars());
InitialDirectory = #"~/videos"; /// directory that contains videos
}
#endregion
#region Actions
//http://localhost:58720/
[HttpGet]
public HttpResponseMessage Play(string f)
{
// This can prevent some unnecessary accesses.
// These kind of file names won't be existing at all.
if (string.IsNullOrWhiteSpace(f) || AnyInvalidFileNameChars(f))
throw new HttpResponseException(HttpStatusCode.NotFound);
var mappedPath = System.Web.Hosting.HostingEnvironment.MapPath(Path.Combine(InitialDirectory, f));
FileInfo fileInfo = new FileInfo(mappedPath);
if (!fileInfo.Exists)
throw new HttpResponseException(HttpStatusCode.NotFound);
long totalLength = fileInfo.Length;
RangeHeaderValue rangeHeader = base.Request.Headers.Range;
HttpResponseMessage response = new HttpResponseMessage();
response.Headers.AcceptRanges.Add("bytes");
// The request will be treated as normal request if there is no Range header.
if (rangeHeader == null || !rangeHeader.Ranges.Any())
{
response.StatusCode = HttpStatusCode.OK;
response.Content = new PushStreamContent((outputStream, httpContent, transpContext)
=>
{
using (outputStream) // Copy the file to output stream straightforward.
using (Stream inputStream = fileInfo.OpenRead())
{
try
{
inputStream.CopyTo(outputStream, ReadStreamBufferSize);
}
catch (Exception error)
{
Debug.WriteLine(error);
}
}
}, GetMimeNameFromExt(fileInfo.Extension));
response.Content.Headers.ContentLength = totalLength;
return response;
}
long start = 0, end = 0;
// 1. If the unit is not 'bytes'.
// 2. If there are multiple ranges in header value.
// 3. If start or end position is greater than file length.
if (rangeHeader.Unit != "bytes" || rangeHeader.Ranges.Count > 1 ||
!TryReadRangeItem(rangeHeader.Ranges.First(), totalLength, out start, out end))
{
response.StatusCode = HttpStatusCode.RequestedRangeNotSatisfiable;
response.Content = new StreamContent(Stream.Null); // No content for this status.
response.Content.Headers.ContentRange = new ContentRangeHeaderValue(totalLength);
response.Content.Headers.ContentType = GetMimeNameFromExt(fileInfo.Extension);
return response;
}
var contentRange = new ContentRangeHeaderValue(start, end, totalLength);
// We are now ready to produce partial content.
response.StatusCode = HttpStatusCode.PartialContent;
response.Content = new PushStreamContent((outputStream, httpContent, transpContext)
=>
{
using (outputStream) // Copy the file to output stream in indicated range.
using (Stream inputStream = fileInfo.OpenRead())
CreatePartialContent(inputStream, outputStream, start, end);
}, GetMimeNameFromExt(fileInfo.Extension));
response.Content.Headers.ContentLength = end - start + 1;
response.Content.Headers.ContentRange = contentRange;
return response;
}
#endregion
#region Others
private static bool AnyInvalidFileNameChars(string fileName)
{
return InvalidFileNameChars.Intersect(fileName).Any();
}
private static MediaTypeHeaderValue GetMimeNameFromExt(string ext)
{
string value;
if (MimeNames.TryGetValue(ext.ToLowerInvariant(), out value))
return new MediaTypeHeaderValue(value);
else
return new MediaTypeHeaderValue(MediaTypeNames.Application.Octet);
}
private static bool TryReadRangeItem(RangeItemHeaderValue range, long contentLength,
out long start, out long end)
{
if (range.From != null)
{
start = range.From.Value;
if (range.To != null)
end = range.To.Value;
else
end = contentLength - 1;
}
else
{
end = contentLength - 1;
if (range.To != null)
start = contentLength - range.To.Value;
else
start = 0;
}
return (start < contentLength && end < contentLength);
}
private static void CreatePartialContent(Stream inputStream, Stream outputStream,
long start, long end)
{
int count = 0;
long remainingBytes = end - start + 1;
long position = start;
byte[] buffer = new byte[ReadStreamBufferSize];
inputStream.Position = start;
do
{
try
{
if (remainingBytes > ReadStreamBufferSize)
count = inputStream.Read(buffer, 0, ReadStreamBufferSize);
else
count = inputStream.Read(buffer, 0, (int)remainingBytes);
outputStream.Write(buffer, 0, count);
}
catch (Exception error)
{
Debug.WriteLine(error);
break;
}
position = inputStream.Position;
remainingBytes = end - position + 1;
} while (position <= end);
}
#endregion
}
}

Generating msi transform using c#

I am creating a cutomization software which will do all the standardization to a mst file.
Below is the code of class that will change product name and genrate transform.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WindowsInstaller;
using System.Data;
namespace Automation
{
class CustomInstaller
{
public CustomInstaller()
{
}
public Record getInstaller(string msiFile,MsiOpenDatabaseMode mode,string query)
{
Type type = Type.GetTypeFromProgID("WindowsInstaller.Installer");
Installer inst = (Installer)Activator.CreateInstance(type);
Database db = inst.OpenDatabase(msiFile, mode);
WindowsInstaller.View view = db.OpenView(query);
view.Execute(null);
Record record = view.Fetch();
db.Commit();
return record;
}
public bool generateTrans(string file1, string file2,string transName)
{
Type type = Type.GetTypeFromProgID("WindowsInstaller.Installer");
Installer inst = (Installer)Activator.CreateInstance(type);
Database db1 = inst.OpenDatabase(file1, MsiOpenDatabaseMode.msiOpenDatabaseModeReadOnly);
try
{
Database db2 = inst.OpenDatabase(file2, MsiOpenDatabaseMode.msiOpenDatabaseModeReadOnly);
return db2.GenerateTransform(db1, transName);
}
catch (Exception e) { }
return false;
}
public int editTransform(string msiFile, MsiOpenDatabaseMode mode, string query)
{
Type type = Type.GetTypeFromProgID("WindowsInstaller.Installer");
Installer inst = (Installer)Activator.CreateInstance(type);
Database db = inst.OpenDatabase(msiFile, mode);
WindowsInstaller.View view = db.OpenView(query);
view.Execute(null);
db.Commit();
int o=(int)db.DatabaseState;
db = null;
inst = null;
type = null;
return 1;
}
}
}
First editTransform() is called which will create a copy of original msi and do some changes in it, then generateTrans() is called which will get difference detween two msi files and create a transform file.
Now issue is when genrateTrans() is called, then it goes to catch block of it as inst.OpenDatabase return "MSI Api Error".
It seems to me that the copy of file crated by editTransform is still locked by it and is not available for use for generateTrans() menthod.
Please help here.
PS: mode used for edit transform is transact.
Instead of doing the COM Interop, checkout the far superior interop library ( Microsoft.Deployment.WindowsInstaller ) found in Windows Installer XML Deployment Tools Foundation. You'll find it much easier to use.
using System;
using System.IO;
using Microsoft.Deployment.WindowsInstaller;
namespace ConsoleApplication1
{
class Program
{
const string REFERENCEDATABASE = #"C:\orig.msi";
const string TEMPDATABASE = #"C:\temp.msi";
const string TRANSFORM = #"c:\foo.mst";
static void Main(string[] args)
{
File.Copy(REFERENCEDATABASE, TEMPDATABASE, true);
using (var origDatabase = new Database(REFERENCEDATABASE, DatabaseOpenMode.ReadOnly))
{
using (var database = new Database(TEMPDATABASE, DatabaseOpenMode.Direct))
{
database.Execute("Update `Property` Set `Property`.`Value` = 'Test' WHERE `Property`.`Property` = 'ProductName'");
database.GenerateTransform(origDatabase, TRANSFORM);
database.CreateTransformSummaryInfo(origDatabase, TRANSFORM, TransformErrors.None, TransformValidations.None);
}
}
}
}
}

MongoDB GridFs with C#, how to store files such as images?

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; }
}

Categories