65.9K
CodeProject 正在变化。 阅读更多。
Home

MongoDB 中 CRUD 操作的 RESTful WEB API

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.96/5 (14投票s)

2016年1月14日

CPOL

7分钟阅读

viewsIcon

52672

在本文中,我们将为项目中的学生资源创建 Web API 以进行操作和执行 CRUD 操作。

引言

在我之前的 文章 中,我们使用 MongoDB shell 命令进行了 CRUD 操作。正如我承诺的,这篇文章将分享如何使用 .NET 驱动程序创建用于 MongoDB 中 CRUD 操作的 RESTful Web API。

正如您已经知道的,MongoDB 是现代 Web 应用程序的未来,对于 .NET 开发者来说,掌握 MongoDB 驱动程序非常重要,因此本文是我在这方面的努力。希望您会喜欢并赞赏我的工作。

在本文中,我们将为项目中的学生资源创建 Web API 以进行操作和执行 CRUD 操作。

应用程序架构

我们将构建的应用程序非常简单,我们将使用 MongoDB 作为我们的数据库,并将为 MongoDB 上的数据操作创建 .NET Web API,并且将有一个测试客户端来使用我们的 Web API。

数据库设置

在 MongoDB 中创建数据库非常容易。您可以参考我之前的文章了解更多详细信息。我们只需要编写以下命令来创建名为 studentsDB 的数据库和名为 students 的集合

use studentsDB
 db.students.insert({ "_id" : 1, "RollNo" : "rol1", "Name" : "vikas", "Class" : "12th" })

上面的命令将创建集合并在其中插入一条记录。

为了简单起见,我只创建一个名为 'students' 的集合,并将在此集合上执行所有操作。

创建 Web API

打开您的 visual studio 以创建新项目,我使用的是 Visual Studio 2013 社区版。您可以使用 visual studio 2013 或更高版本进行此操作。

步骤

1. 选择 Web -> ASP.NET MVC 4 Web Application。

2. 项目名称:Students.API

3. 选择 Web API 并点击 OK。

4. 这就是 Visual Studio 的强大之处;只需几次点击,我们就可以准备好一个虚拟的 Web API 项目。默认情况下,控制器包含 Home 和 Value Controller,您可以选择删除它们,因为我们将创建自己的 student controller 来管理客户端调用。但在此之前,还有其他事情需要我们处理。这只是我们充满乐趣的旅程的开始。

创建数据模型

Data Model 是我们解决方案中包含应用程序模型的项目。

步骤

1. 向您的解决方案添加一个新的类库项目,并将其命名为 Students.DataModel

2. 删除默认的Class1.cs,因为我们不需要它。

3. 创建一个名为Models的文件夹,并在此处添加一个名为Student.cs的类。这个类将成为我们 students 集合中 Student 实体的模型类。

4. 同样,创建一个名为GenericRepository的文件夹,并将Repository.cs类添加到其中。

5. 以同样的方式再创建一个名为UnitOfWork的文件夹,并将UnitOfWork.cs添加到其中。

6. 在向 Student 类添加任何代码之前,我们需要将*官方 MongoDB* 驱动程序的引用添加到我们的 Data Model 项目,以便我们可以与 MongoDB 通信。

7. 右键单击 Data Model 项目,选择 Manage NuGet Packages 并搜索 MongoDB。

8. 将Student类的代码替换为以下代码

using MongoDB.Bson.Serialization.Attributes;

namespace Students.DataModel.Models
{
    public class Student
    {
        [BsonElement("_id")]
        public int StudentID { get; set; }
        public string RollNo { get; set; }
        public string Name { get; set; }
        public string Class { get; set; }
        
    }
}

这里的[BsonElement("_id")]属性告诉 MongoDB StudentID将用作唯一键,即 student 集合中的 _id。其余的非常简单。无需解释。

9. 将Repository类的代码替换为以下代码

using MongoDB.Driver;
using MongoDB.Driver.Builders;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

namespace Students.DataModel.Repository
{
    public class Repository<T>  where T : class
    {
        private MongoDatabase _database;
        private string _tableName;
        private MongoCollection<T> _collection;

        // constructor to initialise database and table/collection  
        public Repository(MongoDatabase db, string tblName)
        {
            _database = db;
            _tableName = tblName;
            _collection = _database.GetCollection<T>(tblName);
        }


        /// <summary>
        /// Generic Get method to get record on the basis of id
        /// </summary>
        /// <param name="i"></param>
        /// <returns></returns>
        public T Get(int i)
        {
           return _collection.FindOneById(i);
 
        }

       /// <summary>
       /// Get all records 
       /// </summary>
       /// <returns></returns>
        public IQueryable<T> GetAll()
        {
            MongoCursor<T> cursor =_collection.FindAll();
            return cursor.AsQueryable<T>();

        }

        /// <summary>
        /// Generic add method to insert enities to collection 
        /// </summary>
        /// <param name="entity"></param>
        public void Add(T entity)
        {
            _collection.Insert(entity);
        }

        /// <summary>
        /// Generic delete method to delete record on the basis of id
        /// </summary>
        /// <param name="queryExpression"></param>
        /// <param name="id"></param>
        public  void Delete(Expression<Func<T, int>> queryExpression, int id)
        {
            var query = Query<T>.EQ(queryExpression, id);
            _collection.Remove(query);
        }

        /// <summary>
        ///  Generic update method to delete record on the basis of id
        /// </summary>
        /// <param name="queryExpression"></param>
        /// <param name="id"></param>
        /// <param name="entity"></param>
        public void Update(Expression<Func<T, int>> queryExpression, int id,T entity)
        {
            var query = Query<T>.EQ(queryExpression, id);
            _collection.Update(query, Update<T>.Replace(entity));
        }

    }
}

以上类不言自明,它是一个通用的类,用于处理各种集合和不同实体上的操作。我们创建了五个通用方法来对任何集合执行 CRUD 操作。

第一个方法将在构造函数中初始化的集合中根据提供的整数 ID 作为参数来获取一个文档。

第二个方法将从集合中获取所有记录作为可查询对象。请注意FindAll()方法如何返回 MongoCursor,然后该 MongoCursor 将返回实体作为可查询对象。

第三个方法,顾名思义,将添加一个作为参数接收的实体到指定的集合中。

第四个方法将根据提供的 ID 删除记录。首先,它将查询集合以查找具有提供 ID 的文档,然后删除该文档。

第五个方法将根据 ID 查询集合,然后更新(用提供的​​新文档替换找到的文档)。旧文档的 ID 应与提供的​​新文档匹配。

10. 现在是时候用以下代码替换UnitOfWork类了

using MongoDB.Driver;
using Students.DataModel.Models;
using Students.DataModel.Repository;
using System.Configuration;

namespace Students.DataModel.UnitOfWork
{
    public class UnitOfWork
    {
        private MongoDatabase _database;

        protected Repository<Student> _students;

        public UnitOfWork()
        {
            var connectionString = ConfigurationManager.AppSettings["MongoDBConectionString"];
            var client = new MongoClient(connectionString);
            var server = client.GetServer();
            var databaseName = ConfigurationManager.AppSettings["MongoDBDatabaseName"];
            _database = server.GetDatabase(databaseName);
        }
        public Repository<Student> Students
        {
            get
            {
                if (_students == null)
                    _students = new Repository<Student>(_database, "students");

                return _students;
            }
        }
    }
}

在这里,我们创建了UnitOfWork类,它建立了与 MongoDB 服务器以及我们要对其执行 CRUD 操作的数据库的连接,并且它将简单地在其属性中返回 Repository。

11. 在Students.API项目的 web config 的appSettings部分添加新的键值对。

<appSettings>
    <add key="MongoDBConectionString" value="mongodb://:27017" />
    <add key="MongoDBDatabaseName" value="studentsDB"/>

注意:您可能需要通过向项目添加适当的命名空间和引用来解决任何编译错误。

创建服务

现在我们需要服务来处理StudentsUnitOfWork并调用相应的方法与数据库通信并将结果返回给我们的控制器。

步骤

1. 向您的解决方案添加一个新的类库项目,命名为Students.Services

2. 添加一个名为IStudentService的接口和一个名为 StudentService 的类,该类将继承添加到Students.Services的接口。

3. 用以下代码替换接口代码

using Students.DataModel.Models;
using System.Linq;

namespace Students.Services
{
    public interface IStudentService
    {
        void Insert(Student student);
        Student Get(int i);
        IQueryable<Student> GetAll();
        void Delete(int id);
        void Update(Student student);
    }
}

4. 现在是时候向您的StudentService类添加代码了,因为它将继承上述接口,我们将必须为接口的所有方法提供主体。让我们用以下代码替换服务类代码

using Students.DataModel.Models;
using Students.DataModel.UnitOfWork;
using System.Linq;

namespace Students.Services
{
    public class StudentService : IStudentService
    {
        private readonly StudentsUnitOfWork _sUnitOfwork;

        public StudentService()
        {
            _sUnitOfwork = new StudentsUnitOfWork();
        }

        public Student Get(int i)
        {
           return _sUnitOfwork.Students.Get(i);
        }

        public IQueryable<Student> GetAll()
        {
            return _sUnitOfwork.Students.GetAll();
        }

        public void Delete(int id)
        {
            _sUnitOfwork.Students.Delete(s => s.StudentID,id);
        }

        public void Insert(Student student)
        {
            _sUnitOfwork.Students.Add(student);
        }

        public void Update(Student student)
        {
            _sUnitOfwork.Students.Update(s => s.StudentID,student.StudentID, student);
        }

    }
}

让我们来理解一下我们用上面的代码试图实现的目标。

我们创建了一个StudentsUnitOfWork的私有对象,并在构造函数中对其进行了初始化。在我们第一个方法Get中,我们调用了StudentsUnitOfWork属性的 students(StudentsRepository)的通用Get方法,该方法将返回Student对象。同样,第二个方法将返回 student 类的 IQueryable 对象。insert 方法非常简单。我们发送一个新的 student 对象以添加到StudentsUnitOfWorkDeleteUpdate方法在概念上是相似的,因为在这两个方法中都使用了 lambda 表达式,分别用于删除和更新记录。

更新 Web API

让我提醒您,我们的 Web API 项目附带默认的 Home 和 Value Controller,我们需要创建自己的名为 StudentController 的控制器来创建 RESTful Web API。所以以下是步骤

1. 右键单击 Students.API 项目中的 controllers 文件夹,然后选择 new controller。

2. 用以下代码替换控制器的默认代码

using System.Linq;
using System.Web.Http;
using Students.DataModel.Models;
using Students.Services;
using System.Net.Http;
using System.Net;


namespace Students.API.Controllers
{
    public class StudentsController : ApiController
    {
        private readonly IStudentService _studentService;

        public StudentsController()
        {
            _studentService = new StudentService();
        }

// GET api/student/id
        public HttpResponseMessage Get(int id)
        {

            var student= _studentService.Get(id);
            if(student!=null)
                return Request.CreateResponse(HttpStatusCode.OK, student);
            return Request.CreateErrorResponse(HttpStatusCode.NotFound, "Student not found for provided id.");
        }

        public HttpResponseMessage GetAll()
        {
            var students= _studentService.GetAll();
            if (students.Any())
                return Request.CreateResponse(HttpStatusCode.OK, students);
            return Request.CreateErrorResponse(HttpStatusCode.NotFound, "No students found.");
        }
     
        public void Post([FromBody]Student student)
        {
            _studentService.Insert(student);

        }
        public void Delete(int id)
        {
            _studentService.Delete(id);
        }
        public void Put([FromBody]Student student)
        {
            _studentService.Update(student);
        }
    }
}

我们创建了五个方法,或者我们可以说五个 API 来处理 CRUD 操作。在构造函数中,我们创建了StudentService的对象,并在控制器的​​方法中,我们将调用服务方法来处理客户端请求。

第一个方法将根据 URL 中提供的 ID 调用服务来获取记录。

第二个方法将调用服务来获取所有记录。

第三个方法将向服务发布新记录以插入数据库。

第四个方法将调用服务来从数据库中删除记录。

第五个方法将调用服务来更新数据库中的记录。

以上所有方法都是 HTTP VERBS,Web API 将根据 VERB 的名称自行识别请求。

现在我们的 API 准备好进行测试了,保存解决方案并构建解决方案。但是我们将如何测试我们的 API 呢?不用担心,我们不需要为此创建一个功能齐全的客户端。右键单击 Web API 项目,选择 Manage NuGet Packages 并搜索 test client,然后安装“A simple Test Client for ASP.NET Web API”。

它将安装一个测试客户端来测试我们的 API。是的,我们现在可以测试了,但在运行应用程序之前,请确保您的 MongoDB 服务器正在运行。

测试 Web API

测试 Web API 的步骤

1. 运行您的应用程序。

2. ASP.NET Web API 主页将在浏览器中加载,点击 API 链接查看您创建的 API 列表。

3. 点击 APIs 链接进行测试。如果您点击任何一个链接,它将重定向到您点击的 API 的文档页面,您将在屏幕的右角看到一个 Test API 按钮。点击 Test API 按钮来测试 API。

结论

我们创建了简单的 RESTful Web API 来与我们的资源进行交互。我们在后端使用了 MongoDB 作为我们的数据库。我的例子非常简单,因此我试图保持事物简单,我甚至试图保持我们的应用程序结构非常简单,我没有在应用程序中实现依赖注入、安全和错误处理。您可以在 GitHub 上找到源代码。感谢您的阅读

© . All rights reserved.