I am studying ASP.NET MVC4. I don't quite understand what the area parameter is in the code below.
<section id="myWorkingSection">
#Html.Action("myActionName", "myController", new { area = "Widgets", workingSection = "myWorkingSection" })
</section>
myActionName takes workingSection as parameter but it does not take area as parameter. My guess is that since Widgets is the name of the folder, is it telling that the controller myController is located in the Widgets folder?
Thank you.
It is a route parameter used to specify the area within MVC.
In your case the area is Widgets.
Walkthrough: Organizing an ASP.NET MVC Application using Areas
Related
I have an ASP.NET vNext (5) project. I am trying to add two areas to the project. My question is, how do I register areas in vNext? The System.Web.Mvc namespace is gone, which is where AreaRegistrationContext was located. I started looking in the MVC source code on GitHub. I found the Area attribute. However, I'm not sure how to utilize it now.
Can someone please explain to me (or provide a link) of how to use Areas in ASP.NET vNext?
Thank you!
In vNext you register and configure the services you are going to use in Startup.cs. Area routes are added like normal routes. There is a sample here: https://github.com/aspnet/Mvc/blob/a420af67b72e470b9481d6b2eca29f7c7c2254d2/samples/MvcSample.Web/Startup.cs
You could add an MVC route for an area like this:
app.UseMvc(routes =>
{
routes.MapRoute("areaRoute", "{area:exists}/{controller}/{action}");
});
Or you could use a route attribute like this: [Route("[area]/Home")]
The [Area] attribute decorates controllers included in the area. It takes only one parameter, the name of the area. Here's an example: https://github.com/aspnet/Mvc/blob/a420af67b72e470b9481d6b2eca29f7c7c2254d2/samples/MvcSample.Web/Areas/Travel/Controllers/HomeController.cs
[Area("Travel")]
public class HomeController : Controller
{ //... }
I don't have so much experience using AJAX in a MVC application, in fact is my first facing. Please check the below image and note the rectangles.
The image is just an example that I took from internet.
The biggest rectangle is a partial view in my application and I have to render it when the user press Continue or Continuar button. The application should replace the current view for another without refresh the page.
This is the code which I'm testing, note first that I'm passing the first element of a list, but when the user press the button, render the view with the next element index = 2.
public ActionResult DoTest()
{
if (!Request.IsAjaxRequest())
{ }
List<Worksheet> worksheets = new List<Worksheet>()
{
new Worksheet("Hoja 1", ...),
new Worksheet("Hoja 2", ...)
};
return View(worksheets[0]);
}
Can orient me a little bit to know how to implement this feature? I just know that I need to use Ajax.
Have a look through the tutorials and examples here. There's plenty of other material around on the web with information on this subject.
There are many different ways you can achieve this. One way would be to write a custom paging Helper (HtmlHelper) that accepts new content upon the post event. You can view all about Helpers here : Custom HTML Helpers
Another way could be to use partial page rendering to achieve the partial page update upon post event.
If I was you I would combine a partial view with a jquery function to update the content. You can view some help on that here: Change dive content with Jquery
How can I get the current view name regarding to current URL, in asp.net MVC 3 using Razor engine?
No idea why you would need to get the current view name but you could use the VirtualPath property inside a view. Normally it's more useful to know the current action or controller. But anyway, here's how to get the current view name:
#VirtualPath
and if you wanted to get only the filename:
#Path.GetFileName(Server.MapPath(VirtualPath))
and without the extension:
#Path.GetFileNameWithoutExtension(Server.MapPath(VirtualPath))
I've also tested this code, and I could do something with it.
But, I'm not sure if is this a good solution or not.
For example, I need to detect the Contacts view located in Home directory. So I wrote:
if (#Request.RawUrl == "/Home/Contacts")
{
// do something
}
You can get it from RequestContext.RouteData
specifically, its Values collection contains "controller" and "action" keys
i.e.
RequestContext.RouteData.Values["controller"]
RequestContext.RouteData.Values["action"]
ASP.NET Core's equivalent:
#ViewContext.ExecutingFilePath
Output is like this:
/Views/Shared/String.cshtml
The rendering of a view may involve one or more files (e.g. _ViewStart, Layouts etc).
This property contains the path of the file currently being rendered.
ViewContext.ExecutingFilePath Property
I am using MenuBuilder with code like this:
public static MenuItem MainMenu(UrlHelper url)
{
Menu.DefaultIconDirectory = url.Content("~/Public/Images/");
Menu.DefaultDisabledClass = "disabled";
Menu.DefaultSelectedClass = "current";
return Menu.Begin(
Menu.Items("",
Menu.Action<HomeController>(p => p.Index(), "Home")
),
Menu.Items("",
Menu.Secure<HomeController>(p => p.About(), "About")
),
Menu.Items("",
Menu.Action<RegulationController>(p => p.Index(null), "Compliance")
)/* This is in the Compliance area */
).SetListClass("menu");
}
But I am also using MvcContib Areas and in the code above the final menu item is in an 'Area' called 'Compliance'.
(There are two other areas in the Mvc application and the first in the list of registered areas is called 'Legislation')
What happens is the following:
When a page is rendered (I am using the standard WebFormsViewEngine) the Urls are all rendered using the 'Legislation' area!!?
E.g. http://localhost:1337/Legislation/Home or http://localhost:1337/Legislation/Home/About
and finally http://localhost:1337/Legislation/Regulation
The first two links should not pick up the 'Legislation' area. The last menu item should be in the 'Compliance' area.
How do I prevent the erroneous Area (Legislation) being rendered on the first two links?
How do I get the MenuBuilder markup in the Site.Master to accept an 'area' attribute or get it picked up automatically from the Controller for each link?
It seems that MvcContrib MenuBuilder does not play well with Areas. In the end I took the Areas out and the problem went away.
However, I recognise there may have been some other issue in the Mvc application which may indeed have been related to the older (beta?) version of Mvc dll that MvcContrib was referencing.
So for anyone that comes across this it may indeed be a none issue.
In other languages (PHP/Python), I am used to creating a class which represents a given HTML page layout. These classes can have an unlimited number of attributes and dynamic features, such as Navigation (multi level), error messages, info messages, footer text, etc... Most of these items have defaults, but may be overridden on a per-page level. For example:
Layout = MainPage()
Layout.Title = "Google Image Search"
Layout.Nav1.Add("Google", "http://www.google.com", Selected=True)
Layout.Nav1.Add("Yahoo", "http://www.yahoo.com")
Layout.Nav1.Add("Bing", "http://www.bing.com")
Layout.Nav2.Add("Google Image Search", "http://......", Selected=True)
Layout.Nav2.Add("Google Shopping Search", "http://......")
Layout.Nav2.Add("Google Video Search", "http://......")
Layout.Nav2.Add("Google Web Search", "http://......")
or, handling errors:
try:
# do something
except ValidationError as e:
Layout.Error.Add(e)
or a php example:
$Layout->Info[] = "Your changes have been saved!";
My question is: how do I implement similar functionality into ASP.Net MVC 3 Razor (VB)?
So far, I have been able to see how you can use ViewData to pass various bits of data to a view. Also, I have been working with strongly typed views.
Frankly, I'm not sure who's job it is to have this logic, the controller or the view (or is there a model that should be in there somewhere).
Here is a summary of what I am shooting for:
A single place to initialize the default values for the layout (like the first layer of navigation, etc...)
Strongly typed attributes, such as Public Readonly Property Nav1 as List(of NavElement)
And a single place to render these layout elements (I assume _Layout.vbhtml)
Please forgive the here-and-there of this post... I'm trying to figure out the "right way" it's done on a platform that is both new (Razor) and new to me (ASP.Net MVC).
General advise very welcome!
I usually have a controller property (MainMenu) which I add to the ViewData dictionary in Controller.OnResultExecuting in my BaseController. Note that it's named ViewBag in mvc3 and it's a dynamic object.
Another approach would be to use sections in razor. Look at this question: ContentPlaceHolder in Razor?
I lean toward the fat models, skinny controllers perspective. If it were me I would create a base class for your page models that provides support for your common data. You can then inherit from that for individual page models and store your page specific data there.
The MVC implementations that have worked well for me usually have relatively clean Controllers. The controller is just the connector, getting the data from the request into the model and then handing off the prepared model to the correct view.
As for how you store collections of things in .Net - look at the classes that implement IEnumerable interface. Specifically focus on the Dictionary and the List classes. Dictionary objects store name/value pairs and can include nested dictionaries. You can work with them almost exactly like you can use multi-dimensional arrays in PHP. List objects are just indexed collections of items of the same type. You can work with them just like a simple array in PHP.
One side note - if you're just getting started in .Net and coming from a PHP/Python background, it might be better if you can switch to C#. You'll find the syntax much more comfortable and the tutorials/examples more plentiful (especially in the asp.net mvc world)
It's not difficult! :-)
If layout model is of the same type of the content page, the association is automatic! Here is the simplest example...
This is a test layout:
#model string
<style>
.test
{
background:#Model;
}
</style>
<div class="test">
Ciao
</div>
#RenderBody()
And this is a test content page
#{
Layout = "~/Views/Shared/_Test.cshtml";
}
#model string
...blah blah...
Just call the View with something like:
...
return View("Name", (object)"Green");
and it's done! The model is the same in the content page and in the layout page!
Andrea
P.S.: Believe me! This is useful!!! Maybe it's not the best for purists, but it's really useful!!! :-)