Why is #Html.ActionLink leaving off the controller and action portions of the link? - asp.net-mvc-routing

I am creating a link inside the main _Layout.cshtml file inside a MVC3 application.
#Html.ActionLink("Security", "Index", "Home", new { area = "Security" }, new { })
When the page is rendered, this is the resultant Html
Security
and if I click on this link, I get a blank page.
I have routedebugger installed and here are the results:
I have the default route inside the Global.ascx.cs as follows:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
new string[] { "Eis.Mvc.Web" }// Parameter defaults
);
and the Security Area's route:
context.MapRoute(
"Security_default",
"Security/{controller}/{action}/{id}",
new { area = "Security", controller = "Home", action = "Index", id = UrlParameter.Optional },
new string[] { "Eis.Mvc.Web.Areas.Security.Controllers" }
);
If I directly type in the following URL, http://localhost:1410/Security/home, the correct page is presented.
How can I get the #Html.Action link to include the controller portion of the URL?
I do have a Home controller with an Index action inside the root portion of the application and had to include the Namespace filters to the route registrations.
Thank you,
Keith

Change the Security Area's route mapping to the following:
context.MapRoute(
"Security_default",
"Security/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional },
new string[] { "Eis.Mvc.Web.Areas.Security.Controllers" }
);
Notice the area and controller portions of the defaults parameter were removed.
Now the #Html.ActionLink("Security", "Index", "Home", new { area = "Security" }, new { }) renders Security
Keith

Related

How to access component model from outside

I have created a shell-in-shell construct in the index.html:
sap.ui.getCore().attachInit(function () {
// create a new Shell that contains the root view
var oShell = new sap.m.Shell({
id: "appShell",
app: new sap.ui.core.ComponentContainer({
name: "internal_app",
height: "100%"
})
});
// load the view that contains the unified shell
var oAppShellView = sap.ui.view({
type: sap.ui.core.mvc.ViewType.XML,
viewName: "internal_app.view.AppShell"
});
// access the unified shell from the view
var oUnifiedShell = oAppShellView.byId("unifiedShell");
// place the app shell in the unified shell
oUnifiedShell.addContent(oShell);
oAppShellView.placeAt("content");
});
In addition, a default model has been defined in manifest.json:
....
},
"models": {
"": {
"type": "sap.ui.model.json.JSONModel"
}
},
....
In the controller of the view internal_app.view.AppShell (which has been created by the code snippet above) I would now like to access the default model but neither this.getModel() nor this.getOwnerComponent().getModel() (getModel() and getOwnerComponent() return undefined) worked. I assume that the AppShell controller does not have an owner. But how can I access the default model in the onInit of that controller?
The app structure in your case is somewhat unusual - Nevertheless, you can always access the model, defined in manifest.json, as long as you can access the inner component.
Assuming this is referencing the controller of the internal_app.view.AppShell, you can get the default model like this:
onInit: function() {
var innerShell = sap.ui.getCore().byId("appShell"); // only if the app is standalone
this.componentLoaded(innerShell.getApp()).then(this.onComponentCreated.bind(this));
},
componentLoaded: function(componentContainer) {
var component = componentContainer.getComponent();
return component ? Promise.resolve(component) : new Promise(function(resolve) {
componentContainer.attachEventOnce("componentCreated", function(event) {
resolve(event.getParameter("component"));
}, this);
}.bind(this));
},
onComponentCreated: function(component) {
var myDefaultModel = component.getModel(); // model from manifest.json
// ...
}

How to manage newly created objects without "saving" before transitioning to a new route it in emberjs?

I have an issue where I have a resource with a new route. When I transition to that new route I create a new object. On the form I have button to cancel, which removes that object. However, if I click a link on my navigation, say going back to the resource index, that object is there with whatever I put in the form. What's the best way of managing creating objects then moving away from the form?
My routes:
App.Router.map(function() {
this.resource('recipes', function() {
this.route('new');
this.route('show', { path: '/:recipe_id' });
});
this.resource('styles');
});
App.RecipesNewRoute = Ember.Route.extend({
model: function() {
return App.Recipe.createRecord({
title: '',
description: '',
instructions: ''
});
},
setupController: function(controller, model) {
controller.set('styles', App.Style.find());
controller.set('content', model);
}
});
My controller for the new route:
App.RecipesNewController = Ember.ObjectController.extend({
create: function() {
this.content.validate()
if(this.content.get('isValid')) {
this.transitionToRoute('recipes.show', this.content);
}
},
cancel: function() {
this.content.deleteRecord();
this.transitionToRoute('recipes.index');
},
buttonTitle: 'Add Recipe'
});
I'm using version 1.0.0.rc.1
Thanks!
Any code that you place in the deactivate method of your route will get executed every time you leave that route. The following code will delete the new model if the user hasn't explicitly saved it.
App.RecipesNewRoute = Ember.Route.extend({
// ...
deactivate: function() {
var controller = this.controllerFor('recipes.new');
var content = controller.get('content');
if (content && content.get('isNew') && !content.get('isSaving'))
content.deleteRecord();
},
// ...
});
As an added bonus, you now don't need to explicitly delete the record when the user presses the cancel button.

MVC3 Routing From an area to default

Working on an MVC3 project.
I have an area named "Area" with an areaRegistration like this,
context.MapRoute(
"Area_Details",
"Area/{controller}/{AreaId}/{AreaName}/{id}/{action}",
new { controller = "Area", action = "Index" }
);
context.MapRoute(
"Area_default",
"Area/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
I have another controller in /Controller "Home" with action "Details" which returns a PartialView.
From a view in the "Area" area I am trying to
#Html.RenderAction("Details","Home", new{ myId = 1})
which should access /home/details?myId=1
but it is trying to access /area/home/details?myId=1
how can I solve this problem?
I think this will work:
Html.RenderAction("action", "controller", new { area = "" })

how to have minimum AreaRegistrations with putting duplicated elements in single place

i have several AreaRegistration classes which one each registers own routes and each one have some duplicated elements such as bolded text in below:
context.MapRoute("Search", "**{culture}/{style}**/search",
new
{
**culture = cultureValue,
style = styleValue,**
controller = "search",
action = "default"
},
new
{
**culture = new CultureRouteConstraint(),
style = new StyleRouteConstraint()**
});
how i can have minimum AreaRegistrations with putting duplicated elements in single place which handles that? this is possible?
You can add routes to the Global.asax file and use the area route value. For example:
routes.MapRoute("Search", "{culture}/{style}/search", new
{
culture = cultureValue,
style = styleValue,
controller = "search",
action = "default",
area = "areaName"
});

How do I generate a RouteLink to a route in a different area?

I have two different areas, and I have a route in one of those areas that is specific to that area, but I need to generate a link to that route using Html.RouteLink from another area (it's how you get over into the new area) but it won't work... It doesn't seem possible to use RouteLink to routes in a different area.
What is the best way around this? Should I just define a new route in the other area and name it differently?
UPDATE (code):
In master page in the main area (I've tried it multiple ways, all of which have produced same result):
<a href="<%= Url.Action("Index", "Home", new { area = "CustomerSite", route = "CustomerSite_preview", domain = (string)ViewData["DomainName"] }, null) %>">
In the CustomerSite area registration as the first route registered:
context.MapRouteLowercase(
"CustomerSite_preview",
"preview/{domain}/{controller}/{action}/{id}",
new { area = "CustomerSite", controller = "Home", action = "Index", id = "" },
new { isCustomerSite = new CustomerSiteRouteConstraint() },
new string[] { "GrayHills.CarLotHosting.Web.Areas.CustomerSite.Controllers" }
);
In your route object you just need a property named area with the name of the area.
Html.RouteLink("My Link Text",
new { area = "MyArea", controller = "MyController" ... },
null);
You need to change your route definition - see the answer ASP.NET MVC Url.Action routing error for more info.
In essence, your route should look as follows since you explicitly supply the controller name and action:
context.MapRouteLowercase(
"CustomerSite_preview",
"preview/{domain}/home/index/",
new { area = "CustomerSite"
, controller = "Home"
, action = "Index"},
new { isCustomerSite = new CustomerSiteRouteConstraint() },
new string[] {
"GrayHills.CarLotHosting.Web.Areas.CustomerSite.Controllers"}
The Url.Action will look like
<a href="<%= Url.Action("Index"
, new {domain = (string)ViewData["DomainName"] }
, null) %>">
which will result in a Url like http://localhost:56291/preview/somedomainname/home/index