1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

ASP.NET Web API

Discussion in 'ASP.NET' started by MinalS, Apr 19, 2015.

  1. MinalS

    MinalS New Member

    Joined:
    Jul 8, 2014
    Messages:
    138
    Likes Received:
    30
    Trophy Points:
    0
    The REST services make use of the SOAP protocol for the client server technology. REST services are always stateless. The HTTP GET, POST, PUT and DELETE are used in the REST services. The GET is used to access the resources, POST is used to add resources, PUT is used to update resources, and DELETE to delete resources.

    Service creation

    ASP.NET Web API belongs to ASP.NET. User needs to create a web application project. Select the Web API from the templates option. The folders and references are added. For the Web API, the Controllers directory is important as it not only has MVC but also Web API controllers and Model directory.

    Defining Model

    User needs to define the type to represent the data to return and modify. The class StudentData is defined. It contains some of the properties as mentioned below:

    Code:
    
    public class StudentData
    {
        public int StudID { get; set; }
        public string name { get; set; }
        public int class { get; set; }
    }
    
    
    Controller creation

    The controller can be added by clicking on Project, Add Controller, Web API 2 Controller. The controller is named as StudentDataController. It is derived from the ApiController. The routing is defined directly by the controller. The HTTP verbs are used for defining them.

    The following code demonstrates the controller in an application.

    Code:
    
    public class StudentDataController : ApiController
    {
        private static List <StudentData> stud;
        static StudentDataController()
        {
            stud = new List <StudentData> ()
            {
                new StudentData { StudID=1, name=’Kelvin’, class=10 },
                new StudentData { StudID=2, name=’Sam’, class=10 },
                new StudentData { StudID=3, name=’Harry’, class=20 },
                new StudentData { StudID=4, name=’Rich’, class=50 },
            };
        }
    }
    
    
    The Get method is created and returns the collection of type IEnumerable<StudentData>

    Code:
    
    public IEnumerable<StudentData>GetStudentData()
    {
        return stud;
    }
    
    
    The PostStudentData adds the StudentData with the parameter to the collection.

    Code:
    
    public void PostStudentData( StudentData value )
    {
        stud.Add(value);
    }
    
    
    The data can be updated using the HTTP PUT request. The PutStudentData method is used to remove the item from the collection. It adds the new item.

    Code:
    
    public void PutStudentData(int id, StudentData value)
    {
        stud.Remove(stud.Where(c=>c.StudID==id).Single());
        stud.Add(value);
    }
    
    
    The HTTP DELETE request is used to delete the stud info.

    Code:
    
    public void DeleteStudentData(int id)
    {
        stud.Remove(stud.Where(c=>c.StudID==id).Single());
    }
    
    
    Error Handling

    The APiController is the base class which defines methods that return objects implementing the IHttpActionResult. The BadRequest method returns BadRequestResult while Ok method returns OkResult.


    Consider the following code to demonstrate the error handling concept.
    Code:
    
    public IHttpActionResult PutStudentData( int id, StudentData value )
    {
        try
        {
            stud.Remove(stud.Where(c=>c.StudID==id).Single());
            stud.Add(value);
            return Ok();
        }
        catch(InvalidOperationException)
        {
            return BadRequest();
        }
    }
    
    
    In the above code, if the id is not found then the InvalidOperationException is thrown. The BadRequestResult object is returned. If the update is possible, then the OkResult is defined.

    Sending GET Requests

    The HttpClient is used to send the HTTP GET request. The System.Net.Http namespace is referred. The GetStringAsync used the HTTP GET request for linking to the web browser. The GetStudentData method is used. The string returned is converted into StudentData array using the JavaScriptSerializer. It is defined in the assembly System.Web.Extensions.

    Code:
    
    private static async Task ReadArray()
    {
        var client = new HttpClient();
        string.response = await client.GetStringAsync("/api/StudentData");
        Console.WriteLine(response);
        var serializer = new JavaScriptSerializer();
        StudentData[ ] stud = serializer.Deserializer<StudentData[ ] >(response);
        
        foreach(StudentData stud1 in stud)
        {
            Console.WriteLine(stud.Name);
        }
    }
    
    
    The ReadArray method is invoked from the Main method. The code is as shown below:

    Code:
    
    static void Main ()
    {
        Console.WriteLine("Waiting");
        Console.Read();
        ReadArray().Wait();
        Console.ReadLine();
    }
    
    Sending POST Requests

    The HTTP POST Request works similar to the GET request. It creates a new object on server side and adds the PostStudentData method. The HTTPClient.PostAsync method is used to send the POST request. The ObjectContent<T> type is used to pass and transform the message. The JSONMediaTypeFormatter is used.

    The following code demonstrates the POST request.

    Code:
    
    private static async Task AddSample()
    {
        var newstudent = new StudentData
        {
            StudID=7,
            name="Kapil",
            class=12
        };
        
        var client = new HttpClient();
        
        HttpContent con = new ObjectContent<StudentData>(
        newStudent, new JsonMediaTypeFormatter());
        
        HttpResponseMessage response = await client.PostAsync("/api/StudentData", con);
        response.EnsureSuccessStatusCode();
        await.ReadArray();
    }
    
    
    In the above code, the student data can be read again by adding the ReadArray and GET request.

    Sending PUT Requests

    The HTTP PUT request is used for updating record. The PutAsJsonAsync method is used. The System.Http.Net.formatting assembly contains the method.

    The following code snippet demonstrates the PUT request.

    Code:
    
    private static async Task UpdateSample()
    {
        var client = new HttpClient();
        var updatestudent = new StudentData
        {
            StudID=3,
            name="Harry",
            class=11
        };
        
        await client.PutAsJsonAsync("/api/StudentData/11", updatestudent);
        await ReadArray();
    }
    
    
    Sending DELETE Requests

    The HTTP DELETE request is used for deletion. The DeleteAsync is used as the method.

    The following code snippet demonstrates the DELETE request.

    Code:
    
    private static async Task DeleteSample()
    {
        try
        {
    
            var client = new HttpClient();
            HttpResponseMessage response=await client.DeleteAsync("/api/StudentData/50");
        
            response.EnsureSuccessStatusCode();
            await ReadArray();
        }
        catch(HttpRequestException ex)
        {
            Console.WriteLine(ex.Message);
        }
    }
    
    
    Addition of HTTP Methods to Actions

    The HTTP GET request maps the GetStudentData method. The HTTP POST request maps the PostStudentData method.

    Code:
    
    public IEnumerable<StudentData> GetStudentData()
    {
        return stud;
    }
    
    public void PostStudentData(StudentData value)
    {
        stud.Add(value);
    }
     
    
    ODATA

    The Web API provides direct support for Open Data Protocol (OData). It provides a CRUD access to the data source. The GET request retrieves collection of entity data. The POST request creates a new entity. PUT request updates the existing entities. DELETE request removes the entity. The OData is created on JSON.

    OData offers more query options as providing the Queryable attribute. It is used as an attribute for the action methods. For returning limited number of entities to the client, the client limits the count using the $top parameter. The $skip allows paging.

    The number of entities to be retrieved is decided by the client. The Queryable attribute helps restrict the limit. The PageSize can be set to a value as an example 30. Once the value is set, the 30 entities are returned.

    Code:
    
    [Queryable (PageSize=30) ]
    
    
    Security using Web API

    User can restrict the access using the format used in ASP.NET Web Forms and ASP.NET MVC. User can select an individual user account option for authentication. It creates a Web API AccountController. The controller is used for defining the methods used to manage the users and passwords.

    Code:
    
    [Authorize]
    public class ValueController: ApiController
    {
        public IEnumerable<string> Get()
        {
            return new string[ ] { "value1", "value2" };
    
        }
    }
    
    
    Account creation

    An account is needed for the user authentication. The OAuth authentication supports the Facebook, Google, twitter accounts directly. The Account controller supports the user creation directly in the database.

    The controller provides a Register method available for the anonymous users. It helps create and enable users. The route to the method is defined through attribute routing. The Microsoft.AspNet.Identity namespace contains the type.

    Code:
    
    [AllowAnonymous]
    [Route("Register")]
    public async Task<IHttpActionResult> Register ( RegisterBindingModel model ) 
    {
        if ( !ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }
    
        IdentityUser user = new IdentityUser
        {
            UserName =model.UserName
        };
        IdentityResult result = await UserManager.CreateAsync(user, model.Password);
        IHttpActionResult error = GetErrorResult ( result );
        if ( error!=null)
        {
            return error;
        }
        return Ok();
    }
    
    private IHttpActionResult GetErrorResult(IdentityResult result)
    {
        if ( result==null)
        {
            return InternalServerError();
        }
        if(!result.Succeeded)
        {
            if(result.Errors!=null)
            {
                foreach(string error in result.Errors)
                {
                    ModelState.AddModelError("", error);
                }
            }
        if(ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }
        return null;
    }
    
    
    Authentication Token creation

    The authentication token requests are defined in the static constructor of the Startup class. The constructor sets the TokenEndPointPath of the OAuthAuthorizationServerOptions to /Token. The provider type defined with the Provider property is of the ApplicationOAuthProvider. The class is created using the template.

    Code:
    
    static Startup()
    {
        PublicClientId = ‘client1’;
        UserManagerFactory = () => new UserManager<IdentityUser>(
        new UserStore<IdentityUser>();
        OAuthOptions = new OAuthAuthroizationServerOptions
        {
            TokenEndPointPath = new PathString(‘/Token’),
            Provider = new ApplicationOAuthProvider(PublicClientId, UserManagerFactory), AuthorizeEndpointPath = new PathString(‘/api/Account/ExternalLogin’),
            AccessTokenExpireTimeSpan = TimeSpan.FromDays(15),
            AllowInsecureHttp = true
        };
    }
    
    Sending an Authenticated call

    User can use the token information for making an authenticated call to the service. The ValuesController is called before creating the token. The token access can be added to the Authorization header using the DefaultRequestHeaders property.

    Code:
    
    private async static void Authenticated()
    {
        dynamic token = await GetToken();
        string valuesUri = "/api/Values";
        var client = new HttpClient();
        client.BaseAddress = new Uri ( baseaddress);
        client.DefaultRequestHeaders.Add("Authorization", string.Format("{0} {1}", token.token_type, token.access_token));
        HttpResponseMessage response = await client.GetAsync(valuesUri);
        Console.WriteLine(response.StatusCode);
        string content = await response.Content.ReadAsStringAsync();
        Console.WriteLine(content);
    }
    
    
    User Information

    The GetUserInfo is uses the information in the form of the UserInfoViewModel object. The properties like UserName, HasRegistered, and LoginProvider are filled by the method implementation.

    In the code below, the FromIdentity is used and ClaimsIdentity represents the identity of the user is checked for retrieving user information.

    Code:
    
    [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer) ]
    [Route("UserInfo")]
    public UserInfoViewModel GetUserInfo()
    {
        ExternalLoginData external = ExternalLoginData.FromIdentity( User.Identity as ClaimsIdentity);
        return new UserInfoViewModel
        {
            UserName = User.Identity.GetUserName(), HasRegsitered = externalLogin == null, LoginProvider = externalLogin!=null ? externalLogin.LoginProvider : null 
        };
    }
    
    
    The request headers for the authorization are added and call the UserInfo request is along with GetAsync.

    Code:
    
    private async static void UserInfo()
    {
        string userInfoUri = "/api/Account/UserInfo";
        var token = await.GetToken();
        HttpClient client = new Uri(baseAddress);
        client.DefaultRequestHeaders.Add("Authorization", string.Format("{0} {1}", token.token_type, token.access_token) );
        
        HttpResponseMessage response = await client.GetAsync(userInfoUri);
        Response.EnsureSuccessStatusCode();
        UserInfo userinfo = await response.Content.ReadAsync<UserInfo>();
        Console.WriteLine("user:{0}, registered:{1}, provider:{2}", userInfo.UserName, userInfo.HasRegistered, userInfo.LoginProvider);
    }
    
    
     
    shabbir likes this.

Share This Page