I have a menu and I used a cookie in order to set the menu as selected by refreshing. The menu is common to all classes, so I put it in the _layout.cshtml, but the same time I want a controller for this layout because there some function to set the menu as highlight. Can I create a controller for this?
Yes, you can call #Html.Action or #Hmtl.RenderAction to invoke a controller from the view. But this borders on mixing of concerns, as now your view is actively calling your controller.
The better approach is often to pass the appropriate data to the view as part of your view model.
Somewhat related answer of mine
RenderAction method documentation
But the same time I want a controller for this layout because there
some function to set the menu as highlight.
If you are doing something basic like highlighting the current page, there may be a simpler solution. You could put the current page ID into the ViewBag and retrieve that value in your main _Layout file and use it to select the appropriate item.
Partial actions may be what you looking for here - this article may be some help. It relates to MVC2 but the principles remain the same.
create an action for menu, and put menu ui in the view, and then call Html.Action("menu action name","controllern name") on layout page.
Related
The layout page that calls the #Renderbody() method has a navigation bar, and I want to add an orange border to the button that represents the page the user is currently on. The only way I can think to do this is to add a class (.current or something) to the button on each individual page, but since the elements live in the _layout page, I can't change them per-page. This is easy to do with JavaScript, but is there a way to do it using strictly HTML and CSS?
Just because they creating the menu happens in _Layout doesn't mean that it cannot change on a page by page basis. You still have access to all the usual pipeline components whilst rendering _Layout. I can think of two methods that you could use, not sure which I prefer or if I even really like either of them, but they should show you that things are possible and perhaps you can think of a cleaner way to achieve it or someone else can think of a better way of doing it.
You could load something into the ViewData object in you action (or as part of a base controller or some generic code that is run for every action) that can then be fished out in the _Layout and used to add the class to the relevant button.
You could interrogate the Route object from within _Layout to figure out what page you where currently looking at and use that to add the class to the relevant button.
Hope this helps.
Cheers Mike
guys, I was applied a big task is about to make the MVC page configurable.
It means:
It just like the webpart in webform.
1.We can config the partial view in the view,make the partial view enable or not,we can drag and drop the partial view anywhere in the container.
2.One partial view is related to a simple mode(entity),and also the fields of the form in the partial view can be configurable:enable or not and the position can be adjusted.
now I have some ideas as following:
1.I create an model base, let other models inherit from model base,model base just hold the metadata related to the fields and the model itself.
2.Render the settings which is in model base to hidden field throght html helper and partial view.And on the client, I just use the jquery to handle the layout according to the setting in the hidden field.
3.The partial view I just let it to render only, and the real logic I will hand it on the page which contain the partial view. I think this would be simple and extendable.right?
So any ideas here? I really think this task is complicate.
In the past, Omar AL Zabir Blog has an portal website, called dropthings, maybe it is closed now. He tried to implemented the things like igoogle did. You can see that project at codeplex.
And you also can find some ideas for that find of application at Lakkakula's Blog
Hope this help.
In my layout file, I am displaying some text, and I want to hide this text only in one view. How do I tell what view is currently loaded from inside the view?
An easy way is to add some conditional logic to render in your _Layout as long as a viewbag bit is not set. If you don't want to render simply say so by defining the viewbag variable in the controller action and the layout won't render it.
There are more elegant solution involving attributes but this should get you going.
Don't forget the layout shouldn't know about specifically what view you're rendering thats a bleeding concerns. Viewbag helps by providing a communication and allowing decoupling of these two pieces.
You can set Id to that text container and in that specific view you can hide that Id by jquery
write this code in that view where you can to hide the text
$(function() { $("#id").hide(); }
I'm having trouble figuring out how to do the following:
On every page (or every page I so desire), I'd like to put a common control widget (e.g. think - Search functionality that contains a textbox+button). What's the best way to do this, and who handles the submit button (assuming it is a submit button)?
i.e. what does my ViewUserControl look like? Does it have a form? does it use jQuery onclick""? Does it post to the main View's action method, or can I redirect it to another Controller/Action?
I have tried using RenderAction of a "Search.ascx" which contains a Form, and is handled by my SearchController... but in the SearchController, it then tries to call RedirectToAction... and I get a complaint about RedirectActions not allowed on Child Actions.
I'm a bit lost on what to do next, so suggestions greatly welcome!
Ray
You seem to be on the right track (using ViewUserControl and RenderPartial). But with the information you have provided, it is not easy to see what you other problems are (RenderAction , ...)
It is easy:
Create a UserControl (.ascx) and get a form in there with URL being /search/..., something that you can get back.
In your views, call RenderPartial and provided the view name
Create your controller to receive the post from your search. This is not the same controller as your parent view controller.
The best way to have the HTML elements show up is to put them in a master page, or in a partial that is referenced by your master page. I would have it be it's own form and submit to your SearchController.
Let me know if you want more particulars.
RenderPartial is the way to go here. Your control.ascx will consist of it's form and submit button.
What's the best way to do this
Probably a partial view. An .ascx file.
and who handles the submit button
(assuming it is a submit button)?
The partial view
what does my ViewUserControl look
like? Does it have a form?
Yes, it has a form. It should be as self contained as possible.
does it use jQuery onclick""? Does it
post to the main View's action method,
or can I redirect it to another
Controller/Action?
Well, whatever fits your exact scenario best. It should probably post to whichever action is most appropriate. That is not likely to be the main view's action, since the partial is reused in different parent views.
I have tried using RenderAction of a
"Search.ascx" which contains a Form,
and is handled by my
SearchController... but in the
SearchController, it then tries to
call RedirectToAction... and I get a
complaint about RedirectActions not
allowed on Child Actions.
You'll probably want to render it using RenderPartial in the parent view:
<%: Html.RenderPartial("MyPartialView.ascx") %>
Ok, I figured out what my problem was. The replies above are correct. I have my own Search.ascx user control and SearchController, I also used RenderPartial, but what stumped me was that I forgot to explicitly specify the controller/action... so then I was fiddling around with onclick events and Url.Action on my button instead.
<% using (Html.BeginForm("MySearchAction", "MySearchController")) { %>
Thanks to all who replied.
I am working on an ASP.NET MVC application that contains a header and menu on each page. The menu and header are dynamic. In other words, the menu items and header information are determined at runtime.
My initial thought is to build a base Controller from which all other controllers derive. In the base controller, I will obtain the menu and header data and insert the required information into the ViewData. Finally, I will use a ViewUserControl to display the header and menu through a master page template.
So, I'm trying to determine the best practice for building such functionality. Also, if this is the recommended approach, which method should I override (I'm guessing Execute) when obtaining the data for insertion into the ViewData.
I'm sure this is a common scenario, so any advice/best-practices would be appreciated! Thanks in advance!
EDIT:
I did find the following resources after posting this (of course), but any additional anecdotes would be awesome!
http://www.singingeels.com/Blogs/Nullable/2008/08/14/How_to_Handle_Side_Content_in_ASPNET_MVC.aspx
How do you use usercontrols in asp.net mvc that display an "island" of data?
Depends on where your information is coming from. We have standard view data that we use to generate some of the information we have on screen that we create in just this fashion. It works well and is easily maintained. We override the View method to implement strongly typed view names and use this information to retrieve some of the data that the master page requires as well.
You could write a helper extension to render the header/menu
That way you could have it show in different places in the view should you need to, but only one place for maintenance.
public static HtmlString MainMenu(this HtmlHelper helper)
Use a base controller class to implement generell filter methods. The controller class implements some filter interfaces IActionFilter, IAuthorizationFilter, IExceptionFilter and IResultFilter which are usefull to implement some common behavior for all controllers.
If the menu data is the same on all pages but different for each unique user.
Generate the menudata in an OnAuthorization or Initialize method of your controller base class. First will be called on authorization. Initialize will be called before every action method. You have access to ViewData Context. Generate the menudata there.
Put the view content for menu and header into the master page and access generated ViewData there.
I tackled a similar design challenge a couple months ago - implementing a breadcrumb feature that changes as user navigates from page to page.
I overrided the OnActionExecuting method to gather the breadcrumbs and store them in ViewData (I use the name of the action as the breadCrumb of the view). Then I updated the Master page to include a user control that takes the ViewData and renders the breadcrumbs.
One thing to be aware is that if you were using the default ASP.NET MVC error handling attribute [HandleError] and your error page is using the same Master page that attempts to read the ViewData, you will soon find out that you can't access ViewData from your error page and it will raise an exception. Depending on whether you need the ViewData for failure scenarios, the viable solution is to use a separate Master page or do this: How do I pass ViewData to a HandleError View?
I'll answer your question with another question. Will the base controller have to determine what type it really is in order to generate the proper menu data? If so, then you're defeating the purpose of polymorphism and the code to generate the data should go in each controller, perhaps in OnActionExecuting if the menu is the same for all actions. Pushing it back down into a parent class seems likely to end up with some switch statement in the parent class doing what each derived controller really ought to take care of.