{"id":10,"date":"2018-07-23T10:30:47","date_gmt":"2018-07-23T08:30:47","guid":{"rendered":"http:\/\/qappdesign.com\/?p=10"},"modified":"2018-10-17T21:44:41","modified_gmt":"2018-10-17T19:44:41","slug":"using-mongodb-with-net-core-webapi","status":"publish","type":"post","link":"https:\/\/qappdesign.com\/code\/using-mongodb-with-net-core-webapi\/","title":{"rendered":"Using MongoDB .NET Driver with .NET Core WebAPI"},"content":{"rendered":"<h4>What&#8217;s about<\/h4>\n<p>Problem \/ solution format brings an easier understanding on how to build things, giving an immediate feedback. Starting from this idea, the blog post I will present step by step how to build<\/p>\n<blockquote><p>a web application to store your ideas in an easy way, adding text notes, either from desktop or mobile, with few characteristics: run fast, save on the fly whatever you write, and be reasonably reliable and secure.<\/p><\/blockquote>\n<p>This article will implement just the backend, WebApi and the database access, in the most simple way.<\/p>\n<h4>A couple of updates done to the original article<\/h4>\n<ul>\n<li>Following Peter&#8217;s comment, I have simplified the documents returned, see HttpGet requests<\/li>\n<li>Following Luciano&#8217;s comment, I have extend the update function, making update of the full MongoDB documents at once, not just to some of the properties. There is a new section below, describing this change<\/li>\n<li>Trying to read from Angular 2, <a href=\"\/getting-started-with-angular2-with-aspnet-core-webapi-build-notebook-app\/\" target=\"_blank\">find the article here<\/a>, I have ran into CORS problems. An error message was displayed &#8220;No &#8216;Access-Control-Allow-Origin&#8217; header is present on the requested resource&#8221;. I have added a new section to describe the solution.<\/li>\n<li>I have updated the project to <a href=\"https:\/\/blogs.msdn.microsoft.com\/dotnet\/2016\/11\/16\/announcing-net-core-1-1\/\" target=\"_blank\">.NET Core 1.1<\/a> as well to <a href=\"https:\/\/github.com\/mongodb\/mongo-csharp-driver\/blob\/master\/Release%20Notes\/Release%20Notes%20v2.4.0.md\" target=\"_blank\">MongoDB .NET Driver 2.4<\/a><\/li>\n<li>Added a basic level of exception management<\/li>\n<li>Following Peter&#8217;s comment I have converted the solution to Visual Studio 2017<\/li>\n<li><strong>Updated to .NET Core 2.0<\/strong><\/li>\n<li>Following Matthew&#8217;s comment, I have updated the interface INoteRepository to not be coupled to MongoDB libraries<\/li>\n<li>added a compound MongoDb index<\/li>\n<li><strong>Following the comments from Kirk and Andrea, I have added to the structure the MongoDb BSonId and added a section of model binding of JSON Posts<\/strong><\/li>\n<li>Following comments from Manish and Zahn, I have extended the example with a nested class; Updated to MongoDb.Driver 2.7, which add support for new features of the MongoDB 4.0 Server.<\/li>\n<\/ul>\n<p>The <a href=\"https:\/\/github.com\/fpetru\/WebApiMongoDB\" target=\"_blank\">GitHub project<\/a> is updated and includes all these changes. You could directly <a href=\"https:\/\/github.com\/fpetru\/WebApiMongoDB\/archive\/master.zip\" target=\"_blank\">download the sources<\/a> or clone the project locally. <\/p>\n<h4>Topics covered<\/h4>\n<ul>\n<li>Technology stack<\/li>\n<li>Configuration model<\/li>\n<li>Options model<\/li>\n<li>Dependency injection<\/li>\n<li>MongoDb &#8211; Installation and configuration using MongoDB C# Driver v.2<\/li>\n<li>Make a full ASP.NET WebApi project, connected async to MongoDB<\/li>\n<li>Allowing Cross Domain Calls (CORS)<\/li>\n<li>Update entire MongoDB documents<\/li>\n<li>Exception management<\/li>\n<li>Model binding of HTTP Post command (newly added)<\/li>\n<li>Nested classes in MongoDb<\/li>\n<\/ul>\n<h4>You might be interested also<\/h4>\n<ul>\n<li>Part 1 &#8211; Run LINQ queries with MongoDB &#8211; <a href=\"https:\/\/qappdesign.com\/code\/search-best-places-mongodb-linq-netcore\/\" target=\"_blank\">How to search good places to travel (MongoDb LINQ &amp; .NET Core)<\/a><\/li>\n<li><a href=\"https:\/\/qappdesign.com\/code\/paging-mongodb-avoid-poor-performance\/\">Part 2 &#8211; Paging in MongoDB \u2013 How to actually avoid poor performance ?<\/a><\/li>\n<li><a href=\"https:\/\/qappdesign.com\/code\/mongodb-and-linq-how-to-aggregate-and-join-collections\/\">Part 3 &#8211; MongoDb and LINQ: How to aggregate and join collections<\/a><\/li>\n<li><a href=\"https:\/\/qappdesign.com\/code\/mongodb-aspnetmvc-core\/\">Using MongoDB .NET Driver with ASP.NET Core MVC<\/a><\/li>\n<\/ul>\n<h4>Technology stack<\/h4>\n<p>The ASP.NET Core Web API has the big advantage that it can be used as HTTP service and it can be subscribed by any client application, ranging from desktop to mobiles, and also be installed on Windows, macOS or Linux.<\/p>\n<p>MongoDB is a popular NoSQL database that makes a great backend for Web APIs. These lend themselves more to document store type, rather than to relational databases. This blog will present how to build a .NET Core Web API connected asynchronously to MongoDB, with full support for HTTP GET, PUT, POST, and DELETE.<\/p>\n<h4>To install<\/h4>\n<p>Here are all the things needed to be installed:<\/p>\n<ul>\n<li><a href=\"http:\/\/visualstudio.com\/free\" target=\"_blank\">Visual Studio Community 2017<\/a>, including .NET Core option<\/li>\n<li><a href=\"https:\/\/www.mongodb.com\/download-center#community\" target=\"_blank\">MongoDB<\/a> and <a href=\"https:\/\/robomongo.org\/\" target=\"_blank\">Robo 3T<\/a><\/li>\n<\/ul>\n<h4>Creating the ASP.NET WebApi project<\/h4>\n<p>Launch Visual Studio and\u00a0then access File\u00a0>\u00a0New Project\u00a0>\u00a0.Net Core\u00a0>\u00a0ASP.NET Core Web Application.<br \/>\n<img src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" data-src=\"https:\/\/qappdesign.com\/wp-content\/uploads\/2017\/04\/VisualStudio2017-New-.NETCore-Project.jpg\" alt=\"\" class=\"lazyload \" \/><noscript><img src=\"https:\/\/i0.wp.com\/qappdesign.com\/wp-content\/uploads\/2017\/04\/VisualStudio2017-New-.NETCore-Project.jpg?w=960&#038;ssl=1\" alt=\"\" data-recalc-dims=\"1\" \/><\/noscript><br \/>\nand then<br \/>\n<img src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" data-src=\"https:\/\/qappdesign.com\/code\/wp-content\/uploads\/2017\/04\/VisualStudio2017-New-WebApi-Project.jpg\" alt=\"\" class=\"lazyload \" \/><noscript><img src=\"https:\/\/i0.wp.com\/qappdesign.com\/code\/wp-content\/uploads\/2017\/04\/VisualStudio2017-New-WebApi-Project.jpg?w=960&#038;ssl=1\" alt=\"\" data-recalc-dims=\"1\" \/><\/noscript><\/p>\n<h4>Configuration<\/h4>\n<p>There are multiple file formats, supported out of the box for the configuration (JSON, XML, or INI). By default, the WebApi project template comes with JSON format enabled. Inside the setting file, order matters, and include complex structures. Here is an example with a 2 level settings structure for database connection.<br \/>\n<b>AppSettings.json &#8211; update the file:<\/b><\/p>\n<pre class=\"lang:xml theme:stock mark:1,2,4,5\">\r\n{\r\n  &quot;MongoConnection&quot;: {\r\n    &quot;ConnectionString&quot;: &quot;mongodb:\/\/admin:abc123!@localhost&quot;,\r\n    &quot;Database&quot;: &quot;NotesDb&quot;\r\n  },\r\n\r\n  &quot;Logging&quot;: {\r\n    &quot;IncludeScopes&quot;: false,\r\n    &quot;Debug&quot;: {\r\n      &quot;LogLevel&quot;: {\r\n        &quot;Default&quot;: &quot;Warning&quot;\r\n      }\r\n    },\r\n    &quot;Console&quot;: {\r\n      &quot;LogLevel&quot;: {\r\n        &quot;Default&quot;: &quot;Warning&quot;\r\n      }\r\n    }\r\n  }\r\n}\r\n<\/pre>\n<h4>Dependency injection and Options model<\/h4>\n<p>Constructor injection is one of the most common approach to implementing Dependency Injection (DI), though not the only one. ASP.NET Core uses constructor injection in its solution, so we will also use it. ASP.NET Core project has a Startup.cs file, which configures the environment in which our application will run. The Startup.cs file also places services into ASP.NET Core&#8217;s Services layer, which is what enables dependency injection.<\/p>\n<p>To map the custom database connection settings, we will add a new Settings class.<\/p>\n<pre class=\"lang:csharp\">\r\nnamespace NotebookAppApi.Model\r\n{\r\n    public class Settings\r\n    {\r\n        public string ConnectionString;\r\n        public string Database;\r\n    }\r\n}\r\n<\/pre>\n<p>Here is how we modify Startup.cs to inject Settings in the Options accessor model:<\/p>\n<pre class=\"lang:csharp\">\r\npublic void ConfigureServices(IServiceCollection services)\r\n{\r\n    \/\/ Add framework services.\r\n    services.AddMvc();\r\n    services.Configure&lt;Settings&gt;(options =&gt;\r\n    {\r\n        options.ConnectionString \r\n\t\t\t= Configuration.GetSection(&quot;MongoConnection:ConnectionString&quot;).Value;\r\n        options.Database \r\n\t\t\t= Configuration.GetSection(&quot;MongoConnection:Database&quot;).Value;\r\n    });\r\n}<\/pre>\n<p>Further in the project, settings will be access via IOptions interface:<\/p>\n<pre>IOptions&lt;Settings&gt;<\/pre>\n<h4>MongoDB configuration<\/h4>\n<p>Once you have installed <a href=\"https:\/\/www.mongodb.com\/download-center#community\" target=\"_blank\">MongoDB<\/a>, you would need to configure the access, as well as where the data is located.<\/p>\n<p>To do this, create a file locally, named <b>mongod.cfg<\/b>. This will include setting path to the data folder for MongoDB server, as well as to the MongoDB log file, initially without any authentication. Please update these local paths, with your own settings:<\/p>\n<pre class=\"lang:xml theme:stock\">\r\nsystemLog:\r\n  destination: file\r\n  path: \"C:\\\\tools\\\\mongodb\\\\db\\\\log\\\\mongo.log\"\r\n  logAppend: true\r\nstorage:\r\n  dbPath: \"C:\\\\tools\\\\mongodb\\\\db\\\\data\"\r\n<\/pre>\n<p>Run in <b>command prompt<\/b> next line. This will start the MongoDB server, pointing to the configuration file already created (in case the server is installed in a custom folder, please update first the command) <\/p>\n<pre class=\"lang:VS2012 Black\">\r\n&quot;C:\\Program Files\\MongoDB\\Server\\3.2\\bin\\mongod.exe&quot; --config C:\\Dev\\Data.Config\\mongod.cfg\r\n<\/pre>\n<p>Once the server is started (and you could see the details in the log file), run mongo.exe in <b>command prompt<\/b>. The next step is to add the <em>administrator<\/em> user to the database. Run mongodb with the full path (ex: &#8220;C:\\Program Files\\MongoDB\\Server\\3.2\\bin\\mongo.exe&#8221;).<br \/>\n<img class=\"img-responsive wp-post-image lazyload \" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" data-src=\"https:\/\/qappdesign.com\/wp-content\/uploads\/2016\/10\/Image-003.1.jpg\" alt=\"sketch\" sizes=\"(max-width: 708px) 100vw, 390px\"><noscript><img class=\"img-responsive wp-post-image\" src=\"https:\/\/i0.wp.com\/qappdesign.com\/wp-content\/uploads\/2016\/10\/Image-003.1.jpg?w=960&#038;ssl=1\" alt=\"sketch\" sizes=\"(max-width: 708px) 100vw, 390px\" data-recalc-dims=\"1\"><\/noscript><\/p>\n<p>and then copy paste the next code in the console:<\/p>\n<pre class=\"lang:VS2012 Black\">\r\nuse admin\r\ndb.createUser(\r\n  {\r\n\tuser: &quot;admin&quot;,\r\n\tpwd: &quot;abc123!&quot;,\r\n\troles: [ { role: &quot;root&quot;, db: &quot;admin&quot; } ]\r\n  }\r\n);\r\nexit;\r\n<\/pre>\n<p>Then stop the server and update the configuration file, including the security option.<\/p>\n<pre class=\"lang:xml theme:stock\">\r\nsystemLog:\r\n  destination: file\r\n  path: &quot;C:\\\\tools\\\\mongodb\\\\db\\\\log\\\\mongo.log&quot;\r\n  logAppend: true\r\nstorage:\r\n  dbPath: &quot;C:\\\\tools\\\\mongodb\\\\db\\\\data&quot;\r\nsecurity:\r\n  authorization: enabled\r\n<\/pre>\n<p>From now on, we&#8217;ll connect to MongoDb using <em>admin<\/em> user. There is a good practice to not use the superuser role (in our case <em>administrator<\/em>) for normal operations, but in order to keep the things simple, we will continue to have just a single user.  <\/p>\n<h4>MongoDB .NET Driver<\/h4>\n<p>To connect to MongoDB, add via Nuget the package named <em>MongoDB.Driver<\/em>. This is the new official driver for .NET, fully supporting the ASP.NET Core applications.<br \/>\n<img src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" data-src=\"https:\/\/qappdesign.com\/code\/wp-content\/uploads\/2017\/04\/MongoDB-Nuget.jpg\" alt=\"\" class=\"lazyload \" \/><noscript><img src=\"https:\/\/i0.wp.com\/qappdesign.com\/code\/wp-content\/uploads\/2017\/04\/MongoDB-Nuget.jpg?w=960&#038;ssl=1\" alt=\"\" data-recalc-dims=\"1\" \/><\/noscript><\/p>\n<h4>Model<\/h4>\n<p>The model class (POCO) associated with each entry in the notebook is included below:<\/p>\n<pre class=\"lang:csharp theme:stock\">\r\nusing System;\r\nusing MongoDB.Bson.Serialization.Attributes;\r\n\r\nnamespace NotebookAppApi.Model\r\n{\r\n\tpublic class Note\r\n\t{\r\n\t\t[BsonId]\r\n\t\t\/\/ standard BSonId generated by MongoDb\r\n\t\tpublic ObjectId InternalId { get; set; }\r\n\r\n\t\t\/\/ external Id, easier to reference: 1,2,3 or A, B, C etc.\r\n\t\tpublic string Id { get; set; }                          \r\n\r\n\t\tpublic string Body { get; set; } = string.Empty;\r\n\r\n\t\t[BsonDateTimeOptions]\r\n                \/\/ attribute to gain control on datetime serialization\r\n\t\tpublic DateTime UpdatedOn { get; set; } = DateTime.Now;\r\n\r\n\t\tpublic NoteImage HeaderImage { get; set; }\r\n\r\n\t\tpublic int UserId { get; set; } = 0;\r\n\t}\r\n}\r\n<\/pre>\n<p><strong><em>Note:<\/em><\/strong> By default, using the parameter <em>BsonDateTimeOptions<\/em>, Bson serializer tries to serialize as a DateTime, as UTC. Adding the attribute as follows, we allow saving in local time instead: [BsonDateTimeOptions(Kind = DateTimeKind.Local)]<\/p>\n<p>Assuming the Note would have a header image, here would be a sample embedded class:<\/p>\n<pre class=\"lang:csharp theme:stock\">\r\npublic class NoteImage\r\n{\r\n\tpublic string Url { get; set; } = string.Empty;\r\n\tpublic string ThumbnailUrl { get; set; } = string.Empty;\r\n\tpublic long ImageSize { get; set; } = 0L;\r\n}\r\n<\/pre>\n<h4>Defining the database context<\/h4>\n<p>In order to keep the functions for accessing the database in a distinct place, we will add a NoteContext class. This will use the <em>Settings<\/em> defined above.<\/p>\n<pre>\r\npublic class NoteContext\r\n{\r\n    private readonly IMongoDatabase _database = null;\r\n\r\n    public NoteContext(IOptions&lt;Settings&gt; settings)\r\n    {\r\n        var client = new MongoClient(settings.Value.ConnectionString);\r\n        if (client != null)\r\n            _database = client.GetDatabase(settings.Value.Database);\r\n    }\r\n\r\n    public IMongoCollection&lt;Note&gt; Notes\r\n    {\r\n        get\r\n        {\r\n            return _database.GetCollection&lt;Note&gt;(&quot;Note&quot;);\r\n        }\r\n    }\r\n}\r\n<\/pre>\n<h4>Adding the repository<\/h4>\n<p>Using a repository interface, we will implement the functions needed to manage the Notes. These will also use Dependency Injection (DI) to be easily access from the application (e.g. controller section): <\/p>\n<pre>\r\npublic interface INoteRepository\r\n{\r\n\tTask&lt;IEnumerable&lt;Note&gt;&gt; GetAllNotes();\r\n\tTask&lt;Note&gt; GetNote(string id);\r\n\r\n\t\/\/ query after multiple parameters\r\n\tTask&lt;IEnumerable&lt;Note&gt;&gt; GetNote(string bodyText, DateTime updatedFrom, long headerSizeLimit);\r\n\r\n\t\/\/ add new note document\r\n\tTask AddNote(Note item);\r\n\r\n\t\/\/ remove a single document \/ note\r\n\tTask&lt;bool&gt; RemoveNote(string id);\r\n\r\n\t\/\/ update just a single document \/ note\r\n\tTask&lt;bool&gt; UpdateNote(string id, string body);\r\n\r\n\t\/\/ demo interface - full document update\r\n\tTask&lt;bool&gt; UpdateNoteDocument(string id, string body);\r\n\r\n\t\/\/ should be used with high cautious, only in relation with demo setup\r\n\tTask&lt;bool&gt; RemoveAllNotes();\r\n}\r\n<\/pre>\n<p>The access to database will be asynchronous. We are using here the new driver, which offers a full async stack. <\/p>\n<p>Just as an example: to get all the Notes, we make an async request:<\/p>\n<pre>\r\npublic async Task&lt;IEnumerable&lt;Note&gt;&gt; GetAllNotes()\r\n{\r\n    var documents = await _context.Notes.Find(_ =&gt; true).ToListAsync();\r\n    return documents;\r\n}\r\n<\/pre>\n<p>Here is the full implementation, for all basic CRUD operations:<\/p>\n<pre>\r\npublic class NoteRepository : INoteRepository\r\n{\r\n\tprivate readonly NoteContext _context = null;\r\n\r\n\tpublic NoteRepository(IOptions&lt;Settings&gt; settings)\r\n\t{\r\n\t\t_context = new NoteContext(settings);\r\n\t}\r\n\r\n\tpublic async Task&lt;IEnumerable&lt;Note&gt;&gt; GetAllNotes()\r\n\t{\r\n\t\ttry\r\n\t\t{\r\n\t\t\treturn await _context.Notes\r\n\t\t\t\t\t.Find(_ =&gt; true).ToListAsync();\r\n\t\t}\r\n\t\tcatch (Exception ex)\r\n\t\t{\r\n\t\t\t\/\/ log or manage the exception\r\n\t\t\tthrow ex;\r\n\t\t}\r\n\t}\r\n\r\n\t\/\/ query after Id or InternalId (BSonId value)\r\n\t\/\/\r\n\tpublic async Task&lt;Note&gt; GetNote(string id)\r\n\t{\r\n\t\ttry\r\n\t\t{\r\n\t\t\tObjectId internalId = GetInternalId(id);\r\n\t\t\treturn await _context.Notes\r\n\t\t\t\t\t\t\t.Find(note =&gt; note.Id == id \r\n\t\t\t\t\t\t\t\t\t|| note.InternalId == internalId)\r\n\t\t\t\t\t\t\t.FirstOrDefaultAsync();\r\n\t\t}\r\n\t\tcatch (Exception ex)\r\n\t\t{\r\n\t\t\t\/\/ log or manage the exception\r\n\t\t\tthrow ex;\r\n\t\t}\r\n\t}\r\n\r\n\t\/\/ query after body text, updated time, and header image size\r\n\t\/\/\r\n\tpublic async Task&lt;IEnumerable&lt;Note&gt;&gt; GetNote(string bodyText, DateTime updatedFrom, long headerSizeLimit)\r\n\t{\r\n\t\ttry\r\n\t\t{\r\n\t\t\tvar query = _context.Notes.Find(note =&gt; note.Body.Contains(bodyText) &amp;&amp;\r\n\t\t\t\t\t\t\t\t   note.UpdatedOn &gt;= updatedFrom &amp;&amp;\r\n\t\t\t\t\t\t\t\t   note.HeaderImage.ImageSize &lt;= headerSizeLimit);\r\n\r\n\t\t\treturn await query.ToListAsync();\r\n\t\t}\r\n\t\tcatch (Exception ex)\r\n\t\t{\r\n\t\t\t\/\/ log or manage the exception\r\n\t\t\tthrow ex;\r\n\t\t}\r\n\t}\r\n\r\n\tprivate ObjectId GetInternalId(string id)\r\n\t{\r\n\t\tObjectId internalId;\r\n\t\tif (!ObjectId.TryParse(id, out internalId))\r\n\t\t\tinternalId = ObjectId.Empty;\r\n\r\n\t\treturn internalId;\r\n\t}\r\n\t\r\n\tpublic async Task AddNote(Note item)\r\n\t{\r\n\t\ttry\r\n\t\t{\r\n\t\t\tawait _context.Notes.InsertOneAsync(item);\r\n\t\t}\r\n\t\tcatch (Exception ex)\r\n\t\t{\r\n\t\t\t\/\/ log or manage the exception\r\n\t\t\tthrow ex;\r\n\t\t}\r\n\t}\r\n\r\n\tpublic async Task&lt;bool&gt; RemoveNote(string id)\r\n\t{\r\n\t\ttry\r\n\t\t{\r\n\t\t\tDeleteResult actionResult \r\n\t\t\t\t= await _context.Notes.DeleteOneAsync(\r\n\t\t\t\t\tBuilders&lt;Note&gt;.Filter.Eq(&quot;Id&quot;, id));\r\n\r\n\t\t\treturn actionResult.IsAcknowledged \r\n\t\t\t\t&amp;&amp; actionResult.DeletedCount &gt; 0;\r\n\t\t}\r\n\t\tcatch (Exception ex)\r\n\t\t{\r\n\t\t\t\/\/ log or manage the exception\r\n\t\t\tthrow ex;\r\n\t\t}\r\n\t}\r\n\r\n\tpublic async Task&lt;bool&gt; UpdateNote(string id, string body)\r\n\t{\r\n\t\tvar filter = Builders&lt;Note&gt;.Filter.Eq(s =&gt; s.Id, id);\r\n\t\tvar update = Builders&lt;Note&gt;.Update\r\n\t\t\t\t\t\t.Set(s =&gt; s.Body, body)\r\n\t\t\t\t\t\t.CurrentDate(s =&gt; s.UpdatedOn);\r\n\r\n\t\ttry\r\n\t\t{\r\n\t\t\tUpdateResult actionResult \r\n\t\t\t\t= await _context.Notes.UpdateOneAsync(filter, update);\r\n\r\n\t\t\treturn actionResult.IsAcknowledged\r\n\t\t\t\t&amp;&amp; actionResult.ModifiedCount &gt; 0;\r\n\t\t}\r\n\t\tcatch (Exception ex)\r\n\t\t{\r\n\t\t\t\/\/ log or manage the exception\r\n\t\t\tthrow ex;\r\n\t\t}\r\n\t}\r\n\r\n\tpublic async Task&lt;bool&gt; UpdateNote(string id, Note item)\r\n\t{\r\n\t\ttry\r\n\t\t{\r\n\t\t\tReplaceOneResult actionResult \r\n\t\t\t\t= await _context.Notes\r\n\t\t\t\t\t\t\t\t.ReplaceOneAsync(n =&gt; n.Id.Equals(id)\r\n\t\t\t\t\t\t\t\t\t\t, item\r\n\t\t\t\t\t\t\t\t\t\t, new UpdateOptions { IsUpsert = true });\r\n\t\t\treturn actionResult.IsAcknowledged\r\n\t\t\t\t&amp;&amp; actionResult.ModifiedCount &gt; 0;\r\n\t\t}\r\n\t\tcatch (Exception ex)\r\n\t\t{\r\n\t\t\t\/\/ log or manage the exception\r\n\t\t\tthrow ex;\r\n\t\t}\r\n\t}\r\n\r\n\t\/\/ Demo function - full document update\r\n\tpublic async Task&lt;bool&gt; UpdateNoteDocument(string id, string body)\r\n\t{\r\n\t\tvar item = await GetNote(id) ?? new Note();\r\n\t\titem.Body = body;\r\n\t\titem.UpdatedOn = DateTime.Now;\r\n\r\n\t\treturn await UpdateNote(id, item);\r\n\t}\r\n\r\n\tpublic async Task&lt;bool&gt; RemoveAllNotes()\r\n\t{\r\n\t\ttry\r\n\t\t{\r\n\t\t\tDeleteResult actionResult \r\n\t\t\t\t= await _context.Notes.DeleteManyAsync(new BsonDocument());\r\n\r\n\t\t\treturn actionResult.IsAcknowledged\r\n\t\t\t\t&amp;&amp; actionResult.DeletedCount &gt; 0;\r\n\t\t}\r\n\t\tcatch (Exception ex)\r\n\t\t{\r\n\t\t\t\/\/ log or manage the exception\r\n\t\t\tthrow ex;\r\n\t\t}\r\n\t}\r\n}\r\n<\/pre>\n<p>In order to access NoteRepository using DI model, we add a new line in ConfigureServices<\/p>\n<pre>\r\nservices.AddTransient&lt;INoteRepository, NoteRepository&gt;();\r\n<\/pre>\n<p>where:<\/p>\n<ul>\n<li>Transient: Created each time.<\/li>\n<li>Scoped: Created only once per request.<\/li>\n<li>Singleton: Created the first time they are requested. Each subsequent request uses the instance that was created the first time.<\/li>\n<\/ul>\n<h4>Adding the main controller<\/h4>\n<p>First we present the main controller. It provides all the CRUD interfaces, available to external applications.<br \/>\nThe <em>Get<\/em> actions have <em>NoCache<\/em> directive, to ensure web clients make always requests to the server. <\/p>\n<pre>\r\n[Produces(&quot;application\/json&quot;)]\r\n[Route(&quot;api\/[controller]&quot;)]\r\npublic class NotesController : Controller\r\n{\r\n\tprivate readonly INoteRepository _noteRepository;\r\n\r\n\tpublic NotesController(INoteRepository noteRepository)\r\n\t{\r\n\t\t_noteRepository = noteRepository;\r\n\t}\r\n\r\n\t[NoCache]\r\n\t[HttpGet]\r\n\tpublic async Task&lt;IEnumerable&lt;Note&gt;&gt; Get()\r\n\t{\r\n\t\treturn await _noteRepository.GetAllNotes();\r\n\t}\r\n\r\n\t\/\/ GET api\/notes\/5 - retrieves a specific note using either Id or InternalId (BSonId)\r\n\t[HttpGet(&quot;{id}&quot;)]\r\n\tpublic async Task&lt;Note&gt; Get(string id)\r\n\t{\r\n\t\treturn await _noteRepository.GetNote(id) ?? new Note();\r\n\t}\r\n\r\n\t\/\/ GET api\/notes\/text\/date\/size\r\n\t\/\/ ex: http:\/\/localhost:53617\/api\/notes\/Test\/2018-01-01\/10000\r\n\t[NoCache]\r\n\t[HttpGet(template: &quot;{bodyText}\/{updatedFrom}\/{headerSizeLimit}&quot;)]\r\n\tpublic async Task&lt;IEnumerable&lt;Note&gt;&gt; Get(string bodyText, \r\n\t\t\t\t\t\t\t\t\t\t\t DateTime updatedFrom, \r\n\t\t\t\t\t\t\t\t\t\t\t long headerSizeLimit)\r\n\t{\r\n\t\treturn await _noteRepository.GetNote(bodyText, updatedFrom, headerSizeLimit) \r\n\t\t\t\t\t?? new List&lt;Note&gt;();\r\n\t}\r\n\r\n\t\/\/ POST api\/notes - creates a new note\r\n\t[HttpPost]\r\n\tpublic void Post([FromBody] NoteParam newNote)\r\n\t{\r\n\t\t_noteRepository.AddNote(new Note\r\n\t\t\t\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\t\t\t\tId = newNote.Id,\r\n\t\t\t\t\t\t\t\t\t\tBody = newNote.Body,\r\n\t\t\t\t\t\t\t\t\t\tCreatedOn = DateTime.Now,\r\n\t\t\t\t\t\t\t\t\t\tUpdatedOn = DateTime.Now,\r\n\t\t\t\t\t\t\t\t\t\tUserId = newNote.UserId\r\n\t\t\t\t\t\t\t\t\t});\r\n\t}\r\n\r\n\t\/\/ PUT api\/notes\/5 - updates a specific note\r\n\t[HttpPut(&quot;{id}&quot;)]\r\n\tpublic void Put(string id, [FromBody]string value)\r\n\t{\r\n\t\t_noteRepository.UpdateNoteDocument(id, value);\r\n\t}\r\n\r\n\t\/\/ DELETE api\/notes\/5 - deletes a specific note\r\n\t[HttpDelete(&quot;{id}&quot;)]\r\n\tpublic void Delete(string id)\r\n\t{\r\n\t\t_noteRepository.RemoveNote(id);\r\n\t}\r\n}\r\n<\/pre>\n<h4>Adding the admin controller<\/h4>\n<p>This will be a controller dedicated to administrative tasks (we use to initialize the database with some dummy data). In real projects, we should very cautiously use such interface. For development only and quick testing purpose, this approach may be convenient. <\/p>\n<p>To use it, we will just add the url in the browser. Running the code below, the full setup will be automatically created (e.g. new database, new collection, sample records). We can use either <a href=\"http:\/\/localhost:5000\/api\/system\/init\">http:\/\/localhost:5000\/api\/system\/init<\/a> (when using IIS) or <a href=\"http:\/\/localhost:53617\/api\/system\/init\">http:\/\/localhost:53617\/api\/system\/init<\/a> (when using IIS Express, enabled as default on this sample project). We could even extend the idea, adding more commands. However, as mentioned above, these kind of scenarios should be used just for development, and be never deployed to a production environment. <\/p>\n<pre>\r\n[Route(&quot;api\/[controller]&quot;)]\r\npublic class SystemController : Controller\r\n{\r\n\tprivate readonly INoteRepository _noteRepository;\r\n\r\n\tpublic SystemController(INoteRepository noteRepository)\r\n\t{\r\n\t\t_noteRepository = noteRepository;\r\n\t}\r\n\r\n\t\/\/ Call an initialization - api\/system\/init\r\n\t[HttpGet(&quot;{setting}&quot;)]\r\n\tpublic string Get(string setting)\r\n\t{\r\n\t\tif (setting == &quot;init&quot;)\r\n\t\t{\r\n\t\t\t_noteRepository.RemoveAllNotes();\r\n\t\t\tvar name = _noteRepository.CreateIndex();\r\n\r\n\t\t\t_noteRepository.AddNote(new Note()\r\n\t\t\t{\r\n\t\t\t\tId = &quot;1&quot;,\r\n\t\t\t\tBody = &quot;Test note 1&quot;,\r\n\t\t\t\tUpdatedOn = DateTime.Now,\r\n\t\t\t\tUserId = 1,\r\n\t\t\t\tHeaderImage = new NoteImage\r\n\t\t\t\t{\r\n\t\t\t\t\tImageSize = 10,\r\n\t\t\t\t\tUrl = &quot;http:\/\/localhost\/image1.png&quot;,\r\n\t\t\t\t\tThumbnailUrl = &quot;http:\/\/localhost\/image1_small.png&quot;\r\n\t\t\t\t}\r\n\t\t\t});\r\n\r\n\t\t\t_noteRepository.AddNote(new Note()\r\n\t\t\t{\r\n\t\t\t\tId = &quot;2&quot;,\r\n\t\t\t\tBody = &quot;Test note 2&quot;,\r\n\t\t\t\tUpdatedOn = DateTime.Now,\r\n\t\t\t\tUserId = 1,\r\n\t\t\t\tHeaderImage = new NoteImage\r\n\t\t\t\t{\r\n\t\t\t\t\tImageSize = 13,\r\n\t\t\t\t\tUrl = &quot;http:\/\/localhost\/image2.png&quot;,\r\n\t\t\t\t\tThumbnailUrl = &quot;http:\/\/localhost\/image2_small.png&quot;\r\n\t\t\t\t}\r\n\t\t\t});\r\n\r\n\t\t\t_noteRepository.AddNote(new Note()\r\n\t\t\t{\r\n\t\t\t\tId = &quot;3&quot;,\r\n\t\t\t\tBody = &quot;Test note 3&quot;,\r\n\t\t\t\tUpdatedOn = DateTime.Now,\r\n\t\t\t\tUserId = 1,\r\n\t\t\t\tHeaderImage = new NoteImage\r\n\t\t\t\t{\r\n\t\t\t\t\tImageSize = 14,\r\n\t\t\t\t\tUrl = &quot;http:\/\/localhost\/image3.png&quot;,\r\n\t\t\t\t\tThumbnailUrl = &quot;http:\/\/localhost\/image3_small.png&quot;\r\n\t\t\t\t}\r\n\t\t\t});\r\n\r\n\t\t\t_noteRepository.AddNote(new Note()\r\n\t\t\t{\r\n\t\t\t\tId = &quot;4&quot;,\r\n\t\t\t\tBody = &quot;Test note 4&quot;,\r\n\t\t\t\tUpdatedOn = DateTime.Now,\r\n\t\t\t\tUserId = 1,\r\n\t\t\t\tHeaderImage = new NoteImage\r\n\t\t\t\t{\r\n\t\t\t\t\tImageSize = 15,\r\n\t\t\t\t\tUrl = &quot;http:\/\/localhost\/image4.png&quot;,\r\n\t\t\t\t\tThumbnailUrl = &quot;http:\/\/localhost\/image4_small.png&quot;\r\n\t\t\t\t}\r\n\t\t\t});\r\n\r\n\t\t\treturn &quot;Database NotesDb was created, and collection 'Notes' was filled with 4 sample items&quot;;\r\n\t\t}\r\n\r\n\t\treturn &quot;Unknown&quot;;\r\n\t}\r\n}\r\n<\/pre>\n<h4>Launch settings<\/h4>\n<p>In order to have a quick display of the values, once the project will run, please update the file <strong>launchSettings.json<\/strong>.<\/p>\n<p><img class=\"img-responsive wp-post-image lazyload \" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" data-src=\"https:\/\/qappdesign.com\/wp-content\/uploads\/2016\/10\/Image-001-1.jpg\" alt=\"sketch\" sizes=\"(max-width: 955px) 100vw, 390px\"><noscript><img class=\"img-responsive wp-post-image\" src=\"https:\/\/i0.wp.com\/qappdesign.com\/wp-content\/uploads\/2016\/10\/Image-001-1.jpg?w=960&#038;ssl=1\" alt=\"sketch\" sizes=\"(max-width: 955px) 100vw, 390px\" data-recalc-dims=\"1\"><\/noscript><\/p>\n<p>Here is the full file content, pointing by default to api\/notes url. <\/p>\n<pre>\r\n{\r\n  \"iisSettings\": {\r\n    \"windowsAuthentication\": false,\r\n    \"anonymousAuthentication\": true,\r\n    \"iisExpress\": {\r\n      \"applicationUrl\": \"http:\/\/localhost:53617\/\",\r\n      \"sslPort\": 0\r\n    }\r\n  },\r\n  \"profiles\": {\r\n    \"IIS Express\": {\r\n      \"commandName\": \"IISExpress\",\r\n      \"launchBrowser\": true,\r\n      \"launchUrl\": \"api\/notes\",\r\n      \"environmentVariables\": {\r\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\r\n      }\r\n    },\r\n    \"NotebookAppApi\": {\r\n      \"commandName\": \"Project\",\r\n      \"launchBrowser\": true,\r\n      \"launchUrl\": \"http:\/\/localhost:5000\/api\/notes\",\r\n      \"environmentVariables\": {\r\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\r\n      }\r\n    }\r\n  }\r\n}\r\n<\/pre>\n<h4>Running the project<\/h4>\n<p>Before running the project, please make sure the <strong>MongoDB is running<\/strong> (either as an Windows Service, or via console application, as presented above).<\/p>\n<p>Run first the initialization link:<br \/>\n<a href=\"http:\/\/localhost:53617\/api\/system\/init\">http:\/\/localhost:53617\/api\/system\/init<\/a><\/p>\n<p>and then run the default application link<br \/>\n<a href=\"http:\/\/localhost:53617\/api\/notes\">http:\/\/localhost:53617\/api\/notes<\/a><\/p>\n<p><img src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" data-src=\"https:\/\/qappdesign.com\/code\/wp-content\/uploads\/2017\/11\/MongoDB-DOTNETCORE-WebApi-Query.jpg\" alt=\"\"  class=\"lazyload \" \/><noscript><img src=\"https:\/\/i0.wp.com\/qappdesign.com\/code\/wp-content\/uploads\/2017\/11\/MongoDB-DOTNETCORE-WebApi-Query.jpg?w=960&#038;ssl=1\" alt=\"\"  data-recalc-dims=\"1\" \/><\/noscript><\/p>\n<h4>Use Robo 3T<\/h4>\n<p>Using <a href=\"https:\/\/robomongo.org\/\" target=\"_blank\">Robo 3T<\/a> we could check the actual entries inside the database. Connecting to the database, using the credentials, we could see all records.<\/p>\n<p>Even if the unique id has the name <em>_id<\/em>, the MongoDb .NET Driver maps it to our variable <em>InternalId<\/em> using the tag <em>[BsonId]<\/em>.<\/p>\n<p><img src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" data-src=\"https:\/\/qappdesign.com\/code\/wp-content\/uploads\/2017\/11\/MongoDB-ROBO3T-WebApi-Query.jpg\" alt=\"\"  class=\"lazyload \" \/><noscript><img src=\"https:\/\/i0.wp.com\/qappdesign.com\/code\/wp-content\/uploads\/2017\/11\/MongoDB-ROBO3T-WebApi-Query.jpg?w=960&#038;ssl=1\" alt=\"\"  data-recalc-dims=\"1\" \/><\/noscript><\/p>\n<h4>Running project on GitHub<\/h4>\n<p>Full source for this example is available on GitHub -> <a href=\"https:\/\/github.com\/fpetru\/WebApiMongoDB\" target=\"_blank\">https:\/\/github.com\/fpetru\/WebApiMongoDB<\/a><\/p>\n<h4>Allowing Cross Domain Calls (CORS)<\/h4>\n<p>Being different applications, running on separate domains, all calls back to ASP.NET WebAPI site are effectively cross domain calls. With Angular 2, there is first a pre-flight request, before the actual request, (an OPTIONS request). Doing this pre-check, we verify first that cross domain calls are allowed (CORS).<\/p>\n<p>I have enabled CORS by applying two changes:<\/p>\n<ul>\n<li>First register CORS functionality in ConfigureServices() of Startup.cs:<\/li>\n<pre>\r\n public void ConfigureServices(IServiceCollection services) \r\n {\r\n      \/\/ Add service and create Policy with options \r\n      services.AddCors(options =&gt; { options.AddPolicy(&quot;CorsPolicy&quot;, \r\n                                      builder =&gt; builder.AllowAnyOrigin() \r\n                                                        .AllowAnyMethod() \r\n                                                        .AllowAnyHeader() \r\n                                                        .AllowCredentials()); \r\n                                  }); \r\n      \/\/ .... \r\n\r\n      services.AddMvc(); \r\n }\r\n<\/pre>\n<li>and then enable the policy globally to every request in the application by calling <strong>app.useCors()<\/strong> in the Configure()method of Startup, before <strong>UseMVC<\/strong>.<\/li>\n<pre>\r\n public void Configure(IApplicationBuilder app) \r\n { \r\n    \/\/ ... \r\n\r\n    \/\/ global policy, if assigned here (it could be defined individually for each controller) \r\n    app.UseCors(&quot;CorsPolicy&quot;); \r\n\r\n    \/\/ ... \r\n\r\n    \/\/ We define UseCors() BEFORE UseMvc, below just a partial call\r\n    app.UseMvc(routes =&gt; {\r\n }\r\n<\/pre>\n<\/ul>\n<p>Even if this could be further and more selective applied, the rest of the article remains unchanged.<\/p>\n<h4>Fully update the MongoDB documents<\/h4>\n<p>Initially the sample project included only selective update of the properties. Using <em>ReplaceOneAsync<\/em> we could update the full document. <em>Upsert<\/em> creates the document, in case it doesn&#8217;t already exist. <\/p>\n<pre>\r\npublic async Task&lt;ReplaceOneResult&gt; UpdateNote(string id, Note item)\r\n{\r\n     return await _context.Notes\r\n                          .ReplaceOneAsync(n =&gt; n.Id.Equals(id)\r\n                                            , item\r\n                                            , new UpdateOptions { IsUpsert = true });\r\n} \r\n<\/pre>\n<h4>Test the update<\/h4>\n<p>To be able to test the update, I have used <a href=\"https:\/\/www.getpostman.com\/\" target=\"_blank\"><em>Postman<\/em><\/a>. It is an excellent tool to test APIs.<\/p>\n<p>I have selected the command type <em>POST<\/em>, then entered the local URL, and added a new Header (<em>Content-Type<\/em> as <em>application\/json<\/em>). <\/p>\n<p><img class=\"img-responsive wp-post-image lazyload \" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" data-src=\"https:\/\/qappdesign.com\/wp-content\/uploads\/2016\/11\/ASP.NET-Core-WebAPI-Set-header.jpg\" alt=\"ASP.NET Core WebAPI Set-header\" sizes=\"(max-width: 708px) 100vw, 390px\"><noscript><img class=\"img-responsive wp-post-image\" src=\"https:\/\/i0.wp.com\/qappdesign.com\/wp-content\/uploads\/2016\/11\/ASP.NET-Core-WebAPI-Set-header.jpg?w=960&#038;ssl=1\" alt=\"ASP.NET Core WebAPI Set-header\" sizes=\"(max-width: 708px) 100vw, 390px\" data-recalc-dims=\"1\"><\/noscript><\/p>\n<p>And then set the Body as <em>raw<\/em> and updated a dummy value.<br \/>\n<img class=\"img-responsive wp-post-image lazyload \" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" data-src=\"https:\/\/qappdesign.com\/wp-content\/uploads\/2016\/11\/ASP.NET-Core-WebAPI-Make-the-request.jpg\" alt=\"ASP.NET Core WebAPI Make the request\" \/><noscript><img class=\"img-responsive wp-post-image\" src=\"https:\/\/i0.wp.com\/qappdesign.com\/wp-content\/uploads\/2016\/11\/ASP.NET-Core-WebAPI-Make-the-request.jpg?w=960&#038;ssl=1\" alt=\"ASP.NET Core WebAPI Make the request\" data-recalc-dims=\"1\" \/><\/noscript><\/p>\n<p>Using RoboMongo we can see the value updated.<br \/>\n<img class=\"img-responsive wp-post-image lazyload \" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" data-src=\"https:\/\/qappdesign.com\/wp-content\/uploads\/2016\/11\/MongoDB-Updated-document-1.jpg\" alt=\"MongoDB .NET Driver Updated document in Robomongo\"  \/><noscript><img class=\"img-responsive wp-post-image\" src=\"https:\/\/i0.wp.com\/qappdesign.com\/wp-content\/uploads\/2016\/11\/MongoDB-Updated-document-1.jpg?w=960&#038;ssl=1\" alt=\"MongoDB .NET Driver Updated document in Robomongo\"  data-recalc-dims=\"1\" \/><\/noscript><\/p>\n<h4>Exception management<\/h4>\n<p>Starting with C# 5.0 <em>async<\/em>\u00a0and\u00a0<em>await<\/em>\u00a0were introduced into the language to simplify using the\u00a0Task Parallel Library. We can simply use a\u00a0try\/catch\u00a0block to catch an exception, like so:<\/p>\n<pre>\r\npublic async Task&lt;IEnumerable&lt;Note&gt;&gt; GetAllNotes()\r\n{\r\n    try\r\n    {\r\n        return await _context.Notes.Find(_ =&gt; true).ToListAsync();\r\n    }\r\n    catch (Exception ex)\r\n    {\r\n        \/\/ log or manage the exception\r\n        throw ex;\r\n    }\r\n}\r\n<\/pre>\n<p>In this way we handle a faulted task by asynchronously wait for it to complete, using <em>await<\/em>. This will rethrow the original stored exception. <\/p>\n<p>Initially I have used <em>void<\/em> as return. Changing the return type, the exception raised in the async method will get safely saved in the returning Task instance. When we await the faulty method, the exception saved in the Task will get rethrown with its full stack trace preserved.<\/p>\n<pre>\r\npublic async Task AddNote(Note item)\r\n{\r\n    try\r\n    {\r\n        await _context.Notes.InsertOneAsync(item);\r\n    }\r\n    catch (Exception ex)\r\n    {\r\n        \/\/ log or manage the exception\r\n        throw ex;\r\n    }\r\n}\r\n<\/pre>\n<h4>Model binding of JSON POSTs in .NET Core<\/h4>\n<p>Model binding is the conversion of the raw HTTP request into the arguments for an action method invocation on a controller.<br \/>\n<em>[FromBody]<\/em> parameter tells the .net core framework to use the <em>content-type<\/em> header of the request, to decide which of the configured IInputFormatters to use for model binding.<\/p>\n<p>By default, when you call AddMvc() in Startup.cs, a JSON formatte (JsonInputFormatter) is automatically configured. You could add additional formatters if you need to, for example to bind XML to an object.<\/p>\n<pre>\r\n[HttpPost]\r\npublic void Post([FromBody] NoteParam newNote)\r\n<\/pre>\n<p>To add a new Note, we need first to set Content-Type, to be <em>application\/json<\/em>.<br \/>\n<img loading=\"lazy\" src=\"data:image\/svg+xml,%3Csvg xmlns='http:\/\/www.w3.org\/2000\/svg' viewBox='0 0 1061 162'%3E%3C\/svg%3E\" data-src=\"https:\/\/qappdesign.com\/code\/wp-content\/uploads\/2017\/11\/MongoDB-POSTMAN-WebApi-Post01.jpg\" alt=\"\" width=\"1061\" height=\"162\" class=\"alignnone size-full wp-image-859 lazyload \" data-sizes=\"auto\" data-srcset=\"https:\/\/i0.wp.com\/qappdesign.com\/code\/wp-content\/uploads\/2017\/11\/MongoDB-POSTMAN-WebApi-Post01.jpg?w=1061&amp;ssl=1 1061w, https:\/\/i0.wp.com\/qappdesign.com\/code\/wp-content\/uploads\/2017\/11\/MongoDB-POSTMAN-WebApi-Post01.jpg?resize=300%2C46&amp;ssl=1 300w, https:\/\/i0.wp.com\/qappdesign.com\/code\/wp-content\/uploads\/2017\/11\/MongoDB-POSTMAN-WebApi-Post01.jpg?resize=768%2C117&amp;ssl=1 768w, https:\/\/i0.wp.com\/qappdesign.com\/code\/wp-content\/uploads\/2017\/11\/MongoDB-POSTMAN-WebApi-Post01.jpg?resize=1024%2C156&amp;ssl=1 1024w, https:\/\/i0.wp.com\/qappdesign.com\/code\/wp-content\/uploads\/2017\/11\/MongoDB-POSTMAN-WebApi-Post01.jpg?resize=940%2C144&amp;ssl=1 940w\" sizes=\"(max-width: 960px) 100vw, 960px\" \/><noscript><img loading=\"lazy\" src=\"https:\/\/i0.wp.com\/qappdesign.com\/code\/wp-content\/uploads\/2017\/11\/MongoDB-POSTMAN-WebApi-Post01.jpg?resize=960%2C147&#038;ssl=1\" alt=\"\" width=\"960\" height=\"147\" class=\"alignnone size-full wp-image-859\" srcset=\"https:\/\/i0.wp.com\/qappdesign.com\/code\/wp-content\/uploads\/2017\/11\/MongoDB-POSTMAN-WebApi-Post01.jpg?w=1061&amp;ssl=1 1061w, https:\/\/i0.wp.com\/qappdesign.com\/code\/wp-content\/uploads\/2017\/11\/MongoDB-POSTMAN-WebApi-Post01.jpg?resize=300%2C46&amp;ssl=1 300w, https:\/\/i0.wp.com\/qappdesign.com\/code\/wp-content\/uploads\/2017\/11\/MongoDB-POSTMAN-WebApi-Post01.jpg?resize=768%2C117&amp;ssl=1 768w, https:\/\/i0.wp.com\/qappdesign.com\/code\/wp-content\/uploads\/2017\/11\/MongoDB-POSTMAN-WebApi-Post01.jpg?resize=1024%2C156&amp;ssl=1 1024w, https:\/\/i0.wp.com\/qappdesign.com\/code\/wp-content\/uploads\/2017\/11\/MongoDB-POSTMAN-WebApi-Post01.jpg?resize=940%2C144&amp;ssl=1 940w\" sizes=\"(max-width: 960px) 100vw, 960px\" data-recalc-dims=\"1\" \/><\/noscript><\/p>\n<p>Then we send a JSON object, and we successfully add a new Note. Since UserId is not set, the object will take the default value.<br \/>\n<img loading=\"lazy\" src=\"data:image\/svg+xml,%3Csvg xmlns='http:\/\/www.w3.org\/2000\/svg' viewBox='0 0 1058 207'%3E%3C\/svg%3E\" data-src=\"https:\/\/qappdesign.com\/code\/wp-content\/uploads\/2017\/11\/MongoDB-POSTMAN-WebApi-Post02.jpg\" alt=\"\" width=\"1058\" height=\"207\" class=\"alignnone size-full wp-image-858 lazyload \" data-sizes=\"auto\" data-srcset=\"https:\/\/i0.wp.com\/qappdesign.com\/code\/wp-content\/uploads\/2017\/11\/MongoDB-POSTMAN-WebApi-Post02.jpg?w=1058&amp;ssl=1 1058w, https:\/\/i0.wp.com\/qappdesign.com\/code\/wp-content\/uploads\/2017\/11\/MongoDB-POSTMAN-WebApi-Post02.jpg?resize=300%2C59&amp;ssl=1 300w, https:\/\/i0.wp.com\/qappdesign.com\/code\/wp-content\/uploads\/2017\/11\/MongoDB-POSTMAN-WebApi-Post02.jpg?resize=768%2C150&amp;ssl=1 768w, https:\/\/i0.wp.com\/qappdesign.com\/code\/wp-content\/uploads\/2017\/11\/MongoDB-POSTMAN-WebApi-Post02.jpg?resize=1024%2C200&amp;ssl=1 1024w, https:\/\/i0.wp.com\/qappdesign.com\/code\/wp-content\/uploads\/2017\/11\/MongoDB-POSTMAN-WebApi-Post02.jpg?resize=940%2C184&amp;ssl=1 940w\" sizes=\"(max-width: 960px) 100vw, 960px\" \/><noscript><img loading=\"lazy\" src=\"https:\/\/i0.wp.com\/qappdesign.com\/code\/wp-content\/uploads\/2017\/11\/MongoDB-POSTMAN-WebApi-Post02.jpg?resize=960%2C188&#038;ssl=1\" alt=\"\" width=\"960\" height=\"188\" class=\"alignnone size-full wp-image-858\" srcset=\"https:\/\/i0.wp.com\/qappdesign.com\/code\/wp-content\/uploads\/2017\/11\/MongoDB-POSTMAN-WebApi-Post02.jpg?w=1058&amp;ssl=1 1058w, https:\/\/i0.wp.com\/qappdesign.com\/code\/wp-content\/uploads\/2017\/11\/MongoDB-POSTMAN-WebApi-Post02.jpg?resize=300%2C59&amp;ssl=1 300w, https:\/\/i0.wp.com\/qappdesign.com\/code\/wp-content\/uploads\/2017\/11\/MongoDB-POSTMAN-WebApi-Post02.jpg?resize=768%2C150&amp;ssl=1 768w, https:\/\/i0.wp.com\/qappdesign.com\/code\/wp-content\/uploads\/2017\/11\/MongoDB-POSTMAN-WebApi-Post02.jpg?resize=1024%2C200&amp;ssl=1 1024w, https:\/\/i0.wp.com\/qappdesign.com\/code\/wp-content\/uploads\/2017\/11\/MongoDB-POSTMAN-WebApi-Post02.jpg?resize=940%2C184&amp;ssl=1 940w\" sizes=\"(max-width: 960px) 100vw, 960px\" data-recalc-dims=\"1\" \/><\/noscript><\/p>\n<h4>Query on Embedded \/ Nested Documents<\/h4>\n<p>CSharp driver of MongoDB makes the query on the embedded documents easy. In the example below we mix two filters, one comparing the date from the main document, and one comparing a long member of the nested class. <\/p>\n<pre>\r\nnote.UpdatedOn &gt;= updatedFrom &amp;&amp; note.HeaderImage.ImageSize &lt;= headerSizeLimit\r\n<\/pre>\n<p>Accessing the application using IIS Express, we could use the <strong>Get<\/strong> function that contain all the notes with <em>Test<\/em>, created after <em>2018-01-01<\/em> and size smaller than <em>10000<\/em>. Once the project is started, this function could be called by using the next URL in the browser: <a href=\"http:\/\/localhost:53617\/api\/notes\/Test\/2018-01-01\/10000\" rel=\"noopener\" target=\"_blank\">http:\/\/localhost:53617\/api\/notes\/Test\/2018-01-01\/10000<\/a>.<\/p>\n<h4>At the end<\/h4>\n<p>Hope this helped ! Let me know if you have questions or some things needs to be updated.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>What&#8217;s about Problem \/ solution format brings an easier understanding on how to build things, giving an immediate feedback. Starting from this idea, the blog post I will present step by step how to build a web application to store your ideas in an easy way, adding text notes, either from desktop or mobile, with few characteristics: run fast, save on the fly whatever you write, and be reasonably reliable and secure. This article will implement just the backend, WebApi and the database access, in the most simple way. A couple of updates done to the original article Following Peter&#8217;s comment, I have simplified the documents returned, see HttpGet requests Following Luciano&#8217;s comment, I have extend the update function, making update of the full MongoDB documents at once, not just to some of the properties. There is a new section below, describing this change Trying to read from Angular 2, find the article here, I have ran into CORS problems. An error message was displayed &#8220;No &#8216;Access-Control-Allow-Origin&#8217; header is present on the requested resource&#8221;. I have added a new section to describe the solution. I have updated the project to .NET Core 1.1 as well to MongoDB .NET Driver 2.4 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":51,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"image","meta":{"spay_email":"","jetpack_publicize_message":"","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true},"categories":[13,7,8],"tags":[4,17,5,3],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v18.0 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Using MongoDB .NET Driver with .NET Core WebAPI - Cloud, Data and Integrations<\/title>\n<meta name=\"description\" content=\"How to build step by step an ASP.NET Core WebAPI (.NET Core 2.0) with latest MongoDB driver. The project supports all requests to MongoDB asynchronously.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/qappdesign.com\/code\/using-mongodb-with-net-core-webapi\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Using MongoDB .NET Driver with .NET Core WebAPI - Cloud, Data and Integrations\" \/>\n<meta property=\"og:description\" content=\"How to build step by step an ASP.NET Core WebAPI (.NET Core 2.0) with latest MongoDB driver. The project supports all requests to MongoDB asynchronously.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/qappdesign.com\/code\/using-mongodb-with-net-core-webapi\/\" \/>\n<meta property=\"og:site_name\" content=\"Cloud, Data and Integrations\" \/>\n<meta property=\"article:published_time\" content=\"2018-07-23T08:30:47+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2018-10-17T19:44:41+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/qappdesign.com\/code\/wp-content\/uploads\/2016\/10\/Image-003.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"898\" \/>\n\t<meta property=\"og:image:height\" content=\"333\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"twitter:card\" content=\"summary\" \/>\n<meta name=\"twitter:creator\" content=\"@qappdesign\" \/>\n<meta name=\"twitter:site\" content=\"@QAppDesign\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Petru Faurescu\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"18 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebSite\",\"@id\":\"https:\/\/qappdesign.com\/code\/#website\",\"url\":\"https:\/\/qappdesign.com\/code\/\",\"name\":\"QualityAppDesign\",\"description\":\"with Petru Faurescu\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/qappdesign.com\/code\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/qappdesign.com\/code\/using-mongodb-with-net-core-webapi\/#primaryimage\",\"inLanguage\":\"en-US\",\"url\":\"https:\/\/i0.wp.com\/qappdesign.com\/code\/wp-content\/uploads\/2016\/10\/Image-003.jpg?fit=898%2C333&ssl=1\",\"contentUrl\":\"https:\/\/i0.wp.com\/qappdesign.com\/code\/wp-content\/uploads\/2016\/10\/Image-003.jpg?fit=898%2C333&ssl=1\",\"width\":898,\"height\":333},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/qappdesign.com\/code\/using-mongodb-with-net-core-webapi\/#webpage\",\"url\":\"https:\/\/qappdesign.com\/code\/using-mongodb-with-net-core-webapi\/\",\"name\":\"Using MongoDB .NET Driver with .NET Core WebAPI - Cloud, Data and Integrations\",\"isPartOf\":{\"@id\":\"https:\/\/qappdesign.com\/code\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/qappdesign.com\/code\/using-mongodb-with-net-core-webapi\/#primaryimage\"},\"datePublished\":\"2018-07-23T08:30:47+00:00\",\"dateModified\":\"2018-10-17T19:44:41+00:00\",\"author\":{\"@id\":\"https:\/\/qappdesign.com\/code\/#\/schema\/person\/54db90dc6fe846cfd4c5a9544d93b75a\"},\"description\":\"How to build step by step an ASP.NET Core WebAPI (.NET Core 2.0) with latest MongoDB driver. The project supports all requests to MongoDB asynchronously.\",\"breadcrumb\":{\"@id\":\"https:\/\/qappdesign.com\/code\/using-mongodb-with-net-core-webapi\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/qappdesign.com\/code\/using-mongodb-with-net-core-webapi\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/qappdesign.com\/code\/using-mongodb-with-net-core-webapi\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/qappdesign.com\/code\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Using MongoDB .NET Driver with .NET Core WebAPI\"}]},{\"@type\":\"Person\",\"@id\":\"https:\/\/qappdesign.com\/code\/#\/schema\/person\/54db90dc6fe846cfd4c5a9544d93b75a\",\"name\":\"Petru Faurescu\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/qappdesign.com\/code\/#personlogo\",\"inLanguage\":\"en-US\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/84fb359a4e3d583dbea5a34bd5566956?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/84fb359a4e3d583dbea5a34bd5566956?s=96&d=mm&r=g\",\"caption\":\"Petru Faurescu\"},\"description\":\"Product lead, software developer &amp; architect\",\"sameAs\":[\"https:\/\/qappdesign.com\/code\",\"https:\/\/www.linkedin.com\/in\/petrufaurescu\/\",\"https:\/\/twitter.com\/@qappdesign\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Using MongoDB .NET Driver with .NET Core WebAPI - Cloud, Data and Integrations","description":"How to build step by step an ASP.NET Core WebAPI (.NET Core 2.0) with latest MongoDB driver. The project supports all requests to MongoDB asynchronously.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/qappdesign.com\/code\/using-mongodb-with-net-core-webapi\/","og_locale":"en_US","og_type":"article","og_title":"Using MongoDB .NET Driver with .NET Core WebAPI - Cloud, Data and Integrations","og_description":"How to build step by step an ASP.NET Core WebAPI (.NET Core 2.0) with latest MongoDB driver. The project supports all requests to MongoDB asynchronously.","og_url":"https:\/\/qappdesign.com\/code\/using-mongodb-with-net-core-webapi\/","og_site_name":"Cloud, Data and Integrations","article_published_time":"2018-07-23T08:30:47+00:00","article_modified_time":"2018-10-17T19:44:41+00:00","og_image":[{"width":898,"height":333,"url":"https:\/\/qappdesign.com\/code\/wp-content\/uploads\/2016\/10\/Image-003.jpg","type":"image\/jpeg"}],"twitter_card":"summary","twitter_creator":"@qappdesign","twitter_site":"@QAppDesign","twitter_misc":{"Written by":"Petru Faurescu","Est. reading time":"18 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebSite","@id":"https:\/\/qappdesign.com\/code\/#website","url":"https:\/\/qappdesign.com\/code\/","name":"QualityAppDesign","description":"with Petru Faurescu","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/qappdesign.com\/code\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"ImageObject","@id":"https:\/\/qappdesign.com\/code\/using-mongodb-with-net-core-webapi\/#primaryimage","inLanguage":"en-US","url":"https:\/\/i0.wp.com\/qappdesign.com\/code\/wp-content\/uploads\/2016\/10\/Image-003.jpg?fit=898%2C333&ssl=1","contentUrl":"https:\/\/i0.wp.com\/qappdesign.com\/code\/wp-content\/uploads\/2016\/10\/Image-003.jpg?fit=898%2C333&ssl=1","width":898,"height":333},{"@type":"WebPage","@id":"https:\/\/qappdesign.com\/code\/using-mongodb-with-net-core-webapi\/#webpage","url":"https:\/\/qappdesign.com\/code\/using-mongodb-with-net-core-webapi\/","name":"Using MongoDB .NET Driver with .NET Core WebAPI - Cloud, Data and Integrations","isPartOf":{"@id":"https:\/\/qappdesign.com\/code\/#website"},"primaryImageOfPage":{"@id":"https:\/\/qappdesign.com\/code\/using-mongodb-with-net-core-webapi\/#primaryimage"},"datePublished":"2018-07-23T08:30:47+00:00","dateModified":"2018-10-17T19:44:41+00:00","author":{"@id":"https:\/\/qappdesign.com\/code\/#\/schema\/person\/54db90dc6fe846cfd4c5a9544d93b75a"},"description":"How to build step by step an ASP.NET Core WebAPI (.NET Core 2.0) with latest MongoDB driver. The project supports all requests to MongoDB asynchronously.","breadcrumb":{"@id":"https:\/\/qappdesign.com\/code\/using-mongodb-with-net-core-webapi\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/qappdesign.com\/code\/using-mongodb-with-net-core-webapi\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/qappdesign.com\/code\/using-mongodb-with-net-core-webapi\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/qappdesign.com\/code\/"},{"@type":"ListItem","position":2,"name":"Using MongoDB .NET Driver with .NET Core WebAPI"}]},{"@type":"Person","@id":"https:\/\/qappdesign.com\/code\/#\/schema\/person\/54db90dc6fe846cfd4c5a9544d93b75a","name":"Petru Faurescu","image":{"@type":"ImageObject","@id":"https:\/\/qappdesign.com\/code\/#personlogo","inLanguage":"en-US","url":"https:\/\/secure.gravatar.com\/avatar\/84fb359a4e3d583dbea5a34bd5566956?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/84fb359a4e3d583dbea5a34bd5566956?s=96&d=mm&r=g","caption":"Petru Faurescu"},"description":"Product lead, software developer &amp; architect","sameAs":["https:\/\/qappdesign.com\/code","https:\/\/www.linkedin.com\/in\/petrufaurescu\/","https:\/\/twitter.com\/@qappdesign"]}]}},"jetpack_featured_media_url":"https:\/\/i0.wp.com\/qappdesign.com\/code\/wp-content\/uploads\/2016\/10\/Image-003.jpg?fit=898%2C333&ssl=1","jetpack_publicize_connections":[],"jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p82xvM-a","_links":{"self":[{"href":"https:\/\/qappdesign.com\/code\/wp-json\/wp\/v2\/posts\/10"}],"collection":[{"href":"https:\/\/qappdesign.com\/code\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/qappdesign.com\/code\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/qappdesign.com\/code\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/qappdesign.com\/code\/wp-json\/wp\/v2\/comments?post=10"}],"version-history":[{"count":99,"href":"https:\/\/qappdesign.com\/code\/wp-json\/wp\/v2\/posts\/10\/revisions"}],"predecessor-version":[{"id":558,"href":"https:\/\/qappdesign.com\/code\/wp-json\/wp\/v2\/posts\/10\/revisions\/558"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/qappdesign.com\/code\/wp-json\/wp\/v2\/media\/51"}],"wp:attachment":[{"href":"https:\/\/qappdesign.com\/code\/wp-json\/wp\/v2\/media?parent=10"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/qappdesign.com\/code\/wp-json\/wp\/v2\/categories?post=10"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/qappdesign.com\/code\/wp-json\/wp\/v2\/tags?post=10"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}