Bit of Technology

  • Archive
  • About Me
    • Advertise
    • Disclaimer
  • Speaking
  • Contact

Building ASP.Net Web API RESTful Service – Part 6

November 25, 2013 By Taiseer Joudeh 11 Comments

Be Sociable, Share!

  • Tweet
  • Email
  • WhatsApp

This is the sixth part of Building ASP.Net Web API RESTful Service Series. The topics we’ll cover are:

  • Building the Database Model using Entity Framework Code First – Part 1.
  • Applying the Repository Pattern for the Data Access Layer – Part 2.
  • Getting started with ASP.Net Web API – Part 3.
  • Implement Model Factory, Dependency Injection and Configuring Formatters – Part 4.
  • Implement HTTP actions POST, PUT, and DELETE In Web API – Part 5.
  • Implement Resources Association – Part 6 (This Post).
  • Implement Resources Pagination – Part 7.
  • Securing Web API – Part 8.
  • Preparing Web API for Versioning – Part 9.
  • Different techniques to Implement Versioning – Part 10.
  • Caching resources using CacheCow and ETag – Part 11.

Update (2014-March-5) Two new posts which cover ASP.Net Web API 2 new features:

  • ASP.NET Web API 2 Attribute Routing.
  • IHttpActionResult as new response type and CORS Support.

Implement Resources Association

In this post we’ll be covering the relationship between resources which is called “Resources Association”, for example there is a relation between each “Course” and “Students” i.e. each course has multiple students enrolled in it. So we can build an absolute URI in the form:”api/courses/courseid/students/{userName}”, so if we want to list all students enrolled in course id 5 our GET request will be as: “api/courses/5/students/”. If we want to enroll student his username is “TaiseerJoudeh” in course id 5 we’ll issue POST request to the URI: ”api/courses/5/students/TaiseerJoudeh” and so on.

To implement this we need add new route in “WebApiConfig” class named “Enrollments” as the code below:

C#
1
2
3
4
5
config.Routes.MapHttpRoute(
        name: "Enrollments",
        routeTemplate: "api/courses/{courseId}/students/{userName}",
        defaults: new { controller = "Enrollments", userName = RouteParameter.Optional }
        );

Notice how is “courseId” parameter is not optional and “userName” parameter is optional.

Now we’ve to add new controller named “EnrollmentsController”, we’ll support two HTTP verbs, GET to list all students in specific class, and POST to enroll student in specific calls, you’ll notice that we’ve implemented pagination for GET method, we’ll cover this topic in the next post. The controller code listed as the below:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
public class EnrollmentsController : BaseApiController
    {
        public EnrollmentsController(ILearningRepository repo)
            : base(repo)
        {
        }
 
        public IEnumerable<StudentBaseMode> Get(int courseId, int page = 0, int pageSize = 10)
        {
            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
            .Skip(pageSize * page)
            .Take(pageSize)
            .ToList()
            .Select(s => TheModelFactory.CreateSummary(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);
            }
        }
    }

In the POST method notice how we’re using FromUri and FromBody attribute to indicate from where we’re getting the values of the request, we’ll get the “userName” from the URI and the “enrollment” object from Request Body. The “enrollment” object will contain the enrollment data only, we could send the “CourseID” and “StudentID” as well, but it makes more sense to get both values from the URI.

To test the POST request we’ll use fiddler to issue a POST request, we want to enroll student “TaiseerJoudeh” in course with ID=5, the request will be as the image below:

FiddlerPostRequest-Enrollments

As we’ve learned before, we will return HTTP status code as a result for this POST operation, if the request is successful we will return 201 (Resource Created), if the student already enrolled in this class we’ll return status code 304 (Not modified).

In the next post we’ll talk about pagination for large results, using manual pagination, and how we return pagination meta-data.

Source code is available on GitHub.

Be Sociable, Share!

  • Tweet
  • Email
  • WhatsApp

Related Posts

  • Integrate Azure AD B2C with ASP.NET MVC Web App – Part 3
  • Secure ASP.NET Web API 2 using Azure AD B2C – Part 2
  • Azure Active Directory B2C Overview and Policies Management – Part 1
  • ASP.NET Identity 2.1 Accounts Confirmation, and Password Policy Configuration – Part 2
  • ASP.NET Identity 2.1 with ASP.NET Web API 2.2 (Accounts Management) – Part 1

Filed Under: ASP.NET, ASP.Net Web API, Entity Framework, Web API Tutorial Tagged With: API, ASP.NET, Entity Framework, Resources Association, REST, RESTful, Tutorial, Web API, Web Service

Comments

  1. bartcalixto says

    January 15, 2014 at 5:21 pm

    How would you architect your code so that you can also ask for students directly without going trougth the course property? like /api/student/studentName ? wouldn’t that make the resource have 2 locations ? how is this implemented?

    Reply
    • tjoudeh says

      February 11, 2014 at 11:19 pm

      Hi, am really sorry for the late reply, there is already route for api/students/{userName} where you can query single student. And thats fine if the same resource have 2 end points while you are doing associations. Hope this answers your question.

      Reply
  2. Moshe says

    February 10, 2014 at 12:00 am

    this Tutorial Is one of the best I ever saw !!!!! you help me allot Thank you !!

    Reply
    • tjoudeh says

      February 10, 2014 at 12:03 am

      Really glad to hear this, good luck in
      working with Web API. And keep tuned for another tutorial covering different areas of Web API.

      Reply
  3. am says

    July 2, 2014 at 9:20 am

    I agreed that it has given me a great start… will convert those to a videos forms to demonstrate at my end.

    Reply
  4. Harleen says

    June 11, 2015 at 2:10 pm

    This tutorial is one of the best available until now. Please share more information on web APIs

    Reply
    • Taiseer Joudeh says

      June 13, 2015 at 2:38 am

      Glad it is useful Harleen, thanks for your comment!

      Reply
  5. randi2160emlall says

    August 21, 2015 at 9:21 pm

    Hey Taiser, i notice that when you post a request to join the group or create association, i am seeing that it says 401 Unauthorized error. can you show an example on how to get the authorization and post it or how to get over this?

    Reply
    • Taiseer Joudeh says

      August 24, 2015 at 11:01 pm

      Hi Randi, this has been for a while 🙁 sorry for not being able to troubleshoot this one 🙁

      Reply
  6. Alok Gupta says

    February 18, 2016 at 9:09 pm

    Hello Dear,

    I am getting the issue “This operation requires IIS integrated pipeline mode.” while using this URL “http://localhost:50688/api/courses/5/students” VS-2012

    Reply
  7. JuinWoo says

    October 29, 2016 at 5:20 pm

    Hey Taiser, During the POST process, “400 Bad Request” is always returned. “result” returns 0. Why is that?

    Reply

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

About Taiseer

Husband, Father, Consultant @ MSFT, Life Time Learner... Read More…

Buy me a coffeeBuy me a coffee

Recent Posts

  • Integrate Azure AD B2C with ASP.NET MVC Web App – Part 3
  • Secure ASP.NET Web API 2 using Azure AD B2C – Part 2
  • Azure Active Directory B2C Overview and Policies Management – Part 1
  • ASP.NET Web API Claims Authorization with ASP.NET Identity 2.1 – Part 5
  • ASP.NET Identity 2.1 Roles Based Authorization with ASP.NET Web API – Part 4

Blog Archives

Recent Posts

  • Integrate Azure AD B2C with ASP.NET MVC Web App – Part 3
  • Secure ASP.NET Web API 2 using Azure AD B2C – Part 2
  • Azure Active Directory B2C Overview and Policies Management – Part 1
  • ASP.NET Web API Claims Authorization with ASP.NET Identity 2.1 – Part 5
  • ASP.NET Identity 2.1 Roles Based Authorization with ASP.NET Web API – Part 4

Tags

AJAX AngularJS API API Versioning ASP.NET Authentication Autherization Server Azure Active Directory B2C Azure AD B2C basic authentication C# CacheCow Client Side Templating Code First Dependency Injection Entity Framework ETag Foursquare API HTTP Caching HTTP Verbs IMDB API IoC Javascript jQuery JSON JSON Web Tokens JWT Model Factory Ninject OAuth OData Pagination Resources Association Resource Server REST RESTful Single Page Applications SPA Token Authentication Tutorial Web API Web API 2 Web API Security Web Service wordpress.com

Search

Copyright © 2022 · eleven40 Pro Theme on Genesis Framework · WordPress · Log in

loading Cancel
Post was not sent - check your email addresses!
Email check failed, please try again
Sorry, your blog cannot share posts by email.