How to call a Non API Controller function using Web API Controller - c#

I have controller, and it's name is "AuthController" which is being inherited by "BaseController". "AuthController" has a parametric constructor as well a method "RegisterFromOutside" that is being used to register the user. Below code work fine for the Non Api Controller.
Code Sample for Non Api Controller:
Now the question is how can I use the API controller to call the same method? and then access it from my mobile application (using the same implementations). Please note that project doesn't have any implementation for API calling yet.
This is when is am getting this error. and the error is
"But when i tried to access the same UserServices from the other Web API application controller with Parametric constructor. It asks me to declare parameter-less constructor. and when i do that it simply don't run the parametric constructor and in return i receive null reference exception."
public class ValuesController : ApiController
{
UserServices _userServices;
public ValuesController(
UserServices userServices)
{
_userServices = userServices;
}
// POST api/values
public void Post([FromBody]RegisterViewModel model)
{
RegisterFromOutside(model);
}
public void RegisterFromOutside(RegisterViewModel model)
{
User user = _userServices.Register(model.Username, model.Password, model.Email);
}
}

You can add API controller in MVC project(right click on folder Controllers, choose Add
--> Controller)
There is method signature in my project, which executes user authorization, you can do the same thing(you can also try to do that in classic non-API controller)
[AllowAnonymous]
[HttpPost]
[Route("api/mobile/users/login")]
public LoginResponseModel Login(LoginRequestModel loginRequestModel)

Related

Cannot use a single class instance to update class variables in Web API controller methods

First time posting here so could be a little vague.
I recently started working on .NET Web API and was trying to create controller class for the API.
In the controller class I wanted to instantiate an object of a class(lets say class GetLabels) whose methods will be used to modify variable of the class(in my case want to modify a dictionary of the GetLabels class which is private).
[Route("api/[controller]")]
[ApiController]
public class ConnectionController : ControllerBase
{
GetLabels getLabels;
public ConnectionController()
{
getLabels = new GetLabels;
}
// Post: api/Connection/
[HttpPost]
public IActionResult BuildLabels()
{
getLabels.Add(key,value);// a public method Add() of class GetLabels adds a key to the dictionary
}
[HttpPost"{id}"]
public IActionResult RemoveLabels()
{
getlabels.Remove(key,value);// a public method Remove() of class GetLabels deletes the previously added key from the dictionary
}
}
When I run the Put methods one after another(first add and then delete), on the second put method I get empty dictionary even though I using the same instance of the class for both the controller methods. What I am doing wrong over here.
The RESTful architecture with Asp.net works in a stateless way.
The server cannot take advantage of any context stored on the server.
The use of the server cache is possible :
Is it possible to create stateful web service in C#?
The life-cycle of controller in .NET Web API is created per request. Every time you call a request from this controller, the following code is executed:
public ConnectionController()
{
getLabels = new GetLabels;
}
In fact, you add the label to one instance of the class, and you want to remove it from another instance.

How to declare a controller function that can only access by another controller function and prevent direct access (.NET Core)

I have a controller function called Resend email. That function should only call by the payment function and should prevent direct access, but when a user in that view user should have the capability to reload that view.
How can I create a controller function to fulfill all these requirements? (.NET Core MVC)
That function should only call by the payment function and should prevent direct access
If you only want to call that method/function from the code of another method(s) instead of exposing it as an action method, you can apply the NonAction attribute to the method, like below.
public IActionResult ConfirmAccount()
{
//...
//code logic here
//...
return ResendEmail();
}
[NonAction]
public IActionResult ResendEmail()
{
//return Ok("success");
//...
Besides, as #CodeCaster mentioned in comment, you can define the function/method in a generic class library etc, rather than in a controller.
If it is necessary to make controller method to access only from another view it is possible to use the following check:
public IActionResult CalculateBallance(int id)
{
// Gets information about the URL of the client's previous request
// that linked to the current URL.
if (String.IsNullOrEmpty(Request.Headers["Referer"]))
{
return NotFound();
}
// TODO: ...
}

ASP.NET Core 2.2 User.Identity has a value in razor but not in controller

I have an asp.net core 2.2 mvc project setup with windows authentication,
my razor layout has this #User.Identity.Name which works great, but in my controller, User.Identity is null! any idea what I am doing wrong?
here's a sample of my controller:
using Microsoft.AspNetCore.Mvc;
using System.Diagnostics;
using UI.Models;
namespace UI.Controllers
{
public class HomeController : Controller
{
string shortName = string.Empty;
public HomeController()
{
shortName = User.Identity.Name;
}
public IActionResult Index()
{
return View();
}
}
}
You cannot access User, HttpContext, or other related properties within the constructor of a controller. That means that you can access these properties only within an actual controller action, like your Index method.
To understand this, you need to understand how these controller properties actually work and how the framework will manage the lifetime of a controller. As you may be aware, controllers are short-lived objects that are created temporarily only for the duration of a single request. That means that they will always execute within the scope of a single request.
By that logic, accessing the user or other properties of the HTTP context should work just fine; and it usually is. However, when you inherit those properties from Controller or ControllerBase, then those don’t magically have a value. Instead, they will be set explicitly by the framework after it creates the controller.
The logic for this is simlar to this:
// create the controller with its dependencies
var controller = CreateController<HomeController>();
// set the controller context
controller.ControllerContext = context;
// invoke action
controller.Index();
So when the object is constructed and the constructor runs, you can access anything that is a direct dependency of the controller, since the dependency injection container will provide all those values through constructor injection.
Anything else though will not be available automatically. That includes all the default properties that you inherit from Controller or ControllerBase. These are usually implicitly set by the ControllerContext, so you will have to wait for the framework to set those.
Since it is impossible to set a property value before the constructor runs, you will simply not be able to access any of these values within the constructor. So the solution is to move the logic into an action instead. That way, you can access the properties and they will have the proper values.
public class HomeController : Controller
{
public IActionResult Index()
{
var shortName = User.Identity.Name;
return View();
}
}

Is it possible to use 2 different authorization schemes inside the same MVC Controller class?

I am currently working with a legacy .NET Framework application that has a webclient (MVC) and a mobile client. I have successfully configured my project to use bearer tokens for my webapi controllers and session cookies for my mvc controller using the following in my WebApiConfig.cs:
////Tells APIs to ignore the Default Cookie Type Authentication
config.SuppressDefaultHostAuthentication();
config.Filters.Add(newHostAuthenticationFilter(OAuthDefaults.AuthenticationType);
However, within my MVC contrtollers I have some methods that return an IActionResult() and some that return a JSonResult. Is it possible to define an attribute/authshcema on a per basis controller method that would allow my JsonResult controller methods to use bearer tokens instead of cookies sessions, despite not being inside a webapi controller?? This would allow me to call these controller methods from my mobile client and save me a lot of time having to refactor these methods into separate controllers.
Example:
//MVC Controller (Not Web API)
public class HomeController : Controller
{
//Should use cookie session
public ActionResult Index()
{
return View();
}
//Should use bearer tokens
[HttpGet]
public JsonResult GetPrograms()
{
var menu = _menuService.GetMenu();
return new JsonResult
{
Data = menu,
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
}

401-Unauthorized when calling UmbracoAuthorizedApiController from backoffice

Problem
When I change my controller to inherit from UmbracoAuthorizedApiController instead of UmbracoApiController I will get 401-Unauthorized and I will be redirected to loging page.
Mode Details
I want to call some of my backend Api's from the back-office and to do that I've followed the article in our.umbraco.
First I've implemented a controller inheriting from UmbracoApiController to be able to call my services from postman. Everything went fine and I could call my code and read data from Umbraco:
[RoutePrefix("api/admins")]
public class AdminsController : UmbracoApiController
{
[HttpGet]
[Route("getdata")]
public DataViewModel GetData(string id)
{
....
}
}
Then I've called my service from JavaScript in Dashboard using the plugins
$http.get(vm.baseUrl + '/getdata?id=' + id, {})
.then(function (response) {....}
Everything works fine, I can see that my cookies (containing token) has been sent in the request headers.
Then I've updated my controller to inherit from UmbracoAuthorizedApiController and now I don't have access to my Apis.
The controller is now like this:
[RoutePrefix("api/admins")]
public class AdminsController : UmbracoAuthorizedApiController
What did I do wrong?
Authorized controllers (same as other wrapped MVC controllers in Umbraco) are automatically routed. Backoffice authorisation will work when /umbraco/backoffice/ path will be present in the route.
Check: https://our.umbraco.org/documentation/reference/routing/Authorized/
and: https://our.umbraco.org/documentation/reference/routing/webapi/authorization
It's directly said:
In order for Umbraco to authentication a request for the back office,
the routing needs to be specific. Any URL that routes to :
/umbraco/backoffice/*
will be authenticated. If you have a controller
that is not routed within the prefix, it will not be authenticated for
back office use.

Categories

Resources