I want to build a base controller that I can put some reusable methods so I do not have to put a bunch of repeat code in all my controllers. So I built a BaseController.cs
public class BaseController : Controller
{
public IHttpClientFactory _clientFactory;
public BaseController(IHttpClientFactory clientFactory)
{
_clientFactory = clientFactory;
}
}
Then in one of my contollers I do public class TokenController : BaseController. But then it wants me to add the following but then it gives me errors
public TokenController(IHttpClientFactory clientFactory)
{
// I guess something goes here
}
But then VS Code tells me
There is no argument given that corresponds to the required formal parameter 'clientFactory' of 'BaseController.BaseController(IHttpClientFactory)' (CS7036)
What am I missing here? I been in JS world to long :)
When inheriting classes without default constructors you have to pass parameters to them using the following syntax:
public TokenController(IHttpClientFactory clientFactory) : base (clientFactory)
{
/* other initializations */
}
So add the following expression: : base (clientFactory)
See more information here: https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/using-constructors
Related
I have different configurations all inheriting from a base configuration that are customized in forms. I want all of these to be handled by a single action result.
[HttpPost]
public IActionResult Register(AbstractBaseConfig config)
{
...do some logic...
return View("../Home/Index");
}
However, this is not possible because you cannot base in abstract classes as a parameter to an action result. Is there any work around for this so I don't need a seperate action result for each configuration? (I still want each configuration to be it's own class, I only need access to the base class methods in the action result logic).
Basically you can't, and the reason is that MVC will try to do new AbstractBaseConfig() as part of the Data Binding process (which parses the URL or the Form Post and puts the results in a concrete object). And by definition, doing new AbstractBaseConfig() is impossible for an abstract class.
It also makes sense for other reasons, I will explain why.
You seem to expect that MVC can determine the class from the parameters that are being passed in. That is not how it works, in fact the opposite is true: the Action Method has to specify the exact class, and then the Binder will instantiate that exact class and try to bind its properties.
Suppose you had this:
public abstract class Thing { public int ID { get;set; } }
public class NamedThing : Thing { public string Name { get;set; } }
public class OtherThing : Thing { public string Name { get;set; } }
and suppose it would be allowed to use:
public IActionResult Register(Thing thing)
then what would you expect to be in thing after Data Binding: a Thing object with only the ID set? Or one of the other object types, with Name set, but how would MVC ever be able to know which class you meant?
So for all these reasons, this is not possible.
You could have a base class inherit the abstract class and all your classes inherit from that base class whilst having that base class as your parameter
Take for example
public abstract class ABase
{
public void stuff()
{
var stuff = string.Empty;
stuff = "hello";
}
public virtual void otherstuff()
{
var stuff = string.Empty;
stuff = "hello";
}
}
public class Base : ABase
{
//empty
}
public class Derived : Base
{
public void mystuff()
{
this.stuff();
}
public override void otherstuff()
{
// Custom code
}
}
public ActionResult Register(Base config)
{
}
I installed the Nuget package. hooked it through the "using" . The package classes work in another solution, and in my project they do not work
screenshots:
neolux
I think there are two separate issues here. I had an issue similar to #Leo in that the TestForNet() method is part of the NeoDB class.
Assuming that the method exists on the NeoRPC class for you, then #Leo is also spot on in suggesting that you can't create a variable (i.e. var api = NeoRPC.TestForNet()) within a class declaration as you have it in your screenshot.
If you'd like to set api when the class is created, you can create the variable at the class level and assign it in the constructor. I'm going to rely on NeoDB instead of NeoRTC in this example:
public class HomeController : Controller
{
private readonly NeoDB _api;
public HomeController()
{
_api = NeoDB.ForTestNet();
}
public IActionResult Index()
{
// _api.QueryRPC();
}
}
class from the attached library is not activated
You should put the code into the method rather than under the class directly, like:
public class HomeController : Controller
{
public ActionResult Index()
{
var api = NeoRPC.ForTestNet();
Hope this helps.
I have a Spring Boot app with multiple controllers serving various REST methods. Each of the methods require that the same header parameter be defined. Is there a way to specify something like the following one time for all controller methods?
public ResponseEntity get(#RequestHeader(value="NAME", required = true) String name, ...) {
...
}
Thanks.
You can probably achieve this using #ModelAttribute, like this:
public class Something {
private name;
//...
}
#ModelAttribute("something")
public Something addSomething(#RequestHeader(value="NAME", required = true) String name) {
return new Something(name);
}
#RequestMapping("/something")
public ResponseEntity get(#ModelAttribute Something something) {
//...
}
You can implement the #ModelAttribute populating method in a single Controller or in a #ControllerAdvice class, in order to assist multiple controllers. See reference documentation.
Assuming I have an Interface IReportBuilderService and concrete class ReportBuilderService
e.g. public class ReportBuilderService : IReportBuilderService { }
I can start to mock this service with Moq as such
Mock<IReportBuilderService> _reportBuilderServiceMock = new Mock<IReportBuilderService>();
And mock expectations etc on the mock class, ok no problems.
Question: How do I mock the following method signature?
public abstract class ReportBuilder<TReport> where TReport : Report, new()
where a TReport is defined as
public class SomeReport : ReportBuilder<Report>, IMapper{}
And Report class is simply
public class Report { }
In the abstract class ReportBuilder there are a series of Property Get/ Sets, it is the value of these that I’m trying to fake/mock.
But I can’t begin to get the correct mock on this abstract class to start with
Hope this makes sense
Given that your abstract class looks like this:
public abstract class ReportBuilder<TReport> where TReport : Report, new()
{
public abstract Int32 SomeThing { get; set; }
}
there's no problem in mocking it at all:
var m = new Mock<ReportBuilder<Report>>();
m.SetupProperty(r => r.SomeThing, 19);
but note that all your properties have to be virtual or abstract.
So if this is not the case (and you can't or don't want to change this), you could either extract an interface from your base class and use this (if you're willing to change your code accordingly), or simply create a stub/mock by subclassing:
public class StubReportBuilder : ReportBuilder<Report>
{
public override Int32 SomeThing { get { return 42; } set { } }
}
I have an Interface defined as:
public interface DocExporter{
public void exportDoc();
}
with two implementing classes defined as:
#Service(value="docExporter")
#Scope(value="BeanDefinition.SCOPE_PROTOTYPE)
public class PdfDocExporter implements DocExporter{
public void exportDoc(){
// do Pdf Export stuff
}
}
AND
#Service(value="docExporter")
#Scope(value="BeanDefinition.SCOPE_PROTOTYPE)
public class ExcelDocExporter implements DocExporter{
public void exportDoc(){
// do Excel Export stuff
}
}
So can I say like :
#Name("docExportReporter")
#Scope(ScopeType.EVENT)
public class DocExportReporter {
#In("#{docExporter}")
private DocExporter pdfDocExporter;
#In("#{docExporter}")
private DocExporter excelDocExporter;
#Asynchronous
public void reportGen(){
**excelDocExporter.exportDoc()** // THIS THROWS Seam Exception #In attribute requires a not null value
}
}
I am new to Seam with Spring and would like to know if in both impl classes #Service would have values as "docExporter" (name of interface) or would it be like "pdfDocExporter" "excelDocExporter" ?
And with the above, I get #In attribute requires a non null value exception when using pdfDocExporter or excelDocExporter objects within the reportGen async method. Can two implementations of an interface be declared in a third class and work fine
with Seam #Asynchronous annotation ?
You cannot have two components with the same name, otherwise Seam would not know which one to inject. Use two different names.