简体   繁体   中英

Why is C# and MongoDB Driver code connecting, but failing to Write?

Here is the information about my development environment:

  • Microsoft Visual Studio Community 2015
  • .NET Framework 4.6
  • ASP.NET MVC assembly System.Web.Mvc Version=5.2.3.0
  • MongoDB.Driver 2.0.1.27
  • Mongodb 3.0.6

Within my C# application, I have the following code that retrieves a MongoDB database reference:

public class MongoDBConnectionManager {
    public IMongoDatabase getMongoDB() {
        var client = new MongoClient("mongodb://localhost:27017");
        MongoClient(System.Configuration.ConfigurationManager.ConnectionStrings["MongoDB"].ConnectionString);

        MongoServer.Create("Server=localhost:27017");
        IMongoCollection <BsonDocument> UserDetails = iMgDb.GetCollection<BsonDocument>("Users");

        return iMgDb;
    }
}

Here is the POCO class that represent a User Business Entity:

using MongoDB.Bson.Serialization.Attributes;

public class UserModel {
    [BsonId]
    public int ID { get; set; }

    [Required]
    [BsonElement]
    public string UserName { get; set; }

    [Required]
    [BsonElement]
    public string Password { get; set; }

    [Required]
    [BsonElement]
    public string Email { get; set; }

    [BsonElement]
    public string PhoneNo { get; set; }

    [BsonElement]
    public string Address { get; set; }
}

Here is the DAO C# class that uses the Mongo DB Connection Manager Class:

public class DAO {
    public async Task<int> insertNewUser(UserModel um) {
        MongoDBConnectionManager mgoDBCntMng = new MongoDBConnectionManager();

        IMongoDatabase database = mgoDBCntMng.getMongoDB();

        IMongoCollection <UserModel> UserDetails = database.GetCollection<UserModel>("Users");

        try {
            Task getTask = UserDetails.InsertOneAsync(um);
            await getTask;
        } catch(Exception) {
        }
        return 0;
    }
}

When I run the application, I can see the following information logged in the DOS Command Prompt window where I started the mongoDB. If you look towards the end of the Dos Command Prompt, you will notice 2 connections being made:

C:\Program Files\MongoDB\Server\3.0\bin>mongod --dbpath ./data/db

2015-09-23T12:23:07.896+0530 I JOURNAL  [initandlisten] journal 
dir=./data/db\jo

urnal

2015-09-23T12:23:07.900+0530 I JOURNAL  [initandlisten] recover : no 
journal fil

es present, no recovery needed

2015-09-23T12:23:08.060+0530 I JOURNAL  [durability] Durability thread started

2015-09-23T12:23:08.062+0530 I JOURNAL  [journal writer] Journal writer thread s

tarted

2015-09-23T12:23:08.283+0530 I CONTROL  [initandlisten] MongoDB starting 
: pid=1

2936 port=27017 dbpath=./data/db 64-bit host=My-PC

2015-09-23T12:23:08.283+0530 I CONTROL  [initandlisten] targetMinOS: 
Windows 7/W

indows Server 2008 R2

2015-09-23T12:23:08.284+0530 I CONTROL  [initandlisten] db version v3.0.6

2015-09-23T12:23:08.284+0530 I CONTROL  [initandlisten] git version: 
1ef45a23a4c

5e3480ac919b28afcba3c615488f2

2015-09-23T12:23:08.284+0530 I CONTROL  [initandlisten] build info: 
windows sys.

getwindowsversion(major=6, minor=1, build=7601, platform=2, 
service_pack='Servic

e Pack 1') BOOST_LIB_VERSION=1_49

2015-09-23T12:23:08.285+0530 I CONTROL  [initandlisten] allocator: 
tcmalloc

2015-09-23T12:23:08.285+0530 I CONTROL  [initandlisten] options: { 
storage: { db

Path: "./data/db" } }

2015-09-23T12:23:08.321+0530 I NETWORK  [initandlisten] waiting for 
connections

on port 27017

2015-09-23T12:24:20.326+0530 I NETWORK  [initandlisten] connection 
accepted from

 127.0.0.1:65065 #1 (1 connection now open)

2015-09-23T12:24:22.332+0530 I NETWORK  [initandlisten] connection 
accepted from

 127.0.0.1:65066 #2 (2 connections now open)

I'm really stumped as to how to resolve the problem. I tried to search the MongoDB error log using DOS command prompt, but it shows NO errors. From MongoDB client using DOS command prompt, I got the following:

C:\Program Files\MongoDB\Server\3.0\bin>mongo
MongoDB shell version: 3.0.6
connecting to: test
> use foo
switched to db foo
> db.runCommand( { getLastError: 1, w: 1, wtimeout:5000 } )
{
        "connectionId" : 6,
        "n" : 0,
        "syncMillis" : 0,
        "writtenTo" : null,
        "err" : null,
        "ok" : 1
}

The problem that I am facing is that the point of execution runs smoothly, but fails to write to the database.
What is wrong with the way I use async and wait in the said code?

Could someone please tell me how to correct the problem?

From MSDN

The await operator is applied to a task in an asynchronous method to suspend the execution of the method until the awaited task completes. The task represents ongoing work.

So await does suspend or block until the task is completed so we just create multiple tasks and make sure we don't await it until we think we need to, if you are dealing with collection of inserts?

var tasks = new Task<//return type of UserDetails.InsertOneAsync(um)>[//get collection count here];
var count = 0;
foreach(// iterate collection here)
{
try {
            tasks[count] = UserDetails.InsertOneAsync(um); // adds continuations and return back immediately i.e. no blocking
            count++;
        } catch(Exception) {
    }
}
await Task.WhenAll(tasks.ToArray()); // here is where we block all tasks and wait for completion

Note: Not exactly answer but will somewhat clear what we are doing

There are some problem with your getMongoDB function code:

  • No need of making two connection use only one
  • IMongoClient is used to get database in Mongo.Driver 2.0.1.17. No need of Making "MongoServer"
  • No need of getting collection in "getMongoDB" function

Here is the code for "getMongoDB" function:

     public IMongoDatabase getMongoDB() 
     {
        IMongoClient client = new MongoClient("mongodb://localhost:27017");
        var iMgDb = client.GetDatabase("Database Name Here");
        return iMgDb;
     }

Hope this will help.

It took a while, but the problem was caused by the fact that I mistakenly used the int basic data type for the ID in the UserModel as opposed to ObjectId.

Here is the corrected code for the UserModel:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
using MongoDB.Bson;
using MongoDB.Driver;
using MongoDB.Driver.Linq;
using WebApplication1.Models;
using MongoDB.Bson.Serialization.Attributes;

namespace WebApplication1.Models
{
    public class UserModel
    {

        [BsonId]
        public ObjectId ID { get; set; }

        [Required]
        [BsonElement]
        public string UserName { get; set; }

        [Required]
        [BsonElement]
        public string Password { get; set; }

        [Required]
        [BsonElement]
        public string Email { get; set; }

        [BsonElement]
        public string PhoneNo { get; set; }

        [BsonElement]
        public string Address { get; set; }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM