This is the method I wanna call:
[AcceptVerbs(HttpVerbs.Post)]
public string MyPostMethod(int i)
{ ... }
I want to call it from another method in the same controller:
[AcceptVerbs(HttpVerbs.Get)]
public string MyOtherMethod(int i)
{ MyPostMethod(i); }
Is there a way to do this?
You should treat the controller methods as class methods .(A controller is just a class)
So would you do it for a class? If it is YES, you can do it for a controller too
Anyway, I would encapsulate the code in a private method and call it within the controller's
methods.
Related
Is there a way to define method that will be executed before every Route method call.
public class ExampleController : ControllerBase
{
private static int i;
private void funcToCall()
{
i++;
}
[HttpGet]
public IActionResult Ping()
{
return Ok("Pong")
}
}
I want to call funcToCall whenever Ping Route is called. I also cannot do it in constructor, because lifetime of controller is Singleton.
I was wondering if overriding [HttpGet], [HttpPost] etc... attributes will work, but I also belive it may be simpler solution.
I have a series of dynamic links on my view that render like this:
Course Image <strong>(600x384)</strong>
I have a method that looks like this:
public class CantoDownloadPreset
{
public static FileResult DownloadPreset(string preset)
{
...
}
}
how can I call the helper DownloadPreset method and send data-itemid parameter.
CantoDownloadPreset should be a controller in a named file CantoDownloadPresetController.cs inside Controllers Folder.
Then if you need to do a GET, inherit Controller and remove static:
public class CantoDownloadPresetController : Controller
public FileResult DownloadPreset(string preset)
{
...
}
But take consideration if you want to return a FileResult and where. This question implies a lot of research about how MVC Web Controller works and you should be more in focus. But anyway, the link should be then (only for GET of course):
/method/action/value
then:
/CantoDownloadPreset/DownloadPreset/?preset=value
In one of the controllers, every view has a fixed preprocessing. Is there a better way of doing this, instead of the below code; such that SomeFunctionAsync works without writing that line before return View() for all functions with return View() in this controller? I also have some ajax post functions.
public async Task<ActionResult> View1()
{
await SomeFunctionAsync();
return View();
}
public async Task<ActionResult> View2()
{
await SomeFunctionAsync();
return View();
}
In other words, at the end I want to be able to write the following with having the same effect
public async Task<ActionResult> View1()
{
return View();
}
public async Task<ActionResult> View2()
{
return View();
}
If Action Filter as suggested by Varun doesnt suits you, you can try another way.
Create a parent View of all the view. In the action method for your parent view. Call this Method SomeFunctionAsync(). Thus, parent view will be called for all of yours views and the required method will be executed
You can create a base class for your controller, and have have each view in your code call a generic method. I use GetView as a method name (or you could override the existing ones).
Like so:
public class MyControllerBase : Controller {
public Task<ActionResult> GetView() {
yourCommonMethod();
return View();
}
public Task<ActionResult> GetView(string viewName) {
yourCommonMethod();
return View(viewName);
}
public Task<ActionResult> GetView(object model) {
yourCommonMethod();
return View(model);
}
public Task<ActionResult> GetView(string viewName, object model) {
yourCommonMethod();
return View(viewName, model);
}
}
Then in your controller, inherit from that:
public class MyController : MyControllerBase {
public async Task<ActionResult> View1()
{
return GetView();
}
}
If the common method is the same for all controllers and has no controller-specific dependencies, it could be that simple. However, you may want to look at using generics as well:
public class MyControllerBase<T> : Controller {
// base class stuff here based on type T's interface
}
public class MyController : MyControllerBase<MyController> {
// regular class here, sending MyController to the base
}
These are pretty much building blocks of OOP. You may do well to get a book that covers the basics of OOP and work through this type of stuff.
There are tow ways :
Use a single Action with different views like return View("View1") or retrun View("View2"), you can make if else conditions there so you will call your function at a single place.
If you want to go with your current procedure(not recommended) then you have to use Action Filter attribute and decorate it on Controller level then every action would execute your logic before execution of your Action
I would like to know, if it is possible for each subsequent request, to not have the default constructor in the controller invoked?
Here's the fake scenario:
I have a controller (HomeController) with 3 Action methods. Now, each method uses a property from a Customer type. I don't want this Customer Type to always be instantiated for each action method.
Sample Code:
public class HomeController : SampleController
{
public HomeController(System systemInstance)
{
base.System = systemInstance;
}
public ActionResult Index()
{
//Do something with the CustomerType
base.ValidationResult = ValidationEngine.Validate(base.Customer.Address)
return View();
}
public ActionResult Index()
{
//Do something with the CustomerType
base.ValidationResult = ValidationEngine.Validate(base.Customer.ShoppingCart)
return View();
}
}
What I'm trying to achieve it that upon the first Invocation, I instantiate the base.System Property and then for each subsequent action method, I can just reference the instantiated type.
I dont want to store this type in the Session, or in the Cache.
Hope this makes sense :)
Thank u
I'm writing my app using Asp.Net MVC 3. In my controller I have two action methods with the very same code apart from one line. Here it is:
[HttpPost]
public ActionResult EditPost(Post post)
{
if (ModelState.IsValid)
{
_postsRepository.UpdatePost(post);
return RedirectToAction("NewsFeed");
}
return View("EditPost", post);
}
[HttpPost]
public ActionResult AddPost(Post post)
{
if (ModelState.IsValid)
{
_postsRepository.UpdatePost(post);
return RedirectToAction("NewsFeed");
}
return View("AddPost", post); // the return view is different
}
So, I want to withdraw all this code into helper method.
What I've already tried:
1) I tried to put all the code into helper method and pass as parameters ModelState.IsValid and View name. And then in AddPost and EditPost I call this helper method instead of code listed above. Here is the new code:
[HttpPost] // also tried without this attribute
public ActionResult HelperPost(Post post, string viewName, bool modelState)
{
if (modelState)
{
_postsRepository.UpdatePost(post);
return RedirectToAction("NewsFeed");
}
return View(viewName, post);
}
[HttpPost] // also tried without this attribute
public void AddPost(Post post)
{
HelperPost(post, "AddPost", ModelState.IsValid);
}
The EditPost code is almost the same. The view name is "EditPost".
When I run the app and AddPost method executes the validation works and the new post is created but this line never executes:
return RedirectToAction("NewsFeed");
So I'm redirected to "AddPost" view again and again.
2) Also tried to redirect to HelperPost method instead of calling it withing AddPost and EditPost. The result is still the same: seems like RedirectToAction("NewsFeed") doesn't execute. (Here I neglected the validation just to simplify the example, cause I would have to create new model with properties: Post post, string viewName, bool modelState). The code:
[HttpPost] // tried without attribute
public void AddPost(Post post)
{
return RedirectToAction("HelperPost", post);
}
[HttpPost] // tried without attribute
public RedirectToRouteResult HelperUpdatePost(Post post)
{
_postsRepository.UpdatePost(post);
return RedirectToAction("NewsFeed");
}
So, How could I refactor my code so my action methods (EditPost and AddPost) would not contain the same chunk of code?
p.s. I need different views for AddPost and EditPost methods cause the "back to content" links in them are different. So, I can't just redirect to the EditPost view from AddPost method.
Thanks for help in advance!
Just put your "back to content" link in the model, then use the same view for both, then you can use the same HttpPost method. Saves having to duplicate everything.
I would solve it like this:
I would withdraw the method implementation into separate private
method. This method will be invoked by each of the public action
methods. Since the View name differs for both methods I would pass
the view name as parameter to the private method.
The private method doesn't need the HttpPostAttribute!
Don't forget to declare Add and Edit action methods as returning
ActionResult! As parameter they will expect only Post, the view name has to be hard-coded into the action methodsiteslf ;-)
I hope this helps.