Render Action from area in layout page of mvc - asp.net-mvc

I want to Render Index() action off my Area (named Menu) in Layout Page of my main MVC project by this code
and got Error on this line of layout
#{Html.RenderAction("Index", "Menu", new { area = "" }); }
Error executing child request for handler 'System.Web.Mvc.HttpHandlerUtil+ServerExecuteHttpHandlerAsyncWrapper'.
and this is my AreaRegistration Code just for inform:
public override string AreaName
{
get
{
return "Menu";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Menu_default",
"Menu/{controller}/{action}/{id}",
new { controller = "Menu", action = "Index", id = UrlParameter.Optional },
new string[] { "Menu.Controllers" }
);
}
as you see my controller name is Menu
Edited: the main reason of my problem is this ...Index action off my area cant return his view ...i was set one break point in Index action, and one break point inside of Index view ... and the program is reaching and stop on first one,but never stops in second one!! ...
So
the main problem is this ...Index action of my area doesn't return Index view..

Try this One
#Html.Action("Index", "Menu")

i solve it. actually, only solution to do this thing was using RenderPartial with direct path:
#{ Html.RenderPartial("~/Areas/Menu/Views/Menu/Index.cshtml");}

Related

How to utilize a user-defined url action in asp,net mvc?

My hope is to provide a method to end users that will let them enter a value 'SmallBuildingCompany', and then use this value to make a custom url that will redirect to an informational view. so for example, www.app.com/SmallBuildingCompany. Can anyone point me to some information to help on this?
edited 161024
My attempt so far:
I added this within RouteConfig.
RouteTable.Routes.MapRoute(
"Organization",
"O/{uniqueCompanyName}",
new { controller = "Organization", action = "Info" }
and added a new controller method and view under the organization controller.
public async Task<ActionResult> Info(string uniqueCompanyName)
{
var Org = db.Organizations.Where(u => u.uniqueCompanyName == uniqueCompanyName).FirstOrDefault();
Organization organization = await db.Organizations.FindAsync(Org.OrgId);
return View("Info");
}
You can achieve this by using the SmallBuildingCompany part of the URL as a parameter for an action that is used to display every informational view.
Set up the Route in Global.asax.cs to extract the company name as parameter and pass it to the Index action of CompanyInfoController:
protected void Application_Start() {
// Sample URL: /SmallBuildingCompany
RouteTable.Routes.MapRoute(
"CompanyInfo",
"{uniqueCompanyName}",
new { controller = "CompanyInfo", action = "Index" }
);
}
Note that this Route will probably break the default route ({controller}/{action}/{id}), so maybe you want to prefix your "Info" route:
protected void Application_Start() {
// Sample URL: Info/SmallBuildingCompany
RouteTable.Routes.MapRoute(
"CompanyInfo",
"Info/{uniqueCompanyName}",
new { controller = "CompanyInfo", action = "Index" }
);
}
Then the CompanyInfoController Index action can use the uniqueCompanyName parameter to retrieve the infos from the database.
public ActionResult Index(string uniqueCompanyName) {
var company = dbContext.Companies.Single(c => c.UniqueName == uniqueCompanyName);
var infoViewModel = new CompanyInfoViewModel {
UniqueName = company.UniqueName
}
return View("Index", infoViewModel);
}
ASP.NET Routing

Two partial views inside an MVC view

I have the following scenario, where I have one model (named Model A) in a view (View1).
This view initially loads a partial view (Partial View 1)
On button click of partial view, I am trying to pass the id generated to another partial view (Partial View 2).
But I am getting an error saying View 1 cannot be found, which loaded without any issues on first run.
If I remove the else statement, the page successfully reloads after submission.
Any tips on passing this model object successfully to the other view please.
I put id=1 and tested it and the same error occured.
I tried RenderAction, RenderPartial and all these failed
Page
#model MyModel
#{
if (ViewBag.Created ==0) {
#Html.Partial("CreateView1",Model);
}
else
{
{ Html.Action("Action2", "Area/Controller2", new { id = Model.Id }); }
}
}
Controller methods:
Controller 1:Entry point of view
[Route("{CreateView1}")]
public ActionResult Create() {
ViewBag.Created = 0;
return View(new MyModel());
}
[Route("{CreateView1}")]
[HttpPost]
public ActionResult Create(MyModel model) {
...........................
ViewBag.Created = 1;
}
Controller 2 which renders 2nd partial view:
public PartialViewResult Index(int createdId)
{
return PartialView(new List<Model2>());
}
Regarding View 1 cannot be found, is because the keyword return in your second Create action is missing. The button click submits the form to the Create method with [HttpPost] attribute and the end of the method, it needs a return View.
Reg Any tips on passing this model object successfully to the other view please, The return in the second Create method should be return View(model); and not 'return View(new MyModel);` as later on in the View you are going to use the Model.
Re I put id=1 and tested it and the same error occured., because runtime never reachs that point as the operation is being handed to '[HttpPost] Create' and it never get back to your Original Page.
There are other issues with your code as you are using different names in your code than what you mention in your description...
A simple solution is:
1- use the following return at the end of you [HttpPost]Create Action:
return RedirectToAction("Action2", "Area/Controller2", new { id = model.Id});
2- replace the following code in your initial page
if (ViewBag.Created ==0) {
#Html.Partial("CreateView1",Model);
}
else
{
{ Html.Action("Action2", "Area/Controller2", new { id = Model.Id }); }
}
with the following:
#Html.Partial("CreateView1",Model);
and remove anywhere you set ViewBag.Created = 0 or ViewBag.Created =1
I also assume the action action2 in controller Controller2 returns a valid Partial View.
Hope this help you get some idea to fix your code.
You may have omitted this for brevity, but you will want to return a viewresult at the end of your post action:
return View(new MyModel());
try this:
if (ViewBag.Created ==0) {
#Html.RenderPartial("CreateView1",Model);
}

ASP.NET MVC Areas in Individual Projects - Refactor AreaRegistration Stuff

I'm trying to molularize my ASP.NET MVC application by moving each Area into their own project. Everything was working fine until i decided to refactor out the AreaRegistration stuff and use my own approach (This way i can also register filters and dependencies within my module). Using reflector i have managed to come up with the following.
First i implement the following interface for each module/area:
public interface IModule {
string ModuleName { get; }
void Initialize(RouteCollection routes);
}
E.g.:
public class BlogsModule : IModule {
public string ModuleName { get { return "Blogs"; } }
public void Initialize(RouteCollection routes) {
routes.MapRoute(
"Blogs_Default",
"Blogs/{controller}/{action}/{id}",
new { area = ModuleName, controller = "Home", action = "Index",
id = UrlParameter.Optional },
new string[] { "Modules.Blogs.Controllers" }
);
}
}
Then in my Global.asax file (Application_Start event) i say:
// Loop over the modules
foreach (var file in Directory.GetFiles(Server.MapPath("~/bin"), "Modules.*.dll")) {
foreach (var type in Assembly.LoadFrom(file).GetExportedTypes()) {
if (typeof(IModule).IsAssignableFrom(type)) {
var module = (IModule)Activator.CreateInstance(type);
module.Initialize(RouteTable.Routes);
}
}
}
I then removed the existing AreaRegistration stuff. Everything is working fine up to this point. When i run my application and render the link to a module, e.g.:
#Html.ActionLink("Blogs", "Index", "Home", new { area = "Blogs" }, null)
The correct url is displayed but when i click on the url it displays the wrong view. After debugging it looks like the url is routed to the correct Action within the HomeController of my Blogs module. However it tries to display the Home/Index.cshtml view in the main project and not the one in the module/area. I'm guessing somewhere along the lines i have missed how to tell the view engine to treat the routed url as an area as it seems to be ignoring the AreaViewLocationFormats (inside the RazorViewEngine).
I'd appreciate it if someone could show me what i'm missing. Thanks
After further refactoring it appears that, the view engine looks for an area data token. I therefore changed the code to add routes in Initialize method of the module as:
// Create the route
var route = new Route("Blogs/{controller}/{action}/{id}", new RouteValueDictionary(new { area = ModuleName, controller = "Home", action = "Index", id = UrlParameter.Optional }), new MvcRouteHandler());
// Add the data tokens
route.DataTokens = new RouteValueDictionary();
route.DataTokens["area"] = this.ModuleName;
route.DataTokens["UseNamespaceFallback"] = false;
route.DataTokens["Namespaces"] = new string[] { "Modules.Blogs.Controllers" };
// Add the route
routes.Add(route);
Hope this helps.

How can I redirect to "page not found" with MVC3?

I have some links in Google that I now no longer expect to work. All of the links look like this:
www.abc.com/xx/que=xxxxxxxxxxx
Where x can be anything.
Can someone tell me how I can set up a route and controller action that will return a 404 to google? I guess I need to set it up with a mask that includes "que" but I am not so sure how to do this.
Add a new route to the top of your global.asax. This will catch requests of the form xx/que={anything} using a regular expression to define the "que" argument.
routes.MapRoute(
"PageNotFound",
"xx/{que}",
new { controller = "Error", action = "NotFound" },
new { que = "que=.*" });
This would also assume you have an ErrorController with action NotFound and corresponding view named NotFound.aspx in your /Views/Error/ directory.
public class ErrorController : Controller
{
public ActionResult NotFound()
{
Response.StatusCode = 404;
return View();
}
}

How to get current controller and action from inside Child action?

I have a portion of my view that is rendered via RenderAction calling a child action. How can I get the Parent controller and Action from inside this Child Action.
When I use..
#ViewContext.RouteData.Values["action"]
I get back the name of the Child Action but what I need is the Parent/Calling action.
Thanks
BTW I am using MVC 3 with Razor.
And if you want to access this from within the child action itself (rather than the view) you can use
ControllerContext.ParentActionViewContext.RouteData.Values["action"]
Found it...
how-do-i-get-the-routedata-associated-with-the-parent-action-in-a-partial-view
ViewContext.ParentActionViewContext.RouteData.Values["action"]
If the partial is inside another partial, this won't work unless we find the top most parent view content. You can find it with this:
var parentActionViewContext = ViewContext.ParentActionViewContext;
while (parentActionViewContext.ParentActionViewContext != null)
{
parentActionViewContext = parentActionViewContext.ParentActionViewContext;
}
I had the same problem and came up with same solution as Carlos Martinez, except I turned it into an extension:
public static class ViewContextExtension
{
public static ViewContext TopmostParent(this ViewContext context)
{
ViewContext result = context;
while (result.ParentActionViewContext != null)
{
result = result.ParentActionViewContext;
}
return result;
}
}
I hope this will help others who have the same problem.
Use model binding to get the action name, controller name, or any other url values:
routes.MapRoute("City", "{citySlug}", new { controller = "home", action = "city" });
[ChildActionOnly]
public PartialViewResult Navigation(string citySlug)
{
var model = new NavigationModel()
{
IsAuthenticated = _userService.IsAuthenticated(),
Cities = _cityService.GetCities(),
GigsWeBrought = _gigService.GetGigsWeBrought(citySlug),
GigsWeWant = _gigService.GetGigsWeWant(citySlug)
};
return PartialView(model);
}

Resources