How to have multiple aliases for a controller action - c#

I have a Search controller with a generic Search() action that takes several parameters and has a bunch of logic. I'd like to call this from other controllers without having a lot of copy/paste code.
I'd like to call this action from these different urls/controllers.actions.
/Search/Search?text=mySearchText
/User/SearchTransactions?type=purcahse
/Transactions/UserSearch?UserId=1
I could move the method to a baseController but I'd have to call /Search on each controller and I'd like to have them all named differently.

you already have your solution man put it in base controller and decorate it with actionName attribute
like
[ActionName("Search1")]
public ActionResult SearchText(string text) {
return View();
}
[ActionName("Search2")]
public ActionResult SearchType(string Type) {
return View();
}
[ActionName("Search3")]
public ActionResult searchId(int ID) {
return View();
}
now you can do like
/search1
/search2
/search3

Related

Run single method from Multiple Actions in MVC controller

I have the following code that is identical across multiple Action Methods in my controller. Is it possible to reduce this down to a single method and route multiple Actions to it?
[HttpGet]
public ActionResult Tool2(Guid? id)
{
var model = _viewModelFactory.CreateViewModel<Guid?, ToolsViewModel>(id);
return model.ReferenceFound ? View(model) : View("~/Views/Tools/InvalidReference.cshtml", model);
}
[HttpGet]
public ActionResult Tool1(Guid? id)
{
var model = _viewModelFactory.CreateViewModel<Guid?, ToolsViewModel>(id);
return model.ReferenceFound ? View(model) : View("~/Views/Tools/InvalidReference.cshtml", model);
}
Each Action does has a unique View and this needs to be retained.
Make a common method which both actions will call. Leave both actions separate as it will be clearer to understand than to write (and read!) custom routes.
public ActionResult Tool1(Guid? guid)
{
return CommonAction(guid, "Tool1");
}
public ActionResult Tool2(Guid? guid)
{
return CommonAction(guid, "Tool2");
}
private ActionResult CommonAction(Guid? guid, string viewName)
{
var model = _viewModelFactory.CreateViewModel<Guid?, ToolsViewModel>(id);
return model.ReferenceFound ?
View(model) : View("~/Views/Tools/InvalidReference.cshtml", model);
}

The controller for path ... was not found or does not implement IController

I am writing an application using ASP.NET MVC 5 using c#. I have a need to add a global menu on the upper right hand side of the application. I was advised other SO to use action with ChildActionOnly attribute.
So here is what I have done.
I created a BaseController like this
public class BaseController : Controller
{
[ChildActionOnly]
public ActionResult ClientsMenu()
{
using (SomeContext db = new SomeContext())
{
return PartialView(db.Database.SqlQuery<Client>("SELECT * FROM clients").ToList());
}
}
}
Then I inherited all my controllers from BaseController like so
public class TasksController : BaseController
{
public ActionResult Index(int ClientId)
{
...
return View();
}
public ActionResult Show(int SurveyId)
{
...
return View();
}
}
To render the ClientsMenu in my layout I added the following code
#Html.Action("ClientsMenu", "Menus")
Now when I run my application I get the following error
The controller for path '/Tasks/Index' was not found or does not implement IController.
When I remove #Html.Action("ClientsMenu", "Menus") from the layout everything works fine but the global menu does not show of course.
What can I do to resolve this issue?
Updated
Here is what I have done after the feedback I got from the comments below
public class TasksController : Controller
{
[ChildActionOnly]
public ActionResult ClientsMenu()
{
using (SomeContext db = new SomeContext())
{
return PartialView(db.Database.SqlQuery<Client>("SELECT * FROM clients").ToList());
}
}
public ActionResult Index(int ClientId)
{
...
return View();
}
public ActionResult Show(int SurveyId)
{
...
return View();
}
}
but still the same error
Take ClientMenus Action out of the BaseController and put it into its own controller MenusController. You can then call that controller from your Views.
#Html.Action("ClientsMenu", "Menus")
In your example you don't have a MenusContoller which is what #Html.Action("ClientsMenu", "Menus") is looking for.
The Phil Haacked - Html.RenderAction and Html.Action article linked to by the other post provided a good example for you to follow.

All Views are not Loading in Browser

When I load the default page (http://localhost/MVCP/Home/index) it loads correctly, whereas when I load another view (http://localhost/MVCP/Home/Create) it doesn't load. How can I fix this?
My Create action in HomeController:
[HttpGet] [ActionName("Create")] public void Create() { }
Q: Do you have an action in your HomeController called Create?
A: Yes, [HttpGet] [ActionName("Create")] public void Create() { }
Your action return value is void and probably you even didn't write anything in response. change the signature of action to have an ActionResult as return a View.
public ActionResult Create()
{
return View();
}
To learn more:
Adding a View
in Getting Started with ASP.NET MVC 5 Series.
May be there is no view you have created so far and it seems your controller are inside area folder so have u checked your routeing too.
I think your Action should return ActionResult or ViewResult but certainly not "void" as you have written currently.
and also you should write
return view();
in Create action

how to override a action method in the controller with same name and signature.?

public ActionResult ListRss(int languageId)
{
return View();
}
public ActionResult ListRss(int languageId)
{
return View() ;
}
I have this two method, Here I just want to override first method with the second one. My goal is to just keep the first method unused for the reference and make the another method.
Is it Possible any way..?
as names of the actions are very strongly binded with the request params and routing mechanism.. you simply can not do much as far as i know.. ofcourse you can differentiate them by attributes of which type of request is going to made...
[HttpPost]
public ActionResult ListRss(int languageId)
{
return View();
}
[HttpGet] // or any other http types
public ActionResult ListRss(int languageId)
{
return View() ;
}
other way which is more complicated is to create own controller factory..
You can't have methods with the same name and signature in one class. You have to rename one of them if the signature is the same.
If you don't want to use the first method, maybe you should just comment it out and keep it as reference in comments.

MVC4 Ignoring [HttpGet] and [HttpPost] attributes

I am attempting to make a simple test website to allow me to list, create, edit and delete customer objects using MVC4.
Inside my controller I have 2 create methods, a Get for when the form loads with the controls, and a Post that actually saves the data.
//
// GET: /Customer/Create
[HttpGet]
public ActionResult Create()
{
return View();
}
//
// POST: /Customer/Create
[HttpPost]
public ActionResult Create(Customer cust)
{
if (ModelState.IsValid)
{
_repository.Add(cust);
return RedirectToAction("GetAllCustomers");
}
return View(cust);
}
However when I run the project and attempt to access the create action I get an error that:
The current request for action 'Create' on controller type 'CustomerController' is ambiguous between the following action methods:
System.Web.Mvc.ActionResult Create() on type [Project].Controllers.CustomerController
System.Web.Mvc.ActionResult Create([Project].Models.Customer) on type [Project].Controllers.CustomerController
My I understand that it can't see the difference between my Get and Post methods, but I have added the attribues. What could be the cause of this and how can I make it work again?
MVC does not authorize you to have 2 action methods with the same name.
BUT you can have 2 action methods with the same URI when the http verb differs (GET, POST). Use the ActionName attribute to set the action name. Don't use the same methods names. You can use any name. A convention is to add the http verb as the method suffix.
[HttpPost]
[ActionName("Create")]
public ActionResult CreatePost(Customer cust)
{
if (ModelState.IsValid)
{
_repository.Add(cust);
return RedirectToAction("GetAllCustomers");
}
return View(cust);
}

Categories

Resources