I have two httppost method one is taking an a concrete class with is working fine. The other one is taking in an interface. When I use postman I get null for the interface method.Should I be able to send a model class to an interface do I need to use custom model binder and if I do where do I need to add it?
public IHttpActionResult InsertData([FromBody] DataLog _datalog)
public IHttpActionResult Insert([ModelBinder(typeof(IDataLog))] IDataLog _log)
I think this would answer your question as well.
Interfaces
Reason why you cannot use interface as an object is because there are no public accessors for them. They also cannot have fields. It is just signature of the properties, and methods.
Interfaces
cannot have implementation
cannot have modifiers public
cannot have virtual
Classes
Each class you define have public properties that have getters and setters. Setters are what sets the values of these public properties. You can use the interfaces and extend them to classes and use these classes as objects to receive the data
Good read about defining and implementing interfaces
Custom Model Binding in ASP with examples
I donĀ“t know if i understand your question. Anyway regarding the code i must say:
Do not use '_' to named your variables, classes, parameters...it is not CLS compliant.
https://learn.microsoft.com/en-us/dotnet/api/system.clscompliantattribute?view=netframework-4.8
Maybe you can use the letter 'D' following the SOLID principle. D as Dependency Inversion using the IOC to Dependency Injection.
https://en.wikipedia.org/wiki/SOLIDhttps://learn.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-3.1
In case that you have only one return type within your method, instead of using generic ActionResults types you can do something like, just to understand the logic:
Instead of:
public ActionResult Index()
{
return View();
}
Do this:
public ViewResult Index()
{
return View();
}
Difference Between ViewResult() and ActionResult()
Do Async await (TAP ) pattern.
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/
Instead of:
public IHttpActionResult InsertData([FromBody] DataLog _datalog)
Make the code to compile faster like this, adding the HttpPost attribute, even knowing this is a POST action:
Do this:
[HttpPost]
public IHttpActionResult InsertData([FromBody] DataLog _datalog)
Hope those good practices helps you somehow! :)
Related
... which may not really be the question at all, but that's what it looks like to me right now.
I have a controller structure that has several layers of inheritance. The base controller is the one that implements Controller and has a method called Create(Guid var1, DateTime? var2) and is called like /MyDomain/Create/00000-0000-0000-000000.
I'm currently trying to implement a method in a controller lower down in the inheritance tree with the signature Create() which takes a QueryString parameter. (/MyDomain/Create?otherVar=somevalue) However, ASP.NET decides this is not valid as an "endpoint" and throws an error message saying The parameters dictionary contains a null entry for parameter 'var1' of non-nullable type 'System.Guid' for method 'System.Web.Mvc.ActionResult Create(System.Guid, System.Nullable`1[System.DateTime])'
I don't really know what is going on here. If I try to call another method on the same controller (with a name that is unique and not used higher up in the inheritance stack e.g. /MyDomain/DifferentMethod) it works without a problem.
My google-fu is coming up short on this problem.
So you have something like:
public abstract class BaseController{
[HttpGet]
public IActionResult Create(Guid var1, DateTime var2){..
}
and
public class SomeClassController : BaseController{
[HttpGet]
public IActionResult Create(){..
}
The problem is that you cannot have 2 routes with the same name and different signature.
This is because the routing don't know exactly where you want to go: with the url '/blalbalba/Create/' witch one you want?
The base class or the inherited once?
It's not so obvious.
Ps take a look on this answer:
ASP.NET MVC ambiguous action methods
I just downloaded music store (microsoft sample projct) source code that based on ASP.NET 5. I don't understand there why developers from Microsoft use IActionResult interface as a return type in controllers.
What is a reason of IActionResult interface usage? Why don't just use ActionResult type.
See this post about IActionResult vs. ActionResult: http://forums.asp.net/post/5980446.aspx
IActionResult allows a wider range of return types, including any custom code that implements the IActionResult interface. ActionResult is limited only to those classes which extend the ActionResult abstract class (which you could also do with custom code, but using an interface allows for something like multiple inheritance, while extending a class does not).
Using interfaces as parameters will allow you to use dependency injection to obtain its dependencies and those dependencies can be replaced with mock implementations when testing which implement those interfaces.
IActionResult has more return types than ActionResult. For ex: If you want to return HttpNotFound you have to use IActionResult return type.
kinda new to MVC, and kinda new with Ninject. Playing around...
I've defined ninject in my MVC application as follows:
private static void RegisterServices(IKernel kernel)
{
kernel.Bind(
x => x.FromThisAssembly()
.SelectAllClasses()
.BindAllInterfaces()
);
}
I have controller with a form and this ActionResult:
public ActionResult Index(IMember Member)
{
return View();
}
and it's returning an error: "Cannot create an instance of an interface."
Now I understand that it might not like the interface but isn't Ninject supposed to inject the real class in there? do I need to put in the actual class? if so, doesn't that take the point out of using interfaces and building a lossly-cuppuled apps?
BTW in my Index.cshtml file I have the following as the first line:
#model IMember
Thanks
You seem to be confusing constructor dependency injection with action method parameters, they are not the same thing.
In your case you seem to want Ninject to somehow inject a concrete IMember implementation whenever a client (browser, etc) calls the Index action.
Bear in mind that any parameters that are going to be passed into an Action method are going to be coming from the client and not from the framework, so it wouldn't make sense to do this.
I am sure there is a hack you could do to make it work for e.g decorate the parameter with [Inject] or something but you've already lost at that point because you have just "revealed your sources" to the controller which is against the point of Inverting control - you might as well just pass the Ninject IKernel to the controller.
Anyway in your case, Ninject will only inject into the Controller constructor (assuming you have correctly wired it up) and in that respect, Doug's answer here is actually correct - if that IMember is some kind of controller dependency, then you must inject it into the constructor, and store it in for e.g. a private member so that you can later refer to it from within action methods.
If the IMember is not a controller dependency but is instead just a model-bound parameter that you want passed to your controller, then Dependency Injection is not the answer - the parameter should be coming from the caller.
Also, there might be another problem even if you do end up using constructor injection.
The convention-based binding you are using requires that there is a single class called Member that implements IMember, i.e that the class name differs from the interface name only by lack of the initial "I". If this isn't the case for your class, then the convention-based binding will not work anyway and you need to use something explicit like
kernel.Bind<IMember>.To<MyMemberImplementationClassName>();
Hope that helps.
Is your RegisterServices method in the NinjectWebCommon.cs file located in the App_Start folder?
You'll also need to pass the Member object into the view kind of like below:
public class HomeController : Controller
{
private IMember _member;
public HomeController(IMember member)
{
_member = member;
}
public ActionResult Index()
{
return View(_member);
}
}
Trying to avoid repetition here. I have an action in a base class controller which I am not allowed to modify. I'd like my action to do some checks, call the base class action, and modify the result in some way before rendering. But part of what I need to do involves modifying some properties of the ViewModel, and the base class returns an ActionResult. I see no way to get the ViewModel from the ActionResult, and so I may have to write a custom method, most of which would just mimic what the base class is doing. I'd strongly prefer not to do this. Any suggestions?
That's because ActionResult is a fairly high-level base class. Try casting it to the appropriate subtype, such as ViewResult.
Quick sample code:
public ActionResult WrapperAction()
{
// do your initial stuff
// call your base controller action and cast the result
// it would be safer to test for various result types and handle accordingly
ViewResult result = (ViewResult)base.SomeAction();
object model = result.ViewData.Model;
// do something with the model
return result;
}
I am fairly new to DI with Autofac and wonder if the following is possible
I want to create a generic controller and action that receives an
injected type.
I do not want an instance of the injected type, but just need its
type, which would be an inplementation of an expected interface.
I would also like to pass that generic type on to a ViewModel, but that is another subject altogether, however if some genious out there can solve both that would be excellent.
public ContractorController<T> : Controller
where T : IContractor{
public ViewResult New() {
var vNewModel = new NewViewModel<T>();
return View(vNewModel);
}
}
This controller should be called through
http://mysite.com/Contractor/New
I have been looking into registering generics with AutoFac, but it
seems that the problem is that the AutofacControllerFactory only implements GetControllerInstance(), expecting the controller Type passed to it from either GetController() or CreateController(), not sure which or what the diffirence is between them. These methods receive the controller's name as a string from RoutData and return the corresponding .NET type which, give the url, http://mysite.com/Contractor/New is controller=Contractor and thus ContractorController cannot be matched by GetController() or CreateController() and therfore passing null to GetControllerInstance() which mean AutofacControllerFactory does not attempt to resolve the type.
I figured that I would have to create a custom Controller Factory
deriving from AutofacControllerFactory, override GetController() or CreateController() and
perform my own mapping from the controller names to the generic types.
Something like
if (controllerName == "Contractor")
return System.Type.GetType(
"UI.Controllers." + controllerName + "Controller`1");
When I debug this I can see that this code is finding the generic controller and returning it.
I thought I could then just register the types like
builder.RegisterType<FakeContractor>().As<IContractor>();
builder.RegisterGeneric(typeof(ContractorController<>));
But I am getting the following error
The Autofac service
'UI.Controllers.ContractorController`1'
representing controller
'ContractorManagement.UI.Controllers.ContractorController`1'
in path '/Contractor/New' has not been registered.
So I think I may be barking up the wrong tree.
Can anyone please shed some light on how I can do this without pulling
my teeth
Thank you
I'm not entirely sure why you want a controller using a generic. Using a generic on a Controller isn't really supported in Mvc - or at least the supporting routing path would be involved. Perhaps you can provide more info on the reasoning behind the approach?
What it looks like is that you want a controller that supports model binding against varying types. The next question is whether these types vary across a common interface or base class.
If that's the case, for Mvc2 check out the IocModelBinder information. This will work with Autofac quite well. This will allow the type to be model bound on post or get allowing you to inject services with autofac.
If you want to vary the types by a common base - supporting a variety of concrete view model - then check out the DerivedTypeModelBinder in MvcContrib. There is a version that works in Mvc 1, 2 and now MvcContrib for Mvc3 has a good sample app to accompany it. The Mvc3 implementation is also faster - speed wasn't a problem before, it's just a more efficient identification process.
Maybe it's not a direct answer to your question, but this is the only possible way to use generic controllers that I ever seen and used:
public abstract class ContractorControllerBase<T> : Controller where T : IContractor {
public ViewResult New() {
var vNewModel = new NewViewModel<T>();
return View(vNewModel);
}
}
public class FakeContractorController : ContractorControllerBase<FakeContractor> {
}