How to add custom authorization filter to method not controller in asp net core? - asp.net

When I add custom IAuthorization attribute to controller method it works, but when I add it to method that is not part of controller method, IAuthorization method does not execute. Why?
public interface ICasbinBLL
{
public abstract string objectId { get; set; }
[ClaimRequirement("userId", "delete")]
string DeleteMonitoring();
}
public class CasbinBLL : ICasbinBLL
{
public string objectId { get; set; }
[ClaimRequirement("userId", "delete")]
public string DeleteMonitoring()
{
return objectId;
}
}

IAuthorizationFilter is one of the filters in ASP.NET Core. Filters are executed by ASP.NET Core framework in filter pipeline.
Filters run within the ASP.NET Core action invocation pipeline, sometimes referred to as the filter pipeline. The filter pipeline runs after ASP.NET Core selects the action to execute.
If you add filters to your own types, ASP.NET Core does not know how to execute them.

Related

.net core API optional route parameters

I have a .net core api with swagger. No I want to add a Filter-Class including optional filter-parameters.
[HttpGet("", Name ="get-index")]
[ProducesResponseType(typeof(IEnumerable<MyModelGet>), (int)HttpStatusCode.OK)]
[ProducesResponseType(typeof(void), (int)HttpStatusCode.NoContent)]
public IActionResult GetIndex([FromRoute] MyFilter? filter){
...
}
The properties of the filter-class are optional/nullabel:
public class MyFilter {
public int? size{
get; set;
} = null;
...
}
But in Swagger all Properties are required:
Is there any way (e.g. a Annotation) to make this fields optional?
Replacing the [FromRoute] by [FromQuery] solved my issue.
just Add '?' in HttpGet , like This :
[HttpGet("", Name ="get-index?")]

UnitOfWork + Repository Pattern

I have a very strange situation. I have a UOW Repository pattern. I have domain layer which houses my entities, A Data Access layer which contains the dbcontext (UnitofWork) and repositories for different entities. I have an application layer where i have services which i call for reading and writing data. Architecture contains basically this with some DTOs to help consistency in data. I have a UI layer with MVC5 where i have injected all the dependencies through Unity and it works great if i instantiate each service from a controller constructer.
I have quiet a few services such as GlobalAppSvc (Implemented from IGlobalAppSvc), SystemSettingAppSvc (ISystemSettingAppSvc) etc etc. To make life easier I've created a class called ApplicationManager like this.
public class ApplicationManager
{
public ApplicationManager(ISystemSettingAppSvc systemSettingAppSvc, IBalanceAppSvc balanceAppSvc, IGlobalAppSvc globalAppSvc, IProfileAppSvc profileAppSvc)
{
SystemSettingAppSvc = systemSettingAppSvc;
BalanceAppSvc = balanceAppSvc;
GlobalAppSvc = globalAppSvc;
ProfileAppSvc = profileAppSvc;
}
public ISystemSettingAppSvc SystemSettingAppSvc { get; set; }
public IBalanceAppSvc BalanceAppSvc { get; set; }
public IGlobalAppSvc GlobalAppSvc { get; set; }
public IProfileAppSvc ProfileAppSvc { get; set; }
}
In my Unity i have Registered all the Services and Repositories along with the Unit of Work
container.RegisterType<IUnitOfWork, WUnitOfWork>(new PerResolveLifetimeManager(), new InjectionConstructor());
container.RegisterType<IWUnitOfWork, WUnitOfWork>(new PerResolveLifetimeManager(), new InjectionConstructor());
I have created a BaseController by extending Controller so that i don't have to resolve Application manager in every controller i write. In base controller i am resolving this ApplicationManager as
public class BaseController : Controller
{
// GET: Base
public ApplicationManager ApplicationManager
{
get;
private set;
}
public BaseController()
{
ApplicationManager = UnityConfig.Container
.Resolve<ApplicationManager>();
}
}
I can then go in any controller and extend the controller with this BaseController and i have access to ApplicationManager.GlobalAppSvc.Methods()...
My problem is that whenever there is a data modification such as lets say there is an action which executes to deduct the balance and save changes for a particular user. When i request the user's balance again it is still showing unchanged balance however the balance in Database is deducted but the service is not fetching the updated data. What am i doing wrong?
It looks like the solution is to ensure the BalanceAppSvc needs to be registered with Unity as such:
ApplicationManager=UnityConfig.Container.Resolve<ApplicationManager>(); and registering types as container.RegisterType<IBalanceAppSvc, BalanceAppSvc>(new PerResolveLifetimeManager());

.Net Core Api Controller inheritance

I'm trying to create an API Module that can be used across multiple API projects. I want the Module to have a controller with an action that can be overriden based on the implementing API requirements.
I have the following project structure:
Module
-Controllers
-ModuleController.cs
-Interfaces
-IModel.cs
-Models
-Model.cs
API
-Controllers
-DerivedModuleController.cs
IModel.cs
public interface IModel
{
int Id { get; set; }
}
Model.cs
public class Model : IModel
{
public int Id { get; set; }
}
ModuleController.cs
[Route("api/module/[action]")]
public class ModuleController : Controller
{
[ActionName("GetModel")]
[HttpGet("{id}")]
public virtual Model GetModel(int id)
{
return new Model() { Id = id };
}
}
DerivedModuleController.cs
public class DerivedModuleController : ModuleController
{
public override Model GetModel(int id)
{
return base.GetModel(id);
}
}
The API project references the Module. If I remove the DerivedModuleController everything works fine. I can make a request to /api/module/GetModel/1 and get a valid result. However, when I add the DerivedModuleController it fails with the following error:
AmbiguousActionException: Multiple actions matched. The following actions matched route data and had all constraints satisfied:
Api.Controllers.DerivedModuleController.GetModel (Api)
Module.ModuleController.GetModel (Module)
Ultimately I want to be able to get a DerivedModel that extends Model from the DerivedModuleController but I can't get past this error.
Is there a way to use the base route (/api/module/GetModel/1) to access the DerivedModuleController and ignore the ModuleController?

Json object using WebAPI controller

I am using webapi controller.I have to pass an JSON object from Java applet to web api controller. How to write a web api controller method to accept the JSON object
public test GetPo(int id)
{
}
ASP.NET Web API uses JSON format as default format:
JSON formatting is provided by the JsonMediaTypeFormatter class. By default, JsonMediaTypeFormatter uses the Json.NET library to perform serialization. Json.NET is a third-party open source project.
what you just do is to defined your model object which map with json:
public class Model
{
public int Property1 { get; set; }
public string Property2 { get; set; }
// More properties
}
And your POST method:
public void Post(Model model)
{}

Overriding validation attribute from a base Model

i have a MVC controller called MyController with an action called MyAction. For other hand i have a Model called MyModel, and all this classes are in a project called Portal.Website (Asp.net MVC3 Application) that i use as a generic website and that store common functionalities for custom websites that i will add in the future.
For other hand i have another website project with a reference to Portal.Website project called Portal.Website.MyCustomWebsite.
This is the viewmodel MyModel.cs in the generic website part:
namespace Portal.Website
{
public class MyModel
{
[Required(ErrorMessage="The field Name is required.")]
[Display("MyPropertyOriginal")]
public virtual string Name{get;set;}
}
}
This is the controller and action in the generic website part:
namespace Portal.Website
{
public class MyController: Controller
{
[HttpPost]
public ActionResult MyAction(MyModel model)
{
if(Model.IsValid)
....
//My issue: Im getting the error message in english, not the overridden one.
}
}
}
This is the viewmodel that i created in the custom part:
namespace Portal.Website.MyCustomWebsite
{
public class MyModel: MyModel
{
[Required(ErrorMessage="My error message in other language.")]
[Display("MyPropertyOverriden")]
public override string Name{get;set;}
}
}
My problem:
I would like to override the ErrorMessage of the Required attribute. For this reason i created a new Model in my custom project. For other hand i would like to use the Controller/Action (MyController/MyAction) that is already defined in my common part.
Do you know if this is possible? Im only getting the issue with the Required attribute, but with the Display one its working perfect.
Thanks in advance.
Greets.
Jose.
You may want to check out this article that suggests two possible solutions :
http://www.codeproject.com/Articles/130586/Simplified-localization-for-DataAnnotations
I've found it was making more sense to re-create some DataAnnotation classes with my custom logic.
MVC3 comes with better support for I18N (internationalisation) than it's predecessors - you can pass the RequiredAttribute the type of your resource class and the resource key and the error message will be displayed in whichever language is most appropriate:
[Required(ErrorMessageResourceType = typeof(MyResources), ErrorMessageResourceName = "ResourceKey")]
public override string Name { get; set; }

Resources