I am working on web api project, we have one htmlhelper class, where I see declarations that look like:
public static string GetCountryDomain(this System.Web.Mvc.HtmlHelper htmlHelper, Area area)
{
//body
}
Can I use method declared in helper class in my api method?
If Yes, then can someone explain how can I call that method from my controller?
Consider following example, wherein am calling method declared in helper from my controller.
HtmlHelper.GetCountryDomain(area_id);
can someone explain what first parameter I need to pass in order to call above method of HtmlHelper class?
Related
I need to inject httpcontext into custom attribute that is used outside the controller. I found several solutions how to do it in controller, but my case is little tricky. Now I have following code in my PermissionController
[PermissionFilter(PermissionEnum.Permission, AccessLevelEnum.Create)] <-- it works perfectly
[HttpPost("users/{userId}")]
public async Task<IActionResult>
AssignPermissionToUser([FromBody] List<PermissionToVM> permissions, int userId)
{
await _permissionService.Assign(permissions); <-- .Assign() extension
//code goes here
}
In the method above there is a call of extension method .Assign. This method code is available below.
//[SecondPermissionFilter(PermissionEnum.Permission,
AccessLevelEnum.Create)] <-- here I check permissions but don't
know how to inject the httpcontext
public async Task Assign(List<PermissionToVM> permissions)
{
//code goes here
}
As mentioned in many websites I visited f.e. here https://dotnetcoretutorials.com/2017/01/05/accessing-httpcontext-asp-net-core/ injecting of httpcontext outside the controller can be done using IHttpContextAccessor. The problem is that I don't know how to use it without passing it into constructor. My custom attribute should be called as decorator [SecondPermissionFilter(PermissionEnum.Permission, AccessLevelEnum.Create)] when only permission settings should be passed, so there is no any reference to httpcontextaccessor.
Is this even possible? If not, there is maybe another way to do this?
EDIT: Here is the code of SecondPermissionFilter class:
public sealed class SecondPermissionFilterAttribute : Attribute
{
private readonly PermissionEnum _requestedPermission;
private readonly IEnumerable<AccessLevelEnum> _accessLevelCollection;
private readonly IHttpContextAccessor _contextAccessor; //<-- how to inject?
public PermissionFilterAttribute(PermissionEnum requestedPermission, params AccessLevelEnum[] accessLevelCollection)
{
_requestedPermission = requestedPermission;
_accessLevelCollection = accessLevelCollection;
}
}
What you are after is something called Property Injection. As per the official docs this is not something that is supported out of the box by the .NET Core DI Container.
You can however use a third party library such as Ninject or Autofac - both of which are available via NuGet.
In my opinion the Ninject syntax is nicer, however as noted in this answer, and this answer property injection itself is considered bad practice. So if possible I would try to avoid it.
So you should instead use one of the three methods specified by the filter documentation, this answer breaks things down a bit more.
Edit
This answer deals specificically with Attribute injection, the second answer looks to achieve this without external dependencies.
i am new in MVC and learning. here i am putting some code. so see first
public class HomeController : BaseController
{
private IProductRepository productRepository;
private string strRouteValue;
protected override void Initialize(System.Web.Routing.RequestContext requestContext)
{
base.Initialize(requestContext);
strRouteValue = this.ControllerContext.RouteData.Values["method"].ToString();
this.productRepository = Factory.Create(strRouteValue);
}
[HttpGet]
public ActionResult Index(int id)
{
productRepository.Get(id);
return View();
}
[HttpPost]
public ActionResult Index(Product model)
{
productRepository.Add(model);
return View();
}
}
what Initialize function does ?
every one must say this is where people would init many object, if so then we can do it in constructor of controller too. so what is special about controller Initialize function ?
what is difference between controller Initialize function and controller constructor ?
Check the documentation for that method: MSDN: Controller.Initialize():
Initializes data that might not be available when the constructor is called.
This method cannot be called directly. Override this method in order to provide additional processing tasks before any ActionResult methods are called, such as setting the thread culture or assigning a custom provider for TempData objects. If you override this method, call the base control's Initialize method.
And as I suggested on your previous twenty or so questions about MVC, Dependency Injection and controller instantiation: stop piecing together advice from poor blogposts and irrelevant answers on SO. Buy a decent MVC book and read it from cover to cover. Then do the same with a book about Unit Testing. You will never get a thorough understanding of things if you continue this way.
There is a difference between instantiating a controller and initializing it. Instantiating is moreover a .NET concept not MVC, so every class is automatically instantiated using default constructor. So, constructor is basically a concept of class whereas Initializing is concept of action method. We override Initialize() method in order to provide additional processing tasks before any ActionResult methods are called, such as setting the thread culture or assigning TempData objects etc....
How to define constructor in Yii application?
Where ?to define the constructors?
I need to create constructors. Where it defines inside model or controller.
Can you guys give some example of formats ?
In a lot of Yii classes there are 2 methods that can be used to define initialization code : __construct() and init():
__construct() is a native php method to instantiate the object.
init() is called when Yii has performed it's own instantiation of the class (for example in a CActiveRecord class Yii has set the scenario name)
it's up to you to use
public function __construct()
{
//Your code
return parent::contruct()
}
or just to use the init method
public function init()
{
//Your code
}
if you use construct be carefull because some classes constructors have some params that you'll also have to set (for example CActiveRecord take the scenario name as a param)
If I were you I'll use the init method as often as possible.
I am learning Symfony2, and part of the documentation on controllers states that the methods on the controller object are actually the controllers, whereas the object is more of a controller container.
Which part specifically is referred to as the controller(s)? I'm new to MVC and OOP, so I'm just trying to make sure I have it right.
the page describes actually a convention endorsed by Symfony2 creators.
in some MVC frameworks (esp. in Java) controllers are implemented by one-class-per-controller convention, e.g.:
class ListContactsController {
public function start() {
// query db...
return ...;
}
}
class AddContactController {
public function start($name, $details) {
// insert into db...
return ...;
}
}
note that every controller-class has one method start() that defines what the controller actually does
in other MVC frameworks (like Symfony2 or cake-php) controllers are implemented by one-method-per-controller convention, grouped together for convenience, e.g.:
class ContactsController {
public function list() {
// query db...
return ...;
}
public function add($name, $details) {
// insert into db...
return ...;
}
}
here the convention assumes every controller is implemented as a method rather than a separate class with a particular method like start()
EDIT: another way of thinking about this difference is this:
one-class-per-controller assumes there is one controller instance (might hold internal state) and when user interacts with the view, view is communicating with that controller instance via callbacks i.e. methods in controller's class.
one-method-per-controller assumes any state is contained within parameters that are passed to methods, and when user interacts with the view, view is communicating with separate controllers/actions. those controllers are seen as independent concepts.
In the example page you shared, the "class HelloController" is the Controller and its' functioned are Controller "Methods".
Okay, they are referring to the default method, indexAction() as the Controller.
In this MVC architecture (and most others, if not all) the "index" method is the default method (function) called when that controller is requested.
I have a class which needs to use an IRepository for one method in it's class.
Ideally, I would like to avoid having to resolve this dependency into the class's constructor, and so I found method level injection in Ninject and was wondering how this works?
I understand how to set it up. What I'm confused about is how to call it?
Example:
class SomeClassThatUsesRepository
{
[Inject]
public void QueryForSomeStuff(IRepository repository)
{
//do some stuff
}
}
My problem is how do I call this method without specifying an IRepository?
var someClass = Kernel.Resolve<SomeClassThatUsesRepository>();
would work if I was using the constructor, but I want to call a method.
How do I call a method using Ninject method injection?
I'm afraid method injection doesn't work this way - it's just one of the ways to inject dependencies into an object during its construction (you can inject your dependencies through constructor parameters, through properties, fields or methods). Method injection is useful if your class takes its dependencies by Java-style setter methods like
public void SetRepository(IRepository repository) { ... }
If it is marked with [Inject] attribute, you don't need to call this methods directly, it is to be called by Ninject during the initialization to pass the IRepository object into your resolved object.
So I believe your QueryForSomeStuff method is being called when you resove your SomeClassThatUsesRepository.
Confirmed that method injection doesn't work as intended. Got a custom MVC attribute class and wanted to use an injected object inside it. Did not pass it
into the constructor and added method
[Ninject.Inject]
public void ResolveDI(ISettingStore store)
{
ConfigHelper = store;
}
This method was never called and ConfigHelper was null when the attribute's OnActionExecuting was called.