Search code examples
asp.net-mvcasp.net-web-apihttpwebrequestdotnet-httpclientasp.net-routing

Call web api c# by passing oauth token along with parameter


I'm using custom oauth in web API for authentication. Now i want to call web api method from MVC controller. Web API method:

public class UserController : ApiController
{
    [Authorize(Roles = "Admin")]
    [HttpPost]
    [ActionName("UserById")]
    public IEnumerable GetUserById(string idValue)
    {
        long ID = idValue != "" ? Convert.ToInt64(idValue) : -1;
        using (var db = new DataModelContext())
        {
            IEnumerable query = (from b in db.User.Include(u => u.EmailAddresses).ToList() 
               where b.Id == ID
               select new { b.Id, UserName = b.UserName, b.EmailAddresses }).ToList();

            return query;
        }
    }
}

MVC controller:

public class PagesController : Controller
{
    public ActionResult GetUserById(long id)
    {
        string baseUrl = Common.GetAPIUrl();
        HttpClient client = new HttpClient();
        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        client.BaseAddress = new Uri(baseUrl);
        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", Common.GetoAuth().access_token);

        var values = new JObject();
        values.Add("idValue",id.ToString());

        HttpContent content = new StringContent(values.ToString(), Encoding.UTF8, "application/json");

        HttpResponseMessage response = client.PostAsJsonAsync(baseUrl + "/api/User/UserById", content).Result;

        string resultJSON = response.Content.ReadAsStringAsync().Result;

        return View("UserDetail",resultJson);
    }
}

Some how its not working, i'm not able to rectify issue why its not working. When i'm calling API direct URL from postman its working fine. like http://localhost:55362/api/UserById/2 or http://localhost:55362/api/UserById?idvalue=2. its not working for only httpclient call.


Solution

  • Incase if you still stuck up with this issue. Please do the following to make it work.

    WebApiConfig: Action Api should come above the controller Route

           config.Routes.MapHttpRoute(
               name: "ActionApi",
               routeTemplate: "api/{controller}/{Action}/{id}",
               defaults: new { id = RouteParameter.Optional }
           );
    
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
    

    On the Api Method: Add the "FromBody" attribute to the parameter.

    [Authorize(Roles = "Admin")]
    [HttpPost]
    [ActionName("UserById")]
    public IEnumerable GetUserById([FromBody]string idValue)
    {
        long ID = idValue != "" ? Convert.ToInt64(idValue) : -1;
        using (var db = new DataModelContext())
        {
            IEnumerable query = (from b in db.User.Include(u => u.EmailAddresses).ToList() 
               where b.Id == ID
               select new { b.Id, UserName = b.UserName, b.EmailAddresses }).ToList();
    
            return query;
        }
    }
    

    Let me know if this works