使用ASP.NET Web Api構建基於REST風格的服務實戰系列教程【六】——實現資源間的關聯


系列導航地址http://www.cnblogs.com/fzrain/p/3490137.html

前言

這一篇文章主要介紹一下資源間的關聯——例如在學生和課程之間就存在這樣的關聯:每一個課程都會有多個學生來選,如何獲取這些有關聯的信息?如何實現選課的業務?對於客戶端應該怎么來調用呢?下面給出解決方案:

配置對應的路由

對於上面的需求,我們可以先定制一個URI模板:”api/courses/courseid/students/{userName}“,如果我們打算查詢所有選了courseId為5的學生,那么客戶端就應該發送Get請求”api/courses/5/students/”.如果我們打算為用戶名為”TaiseerJoudeh“的學生選擇課程CourseId為5的課程,那么就應該發送Post請求”api/courses/5/students/TaiseerJoudeh“。

為了實現上面說的,我們首先要在”WebApiConfig“中添加如下一條路由信息:

config.Routes.MapHttpRoute(
    name: "Enrollments",
    routeTemplate: "api/courses/{courseId}/students/{userName}",
    defaults: new { controller = "Enrollments", userName = RouteParameter.Optional }
);

可以看到在這里courseId是必選的,而userName是可選的

創建響應的控制器

正如上面路由配置的,我們應該有一個“EnrollmentsController”,在這個控制器中我們應該包含2個方法:Get用來返回對應的學生信息,Post用來實現學生選課,下面上代碼:

public class EnrollmentsController : BaseApiController
    {
        public EnrollmentsController(ILearningRepository repo)
            : base(repo)
        {
        }

        public IEnumerable<StudentBaseModel> Get(int courseId)
        {
            IQueryable<Student> query;

            query = TheRepository.GetEnrolledStudentsInCourse(courseId).OrderBy(s => s.LastName);

            var totalCount = query.Count();

            System.Web.HttpContext.Current.Response.Headers.Add("X-InlineCount", totalCount.ToString());

            var results = query
                       
                        .ToList()
                        .Select(s => TheModelFactory.Create(s));

            return results;

        }

        public HttpResponseMessage Post(int courseId, [FromUri]string userName, [FromBody]Enrollment enrollment)
        {
            try
            {

                if (!TheRepository.CourseExists(courseId)) return Request.CreateErrorResponse(HttpStatusCode.BadRequest, "Could not find Course");

                var student = TheRepository.GetStudent(userName);
                if (student == null) return Request.CreateErrorResponse(HttpStatusCode.BadRequest, "Could not find Student");

                var result = TheRepository.EnrollStudentInCourse(student.Id, courseId, enrollment);

                if (result == 1)
                {
                    return Request.CreateResponse(HttpStatusCode.Created);
                }
                else if (result == 2)
                {
                    return Request.CreateResponse(HttpStatusCode.NotModified, "Student already enrolled in this course");
                }

                return Request.CreateResponse(HttpStatusCode.BadRequest);

            }
            catch (Exception ex)
            {
                return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ex);
            }
        }
    }

在Post方法中我們使用了FormURL和FormBody的特性,這樣就表明我們將從請求的什么地方來獲得參數(從URL中獲取UserName,從Body中獲取enrollment),對於enrollment對象來說只要包含一個日期即可(詳情參看系列數據庫及模型的構建:http://www.cnblogs.com/fzrain/p/3491804.html),同時我們要發送“courseId”以及“UserName”。

下面測試一下我們的Post方法:我們打算為“TaiseerJoudeh”選擇CourseId為5的課程:

image

在之前已經介紹過,我們使用http狀態碼來響應請求的不同結果(從這次開始看的朋友可以參考:http://www.cnblogs.com/fzrain/p/3520442.html),請求成功則返回201(Resource Created),如果該選課記錄已存在則返回304(Not modified)

總結

對於資源間的關聯就這么點到為止了,具體的應用在以后慢慢感悟了。對於之前給出的Get方法,有一個明顯的瑕疵:對於大量的數據,服務器會全部返回給客戶端,這是非常不好的,那么下一章我們就來實現分頁。

本章源碼:http://yun.baidu.com/share/link?shareid=1470307710&uk=17559114&third=0


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM