Search code examples
asp.netapimodel-view-controllerasp.net-apicontroller

How do I call my own API from a View? ASP.NET MVC


I have an API that I've created for user registration / authentication, and similar operations. Example post method:

    [AllowAnonymous]
    [HttpPost("authenticate")]
    public IActionResult Authenticate([FromBody]AuthenticateModel model)
    {
        var user = _userService.Authenticate(model.Username, model.Password);

        if (user == null)
            return BadRequest(new { message = "Username or password is incorrect" });

        var tokenHandler = new JwtSecurityTokenHandler();
        var key = Encoding.ASCII.GetBytes(_appSettings.Secret);
        var tokenDescriptor = new SecurityTokenDescriptor
        {
            Subject = new ClaimsIdentity(new Claim[]
            {
                new Claim(ClaimTypes.Name, user.Id.ToString()),
                new Claim(ClaimTypes.Role, user.Role)
            }),
            Expires = DateTime.UtcNow.AddDays(7),
            SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
        };
        var token = tokenHandler.CreateToken(tokenDescriptor);
        var tokenString = tokenHandler.WriteToken(token);

        // return basic user info and authentication token
        return Ok(new
        {
            user.Id,
            user.Username,
            Token = tokenString,

        });

I now need my front-end to implement my API. So I'd like to call this API from a View. For example, say I want to create a simple login page:

<div class="row">
<div class="col-md-12">
    <form method="post" action="">
        <div asp-validation-summary="All" class="text-danger"></div>
        <div class="form-group">
            <label asp-for="Username"></label>
            <input asp-for="Username" class="form-control" />
            <span asp-validation-for="Username" class="text-danger"></span>
        </div>
        <div class="form-group">
            <label asp-for="Password"></label>
            <input asp-for="Password" class="form-control" />
            <span asp-validation-for="Password" class="text-danger"></span>
        </div>
        <button type="submit" class="btn btn-primary">Login</button>
    </form>
</div>

How would I now call the authenticate post method for this login form? As I have a controller which is the API controller, and I have a controller which is the action controller, for the users.

File structure if needed: File structure


Solution

  • Calling your own web action can be done in mainly two ways:

    • Native HTML form submission.
    • AJAX

    Native submit reloads your entire page. And address will be changed to the URL or your web action. Typically used as a search function, like:

    <form asp-controller="Search" asp-action="Blogs" method="get">
        <input type="text" name="question" />
        <input type="submit" />
    </form>
    

    When the user submit the form with clicking the submit button, the browser will be redirect to /search/blogs?question=textHeInput.

    To prevent page refreshing, you can submit a request with pure JavaScript. Which called AJAX.

    https://en.wikipedia.org/wiki/Ajax_(programming)

    For example:

    // Require jQuery:
    $.post('/authenticate', { "yourPropertyName" : "yourPropertyValue" }, function(response) {
        // Do something after the request. Access response like this:
        alert(response.Username);
    });
    

    And server responded username will shown.