3

What's the best way to connect to mongo (on a remote server) from c#?

Story so far

I've had no end of hassle trying to do a simple find from a very basic c# console app connecting to mongo labs.

I was able to connect using both Mongo Shell and RoboMongo and query the collection I had set up. But I still couldn't do the same with my c# code - even though I was using exactly the same credentials. Primarily it was timing out whenever I tried to actually execute a find against the collection I had set up within the database.

All of the help information / examples / etc. out there is Waaaaaaaaaaaaay too old to be useful.

I'm using mLabs mongo connection template - pretty standard stuff

mongodb://<dbuser>:<dbpassword>@<serverName>.mlab.com:<port>/<databaseName>

And doing very standard things to try and read from the collection - but no go, it always times out. Buried in the exception returned was a reference to authentication failed. And inspecting the various objects I could see that for one of the authentication related members was blank.

So to restate the question - what's the best way to connect to a remote mongo repository using c#? Bonus points if it includes best practice for handling all of the good stuff, e.g. clusters, replication sets, etc.

Community
  • 1
  • 1
Lee H
  • 437
  • 1
  • 5
  • 13

4 Answers4

3

Walk-through:

I've set up an account with mongo labs (www.mlab.com) and I'm able to successfully connect to it via their web UI.

I created a database and then tried connecting to it using the mongo shell and also robomongo - no success.

After much digging around I found the simple answer - I needed to create an additional user and give that user specific access to the database. And use that user's credentials to access the database.

So I did all of that and now I can connect to the database with both the Mongo shell and RoboMongo and query the collection.

But I still couldn't query with my c# code - exactly the same credentials (including case) - but I just got time outs when trying to execute a find.

I eventually found this: http://stackoverflow.com/questions/30758668/how-to-get-connection-status-in-the-c-sharp-mongodb-driver-v2-0 and it gave me a clue to try using MongoClientSettings when creating the client instead of MongoUrl. I came up with this bit of code:

  var credential = MongoCredential.CreateCredential(DatabaseName, UserName, Password);

  var mongoClientSettings = new MongoClientSettings
  {
    Server = new MongoServerAddress(serverAddress, Port),
    Credentials = new List<MongoCredential> {credential}
  };

and it worked when I used the credentials in this form to create the client.

Curiously now that I have succeeded with a MongoClientSettings, I'm able to go back to using MongoUrl - it's as if some outstanding value on the mLabs/mongo server side of things has finally been defaulted properly.

The full block of calls for each step looks like this:

  var mongoClientSettings = BuildMongoClientSettings();
  var client = ClientConnection(mongoClientSettings);
  var database = DatabaseConnection(client, DatabaseName);
  var collection = CollectionConnection(database, CollectionName);
  var data = collection.Find(_ => true).ToList(); // yes I know it's not async - that comes next

All of the methods are pretty standard, but here's the one for the collection:

private static IMongoCollection<BsonDocument> CollectionConnection(IMongoDatabase database, string collectionName)
{
  var collection = database.GetCollection<BsonDocument>(collectionName);

  return collection;
}
vidriduch
  • 4,753
  • 8
  • 41
  • 63
Lee H
  • 437
  • 1
  • 5
  • 13
2

Check out the links below :

1) MongoDB uri (c#) : MongoURI

2) Mlab (Online Hosting for MongoDB) : mlab.com

After completing the process of hosting your Database, you can test your database online with the following code :

try
{
    string connectstring1 = "mongodb://user1:password1@ds*****.mlab.com:234***/dbname";
    MongoClient client = new MongoClient(connectstring1);
    var db = client.GetDatabase("dbname");
    var collection = db.GetCollection<BsonDocument>("collectionName");
    var filter1 = Builders<BsonDocument>.Filter.Empty;
    var filter = new BsonDocument();
    using (var cursor = await collection.FindAsync(filter))
    {
        while (await cursor.MoveNextAsync())
        {
            var batch = cursor.Current;
            foreach (var document in batch)
            {
                MessageBox.Show(document[1].ToString(), "msg");
            }
        }
    }
}
catch(Exception ex)
{
    MessageBox.Show(ex.Message);
}
Nuri Tasdemir
  • 9,720
  • 3
  • 42
  • 67
Mirtov
  • 77
  • 11
0

I struggled with connecting to my mLab MongoDB until I read @Lee-H's good answer. The following is the code as I wrote it for my Web API controller's base class. Obviously, you could throw this right in your controller, as needed:

public abstract class CtrlBase : ApiController
{
    private IMongoDatabase _db = null;
    protected IMongoDatabase DB
    {
        get
        {
            if (_db == null)
            {
                var cred = MongoCredential.CreateCredential("user", "password");
                var sett = new MongoClientSettings
                {
                    Server = new MongoServerAddress("server", <port>),
                    Credentials = new List<MongoCredential> { cred }
                };
                var client = new MongoClient(sett);
                _db = client.GetDatabase("dbName");
            }
            return _db;
        }
    }

    protected IMongoCollection<Thing> Things
    {
        get { return DB.GetCollection<Thing>("mythings"); }
    }

}

Note that I did not revert to connecting via a password-embedded connection string as @Lee-H said he did, so I have not verified that it would work that way if I switched back because it would irritate me to learn that. Nonetheless, @Lee-H says it started working that way for him.

Good luck.

witttness
  • 4,984
  • 4
  • 25
  • 24
0

I am trying to insert data into MongoDB using the task class. But some of the MongoDB classes have been deprecated.

 public class Task
    {
        [BsonId(IdGenerator = typeof(CombGuidGenerator))]
        public Guid ID { get; set; }

        [BsonElement("Artist")]
        public string Name { get; set; }

        [BsonElement("Song")]
        public string Song { get; set; }
  }

public void CreateTask(Task task)
        {
            MongoCollection<Task> collection = GetTaskCollection();

            try
            {
                collection.Insert(task);

            }
            catch(MongoCommandException ex)
            {

              string message = ex.Message;
            }
        }

        private void insert_Click(object sender, EventArgs e)
        {

            string name = txtBxName.Text;
            string song = txtBxSong.Text;

            Task t = new Task
            {

                Name = name,

                Song = song
            };
            Dal d = new Dal();

            List<Task> list = new List<Task>(200);
            list.Add(t);

            data.DataSource = list;
        }
Nithin
  • 9,661
  • 14
  • 44
  • 67