I've seen several MVC4 tutorials that show how to access the index URL for a view, but I can't seem to reach a new view that I add.
I can access my home index at:
http://localhost:3214/
But if I create a new view (let's call it "NewView.cshtml") I can't access it from
http://localhost:3214/NewView.cshtml
Where would it be?
The page inspector expects the page to be at:
http://localhost:4244/Home/NewView
But it isn't there.
UPDATE:
In the solution explorer the file is located at:
MyProject/Views/Home/NewView.cshtml
OK - So think of your Views as merely html files (although they are not) - i.e. they are purely for display purposes. But they are not static like normal HTMLs - they have code.
Hence its the controller and the route that you need to understand.
The route is what you type in the browser. For instance /Home/NewView will be translated to HomeController, NewView action if thats how you have configured it. The default view is {controller}/{action}/{id} so try http://localhost:4244/Home/NewView/1
Now to properly display and code NewView you need to go to your HomeController and add a NewView action. Like:
public ActionResult NewView()
{
return View(); // This will automatically display the NewView.chtml view from the Home (or Shared) folder in your Views folder
}
Then go to your Routes (typically in your global.asax file and add it like:
routes.MapRoute(
"SomeUniqueRouteName",
"Home/NewView",
new { controller = "Home" action = "NewView" }
);
Then you can call it like http://localhost:4244/Home/NewView without the id cause you haev specified a route for it.
Let me know if you need any more help.
Related
I have a very simple navigation stack consisting of a root page and then a model page on top of it. My root page is being set as the root by being the first page to be registered with Shell.
public AppShell()
{
InitializeComponent();
// opening view
Regester<LoginPage>();
Regester<SignUpPage>();
...
}
private void Regester<T>()
{
System.Diagnostics.Debug.WriteLine($"Regestering with shell : {typeof(T).Name} - {typeof(T)}");
Items.Add(new ShellContent { Route = typeof(T).Name, ContentTemplate = new DataTemplate(typeof(T)) });
Routing.RegisterRoute(typeof(T).Name, typeof(T));
}
}
Then I am navigating to the model sign up page using relative routing
Shell.Current.GoToAsync("SignUpPage");
or I will use absolute routing
Shell.Current.GoToAsync("///LogInPage/SignUpPage");
then I will attempt to navigate back in the stack using
Shell.Current.GoToAsync("..");
But I get this exception
Global routes currently cannot be the only page on the stack, so absolute routing to global routes is not supported. For now, just navigate to: LoginPage/
At the time of exception the CurrentState.Location property is this
Location = {///LoginPage/SignUpPage}
I don't understand why this is happening. This will also happen if I am further into the stack and doing something like trying to navigate back from a detail page. What do I need to do to be able to use GoToAsync("..") properly?
Cause:
Your path ///LogInPage is invalid . Global routes currently can't be the only page on the navigation stack. Therefore, absolute routing to global routes is unsupported.
Solution:
Navigation can also be performed by specifying a valid relative URI as an argument to the GoToAsync method. The routing system will attempt to match the URI to a ShellContent object. Therefore, if all the routes in an application are unique, navigation can be performed by only specifying the unique route name as a relative URI:
await Shell.Current.GoToAsync("SignUpPage");
I have simple tree structure in SilverStripe.
ParentPage and ChildPage.
On ParentPage I display the list of ChildPages. But I don't want to make accessible url:
/parent-page/child-page
I want to allow only
/parent-page
That's why I did redirect in ChildPage index action to ParentPage:
class ChildPage_Controller extends Page_Controller
{
public function index()
{
$this->redirect('/parent-page/');
}
}
It works well on frontend. But in CMS after I click to ChidPage in tree, it redirects me editing the ParentPage. (not to frontend url but to admin/pages/edit/show/ParentPageID ). This happen only in Split or Preview mode.
Can you advice how to prevent it? Or is there some other option? Thanks!
In the init function you can check if the user has permission to view the CMS and if the page currently has the stage get variable set:
class ChildPage_Controller extends Page_Controller {
public function init() {
parent::init();
if (!($this->getRequest()->getVar('stage') && Permission::check('VIEW_CMS'))) {
return $this->redirect($this->Parent()->Link(), 301);
}
}
}
This way a normal user will be redirected and a CMS user that isn't viewing the page with ?stage=... set will be redirected. The preview / split panes always set the stage get variable so the page will never be redirected when viewed in the preview / split pane.
so finally I found the solution.
Preview pane is displayed in an iframe. And parent CMS frame binds for changing the url of preview pane. It's because when you click to some link in preview pane, CMS navigates you to edit that page. So also when I do the redirect from ChildPage to ParentPage, the CMS pane catches the change of url and editor is redirected to the ParentPage.
I haven't found the way, how to prevent it, finally I needed to edit javascript of CMS (LeftAndMain.Preview.js line 251).
iframe.bind('load', function() {
self._adjustIframeForPreview();
// Load edit view for new page, but only if the preview is activated at the moment.
// This avoids e.g. force-redirections of the edit view on RedirectorPage instances.
// self._loadCurrentPage();
$(this).removeClass('loading');
});
So I commented out this line "self._loadCurrentPage();"
In the comment was written "This avoids e.g. force-redirections of the edit view on RedirectorPage instances." But it did the redirect anyway.
Maybe there's better way how to do that, but I haven't found it.
I have a master.cshtml with a navigation bar. My first link is to another view, ProjectManagement
<li>Project Management</li>
master.cshtml is in /Views/Shared/_master.cshtml
ProjectManagement is in /Views/ProjectManagement.cshtml
Whenever I click on the link I get:
Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.
Requested URL: /Views/ProjectManagement.cshtml
Am I using the wrong path or should I try to access the page differently?
Edit: I was able to get close by using this:
<a href="#Html.Action( "ProjectMgmt", "Service", "Project Management" )">
The only problem is that it now puts the page into my navigation bar! I only want it to link to page, what could I be doing this time?
You don't link to directly to views, you link to actions. Actions are implemented as methods on a controller; these methods are located using the routing system.
Example Controller:
public class ServicesController : Controller
{
[HttpGet]
public ActionResult ProjectManagement()
{
// automatically locates the correct view; you can also explicitly
// pass the path to the view
return View();
}
}
You can now right-click on the action method name ("ProjectManagement") and select "Add View". This will help you create a new view, and put it in a location which can be automatically found by the view engine.
Views are typically placed in a "Views/[ControllerName]/" folder, e.g. "Views/Services/ProjectManagement.cshtml".
To link to this action method in your navigation bar, you can use the helper method ActionLink().
<li>#Html.ActionLink( "Project Management", "ProjectManagement", "Services" )</li>
See also: Controllers and Routing
I'm very new to ASP.NET MVC and this is probably a really obvious thing...Basically, I can't access the "Forum" view which I had created inside "Home" folder (because I need a link to Forum on my main homepage.). I was wondering if it's okay to just move the Forum view into the Shared folder?
Is this somehow very bad practice? It seems like I have strong coupling now, because on the one hand the forum view gets called inside HomeController, and on the other hand it will pretty much always
be used with ForumController from now on. So that might be unnecessary/wrong somehow?
edit: If I do this, the URLs change in a weird way, there must be a better solution right?
First when I click on forum link on main page, I'm at: /Home/Forum. I look at the forum, everything is fine.
Now I click on "Post a topic", and after the roundtrip I'm at /Forum/PostTopic. Home is gone.
If you have a ForumController its associated views need to be located at ~/Views/Forum.
For example:
public class ForumController: Controller
{
public ActionResult Index()
{
return View();
}
}
and then you would have the corresponding view in ~/Views/Forum/Index.cshtml:
#{
ViewBag.Title = "Forum";
}
<h2>Forum</h2>
<p>
Put content here.
</p>
and finally you generate a link to the Index action of the ForumController like this:
#Html.ActionLink("Go to forum", "Index", "Forum")
I'm starting a new ASP.NET MVC project, and I decided to put my controllers in a different assembly. Evertyhing works fine, but I have hit a problem: I created a new area in my MVC Project, called Administration. I have an AdminController Class in my seperate assembly which is supposed to return views from my Admin area, but everytime it tries to return a view,
it looks for it in the wrong place (~/Admin/SomeView.cshtml Instead of ~/Administration/Admin/SomeView.cshtml)
How can I tell the controller to look for views in the wanted area?
Please take a look into this article. And also you problem was answered here.
Basically you will need to extend MvcViewEngine, to tell MVC to look for your Views in the different from standatd pathes:
public class YourMegaViewEngine : WebFormViewEngine
{
public YourMegaViewEngine ()
{
ViewLocationFormats = new string[]
{
"~/Views/Administration/{1}/{0}.cshtml" //I may be wrong for you case, but this is the place to puth you path
};
}
}