C# ASP MVC : navigate between different controllers views from HTML - c#

I have a problem navigating between different controllers views from HTML
Like for example i have two controllers (User and Transaction)
and in my HTML there is a main menu where it has all the main navigations.
so if i wanna navigate to the User list my view would be "User/List_Users"
and if i am inside the Transaction view
(......com/Transaction)
if i clicked on User List it will navigate to
(......com/Transaction/User/List_Users)
instead of going to
(......com/User/List_Users)
So i tried using The Html Action like like
<li>#Html.ActionLink("User List","User/List_Users")</li>
but didn't do any good :(

<li>#Html.ActionLink("Link Name", "Action")</li>
This is your basic ActionLink. An action is the specific method in the controller (which ultimately serves up a view).
If you need to link to a different controller (you need to link to a Transaction view from a User view, for example), you can do:
<li>#Html.ActionLink("Link Name", "Action", "Controller")</li>

Use the overload which accepts controller name:
#Html.ActionLink("User List","List_Users", "User");

I usually use the following
#Html.ActionLink("Link Text", "Action", "Controller", new { querystringparameter = querystringvalue }, null)
In your case it will be:
#Html.ActionLink("User List", "List_Users", "User", new { querystringparameter = querystringvalue }, null)

Related

ASP.NET MVC map single controller to root of website

I am working on an ASP.NET MVC 5 website that has a public "marketing" website that contains somewhat static pages with information about the company, legal, social, contact us, etc. that a non-logged in user can access. Then, once logged in, there is a back end of the website that registered users have access to features.
Originally I had all the public "marketing" pages going to http://www.mywebsite.com/Marketing/About, http://www.mywebsite.com/Marketing/Social, etc.
However, the business wants all the "marketing" pages, to be accessible a single directory down from the root website, so the links above would be accessible with:
http://www.mywebsite.com/About, http://www.mywebsite.com/Social, etc.
I know I can use the below approach to get it to work by registering individual routes for each "marketing" page like so:
routes.MapRoute(
"ShortAbout",
"About",
new { controller = "Marketing", action = "About" }
);
routes.MapRoute(
"ShortSocial",
"Social",
new { controller = "Marketing", action = "Social" }
);
However, since there are about 15 "marketing" pages, this seems inefficient and it seems like there must be a better way to do this.
I also tried a generic routing approach outlined here: http://www.wduffy.co.uk/blog/aspnet-mvc-root-urls-with-generic-routing/
but the problem with that approach was I had a "marketing" page, with the same name as a controller and it ended up forwarding the user to the marketing subdirectory. For example, I had a Controller called "MachineController", and in the "MarketingController" I had an action/page called "Machine", so it was forwarding the user to /Marketing/Machine using the approach in the above link.
Any other ideas? Thanks in advance.
I had exactly this problem. A much simpler but more hardcoded solution is
routes.MapRoute("MarketingPages", "{action}",
new { controller = "Marketing" },
new { action = #"About|Social" });
The last anonymous object constrains the route to match routes where action matches the supplied regular expression, which is simply a list of the urls you want to have marketing pages. Any other url like '/something' falls through to the routes below.

route not mapping mvc 3

I am new in mvc and I have a situation where I am convinced that I am mapping a route correctly although it is not.
it is a very basic login form with the option of passing in parameters.
this is the html
<li>Login</li>
and this is the action method in the 'Home' controller
public ViewResult LoginForm(string userName)
{
return View();
}
This is how is my attempt at mapping the route
routes.MapRoute(
null,
"Login/{userName}",
new { controller = "Home ", action = "LoginForm", UrlParameter.Optional }
);
The url is however displaying as follow
/Home/LoginForm?loginUser=user
my aim would be the following
Login/user
Advice perhaps as to why it is not mapping correctly. I have already registered a number of routes in the Global.asax.cs file. Could it have something to do with the order with which they were registered?
Try this:
<li>Login</li>
change the parameter loginUser to userName.
Use userName instead of loginUser
<li><a href='#Url.Action("LoginForm", "Home", new {userName="user"})'>Login</a></li>
You are hitting a different address than the one specified in MapRoute. The mapped route will not fire. Change both the parameter and the action name.
<li>Login</li>
You need to access /Home/Login not /Home/LoginForm. The routing is done automatically if the right address is accessed.
EDIT:
Following your address edit:
As far as I know, you cannot generate a link such as Login/{userName} using Url.Action; if you don't specify a controller, this defaults to Home controller
You can however access the Login/{userName} link directly from the browser (due to the mapped route)
You can create a "static" (i.e. classic) link, passing a hard-coded address:
<li>Login</li>
Please note that the userName added/removed per JavaScript.

Is there any way to create special controller for my _Layout?

I am developing a website that has a View called _MainPage in View\Shared folder that other views use that for basic layout of my website, so I have a section in this view that populates data from database in fact this section is latest news of the site and I should show latest news in this section ,in simple way I should make section for example called latestNews :
<ul class="news-list">
#RenderSection("latestNews",required:false)
</ul>
and in each views I should fill this section by razor that data came from relevant controller :
#foreach (var item in Model.News)
{
<div>
<p>#Html.Raw(item.Body)<br />ادامه مطلب</p>
</div>
}
in fact I have latest news in every views in footer of my pages.
now my question is : How can define a custom controller for my View (_MainPage) that haven't do these routine in each view. Is there any generic way to accomplish that?
Any public method in a controller class is an action method. Every action method in a controller class can be invoked via an URL from web browser or a view page in application.
Your scenario is some dynamic information (data) need to displayed on couple pages in your application. Generally we end up in adding that data to model passed to views by action methods. We duplicate same data in multiple models where we brake DRY (Don’t Repeat Yourself) principle.
To handle this scenario ASP.NET MVC provides child action methods. Any action method can be child an action method but child actions are action methods invoked from within a view, you can not invoke child action method via user request (URL).
We can annotate an action method with [ChildActionOnly] attribute for creating a child action. Normally we use child action methods with partial views, but not every time.
[ChildActionOnly] represents an attribute that is used to indicate that an action method should be called only as a child action.
[ChildActionOnly]
public ActionResult GetNews(string category)
{
var newsProvider = new NewsProvider();
var news = newsProvider.GetNews(category);
return View(news);
}
Above child action method can be invoked inside any view in the application using Html.RenderAction() or Html.Action() method.
#Html.Action("GetNews", "Home", new { category = "Sports"})
(or)
#{ Html.RenderAction("GetNews", "Home", new { category = "finance"}); }
Instead of a section, you can use Html.RenderAction to specify a controller and an action. The action should return a partial view which is then integrated within the calling site.

Mvc3 Wizard with separate controller actions

I'm putting together a wizard in mvc3/c#. I have a model setup roughly
public interface IStepView {}
public class Step1View : IStepView {}
public class Step2View : IStepView {}
I have a parent view which displays 1 of 2 partial views for these steps.
I would like the form submission for Step 2 to use a custom action on the same controller. Reading similar posts it seems what I need to do is add a custom route like so
RouteTable.Routes.MapRoute("Step2Route", "", new { controller = "Demo", action = "MyAction" });
which I wire together on the Main.cshtml
#using (Html.BeginForm())
{
#Html.BeginRouteForm("Step2Route", new { controller = "RolloverController", action = "Stuff" })
// and so on for each Step I want to use a custom action
}
Is this the way to do it?
If you didn't know the number of steps in the wizard, a custom route might make sense to allow for tracking of progress in the wizard.
i.e. Wizard/{WizardName}Step/{StepNumber}/
But since it looks like you do know the steps, your actions on the controller can correspond to them without custom routes:
i.e RegistrationWizard/EnterInfo, RegistrationWizard/Confirm, RegistrationWizard/Success
Create a get and post method for each action on the controller. Take the same model and pass it along using RedirectToAction or store it in session, so that you keep track of the changes that the user is making to the data before committing the data on the final step.

Is it possible to use one layout page for every view, including area views?

I have a layout page in ~/Views/Shared/_Layout.cshtml and it works great for all normal views that get rendered. However, I created an area called "Demos" and in the ~/Areas/Demos/Views/_ViewStart.cshtml file I pointed it to my original layout page.
This works just fine except some calls to #Html.ActionLink() are now being prefixed with the area name. So where #Html.ActionLink("Blog", "Index", "Blog") would normally generate a link like "website.com/Blog/Index" on area views it generates "website.com/Demos/Blog/Index".
Any ideas?
To use areas open the Global.asax file and insert the following code into the Application_Start method
AreaRegistration.RegisterAllAreas();
You can link within an area as you would in any MVC application but to generate a link to a different area, you must explicitly pass the target area name in the routeValues parameter for these methods.
#Html.ActionLink("Blog", "Index", "Blog", new { area = "blog" }, null)
null parameter is required only because the ActionLink method overloads that have a routeValues parameter also have an htmlAttributes parameter but it is not required in order to be able to link between areas.
UPDATE
You can use RouteLink() instead of ActionLink(), to bypass the area registrations.
#Html.RouteLink("Blog", "MyRoute", new { action = "Index", controller = "Blog" })
The second parameter ("MyRoute") is a route name registered in Global.asax so to use RouteLink() to link between different areas, you only need to specify the correct route name.

Categories