If I have MVC controller that is using something like,
public ActionResult Index()
{
return View();
}
public ActionResult Display()
{
return View();
}
When I run something like this it does not seem to recognize the action for "Display", suppose I use an action link in razor for example,
#Html.ActionLink("Display", "Display")
For what whatever reason this is not routing to the new action result I created, "Display", when ActionLink is clicked. What is the proper way to do this? Do I need a separate controller for this new action?
For your example:
#Html.ActionLink("Display", "Display")
The first parameter is your linkText and the second parameter is the actionName. You really should add a third parameter for your controllerName. So, for example, this:
#Html.ActionLink("Display", "Display", "Home")
Would mean "Display" is shown as your link text, and the link would navigate to the HomeController and call the Display action method as desired.
In my example above, the resulting HTML source would look like this:
Display
("/Home" is not shown as it is implied to be to top level depending on default routing configuration)
Clear?
Related
is it possible to go to a different View without changing the URL? For example in my Index View, I have a link to go the the Details View but I would like to keep the URL the same.
Thank you very much,
Kenny.
As already mentioned, you could make the Details link an Ajax.ActionLink and use this to change the content of a div.
Failing that, the only other way I can think of doing it is by making your details link a button and POST to your index action. You could apply CSS to the button to make it appear more like a normal html link.
public class HomeController : Controller {
public ActionResult Index() {
return View("Index");
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Index(int hiddenInputFieldId) {
return View("Details");
}
}
EDIT:
Based on JonoW's comment, you'll have to pass in a 'fake' param with your post, this is not really a problem though, you can just use a hidden input field for it.
You can return the same view from multiple controller actions, but each controller action requires a unique URL:
public class HomeController : Controller {
public ActionResult Index() {
return View("home");
}
public ActionResult About() {
return View("home");
}
}
If you want a link to load up content from a different page without changing the URL, you'll have to use some Ajax to call the server for the content and update the parts of the page you need to change with the new content.
I don't know why you would like to do that, but you could have an Ajax.Actionlink which renders the Details View..
There is almost no reason to hide an URL, not sure what you would like to to.. maybe you explain further that someone can give a better approach.
You can use a good old Server.Transfer for this. However, I'd suggest doing it like has been detailed in this SO post. This gives you an easy way to return an ActionMethod from your current action without peppering your code with Server.Transfer() everywhere.
You can do this by rendering partials- I do this to load different search screens. Sample code is as follows (this is slightly different to my actual code, but you'll get the idea):
<% Html.RenderPartial(Model.NameOfPartialViewHere, Model.SomeVM); %>
Personally though, I don't see why you don't just change the URL?
I have a view that looks like this:
http://whatever/Download/viaId/12345
And i would like to call the action
public void viaId (int Id)
{
//Code
}
when the page loads. Right now I only have the controller implemented and when I browse the url the parameter Id is null.
Do i need to create the view and call it through javascript ?
Ok i got it solved. I did not have the parameter mapped on the RouteCollection. thanks for your suggestions
It sounds like you don't have a view, you just have a URL and an action.
You should create a view called "viaId" for your Controller to give to the user. The easiest way to do this is to right click on the action and click "Add View" (assuming you're using Visual Studio).
Additionally, the viaId method should probably return ActionResult instead of void.
I think you just need to add the attribute
[AcceptVerbs(HttpVerbs.Get)]
public void viaId(int id) {}
How can I get the actual "Main-Controller" in a RenderAction?
Example:
MyRoute:
{controller}/{action}
My url my be:
pages/someaction
tours/someaction
...
In my Site.Master I make a RenderAction:
<% Html.RenderAction("Index", "BreadCrumb"); %>
My BreadCrumbController Action looks like this:
public ActionResult Index(string controller)
{
}
The strings controller contains "BreadCrumb" (which is comprehensible because actually I am in BreadCrumbController).
What's the best way to get the "real" controller (e.g. pages or tours).
Parent view/controller context
If you use MVC 2 RC (don't know about previous releases) you can get to parent controller via view's context, where you will find a property called:
ViewContext ParentActionViewContext;
which is parent view's context and also has a reference to its controller that initiated view rendering...
Routing
It seems to me (from your question) that you have requests with an arbitrary number of route segments... In this case you have two options:
Define your route with a greedy parameter where actions in this case will catch all actions in your request URL
{controller}/{*actions}
Create a custom Route class that will handle your custom route requirements and populate RouteData as needed.
the second one requires a bit more work and routing knowledge but it will help you gain some more knowledge about Asp.net MVC routing. I've done it in the past and it was a valuable lesson. And also an elegant way of handling my custom route requirements.
Could you pass it as a parameter to the controller?
--Site.master--
<% Html.RenderAction("Index", "BreadCrumb"
new { controller = ViewData["controller"] }); %>
--BreadCrumbController.cs--
public ActionResult Index(string controller)
{
}
--ToursController.cs--
public ActionResult SomeAction(...)
{
// ....
ViewData["controller"] = "Tours"
// You could parse the Controller type name from:
// this.ControllerContext.Controller.GetType().Name
// ....
}
What do you mean with "real" controller? Your action points to one controller.
Do you mean the previous controller? So: the controller that was used to render your view where your link was created that points to your breadcrumbcontroller?
Unless you add the name of that controller to the link as a parameter, there is no way to get to that.
I have written an Action method for an ASP.NET MVC controller, which is being used to provide a model to a usercontrol.
public class ProductsController : Controller
{
public PartialViewResult ProductSummary()
{
ViewData.Model = new ProductSummaryModel("42"); // dummy data for now
return new PartialViewResult()
{
ViewData = ViewData
};
}
}
I am using the 'futures' Microsoft.Web.Mvc dll and rendering the control in my main view like this :
<% Html.RenderAction<ProductsController>(x => x.ProductSummary()); %>
What I have here appears to work just fine, but i attempted to google new PartialResult() to see if what I was doing was following the correct patterns.
Currently this search only comes up with 4 results!
So I figured I'm doing somethin wrong here in my controller. Whats the correct way to create an action method that returns a partial view? And what (if anything) is wrong or bad about what I'm doing.
I usually just use:
return PartialView("MyView", myModel);
But this just returns a new PartialViewResult("MyView", myModel) so it is potatoes/potatoes.
I have an action method, and depending on what is passed to it, I want to redirect to another action in another controller. The action and controller names are determined at run time.
If I return RedirectToAction(), it will force a redirect and change the URL in the browser. What I would like is something like TransferToAction() that can transfer processing of the current request to another action, without doing a redirect. I seem to remember a method behaving like this in earlier previews, but I can't seem to find it in the RC of ASP.NET MVC.
Do you know how I would do this?
UPDATE
I added the following route:
routes.MapRoute(
"PageRouter",
"{site}/{*url}",
new { controller = "PageRouter",
action = "RoutePage", site = "", url = "" }
);
And the PageRouter controller action RoutePage:
public ActionResult RoutePage(string site, string url)
{
var controller = new HomeController {ControllerContext = ControllerContext};
controller.RouteData.Values["controller"] = "Home";
controller.RouteData.Values["action"] = "Index";
return controller.Index(site, url);
}
I had to set the controller and action in RouteData for the Home Index view to be rendered. Otherwise, it would look for an Index view in PageRouterController.
I still need to figure out how to create a controller and its action knowing only their names. e.g. I'd like to be able to just call something like this:
public ActionResult RoutePage(string site, string url)
{
return InvokeAction("Home", "Index");
}
What should go in InvokeAction() ? Do I need to pass it any context?
You should be able to just call the other method directly and, assuming that it returns a ViewResult, it will render that view in response to the request and the url will not change. Note, you'll be responsible for making sure that all of the data that the other method needs is available to it. For example if your other method requires some form parameters that weren't provided, you may need to construct a suitable FormCollection and set the ValueProvider of the controller to a ValueProvider based on your FormCollection. Likewise with any arguments required by the method.