Regarding MVC3 MASTER PAGE ISSUE
I have one master page and inside that master page i have used one usercontrol.
Now inside that usercontrol I have bind out one dropdown list from database from actionresult.
Now the problem is that whenever I use another view i have to call that action result for binding that dropdown list again and again in all other pages which include my master page.
How could I prevent this from happening?
Remember my friends, I am using MVC3.
As per your question, I understand that you want do not want to make DB call on your execution of each view as you included Dropdown in masterpage.
To overcome this problem, you need to implement ouputcache for that usercontrol (partialpage). Please find more details here. Do let me know if you still have any query.
If you don't need to check data from DB then make a static dictionary and bind it to the DropDownListFor:
private static readonly Dictionary<int, string> yourData
= new Dictionary<int, string>
{
{ "1", "Your data one" },
{ "2", "Your data two" }
};
Regards
Related
I'm new with ASP.Net Core (3.0 in this case) and I´m trying to create a menu that is visible on all views of a WebApplication, is created dynamically and must be populated only once. Below i explain the steps and try outs i did to reach the goal needed (if required i can share the code I'm using).
This is what i did:
In a simple way, using the "_Layout.cshtml" page, i created a static HTML menu and made all other views simply inherit that layout. So far, so good;
Next challenge comes from the fact that the menu items are dynamically created after a User has logged-in, which i managed to overcome by setting a ModelView inside a controller (HomeController.cs with Index action in this case), and then delivering it to the view. For this case works OK, because the default page is ~\Home\Index\, problem is when i change to a different view with a different controller, the menu has to be rendered again, and so i have to replicate the code (a problem dealt create a BaseController and BaseModel based on this post along side the OnActionExecuted to host the menu generating code)
Now, the biggest problem is the fact that i can only populate the menu once, after the user logs-in. Each time there is a redirect between different controllers/views (post-back of same controller/view works fine), the model is null inside the OnActionExecuted, I tried using ViewData, ViewBag, TemData, but all are null.
So, my question is, how to keep that specific data alive and shared, basically across all the views, and only gets populated once (after each user login) between redirects from different views?
I have been reading around and found several solutions besides the one i did, but i did not found any that could keep data alive throughout the user session the way I need:
ViewBag, ViewData and TempData
Can the shared layout view have a controller in ASP.NET MVC?
Pass data to layout that are common to all pages
To sum up, my flow at this moment, is like this:
User Logged-in
Redirect to default: ~\Home\Index
MenuModelView.cs for the menu gets built and HomeController.cs returns to Index.cshtml with the model attached to it.
Index.cshtml receives the populated ModelView and it uses _Layout.cshtml
The _Layout.cshtml builds the HTML tags for the menu based on the MenuModelView.cs data
User navigates to a different view and steps 3 to 5 are repeated from a specific controller/view
If you want to create a control that can be accessible in all pages without changing every controller, I strongly suggest creating a view component. For a view component has no relationship with your controller, but can access dependencies like database and full HTTP context.
For example, you want to build a custom nav menu, you can just create a view component named NavHeader
using Microsoft.AspNetCore.Mvc;
namespace YourProject.Views.Shared.Components.NavHeader
{
public class NavHeader : ViewComponent
{
public NavHeader(YourDbContext context)
{
// you can access your dependencies, like database.
}
public IViewComponentResult Invoke()
{
// your own logic. You can access HTTPContext here.
var model = new YourOwnModel();
return View(model);
}
}
}
And just call it in any view or layout.
<!DOCTYPE html>
<html>
<head>
<title>Example</title>
</head>
<body>
#*Render your component like this*#
<vc:nav-header></vc:nav-header>
</body>
For more details about view component, please reference:
https://learn.microsoft.com/en-us/aspnet/core/mvc/views/view-components?view=aspnetcore-3.1
https://anduin.aiursoft.com/post/2020/1/4/share-view-component-between-different-aspnet-core-web-project
We are using MVC 3 to build a Web site with dynamic menu options so that users only see menu options (action Links) that they are allowed to see based on group and individual privileges.
How can we add dynamic menu options (links to partial views) at run time?
Do we hard code all the links of all the partial views and turn of the ones that are not required using a visibility option?
Can we add the links dynamically from a database?
Let me clarify.
WE have admins that have access to all menu options like Manage Users, Manage Groups, Manage Suppliers, Manage products and Manage Orders.
We have regular sales staff who only need Manage Supliers and Manage Orders.
So based on this we only need to show the links that say Manage Orders and Manage Supplier. Hence they dynamic nature of the links I am trying to set up.
We have the permissions set up in the DB.
Jawahar
I am not sure I entirely understand what you mean when you say "links to partial views". You never really have a hyperlink to a partial view. The two possibilities I can think of are either you want to know how to embed the partial view conditionally, or you want to have hyperlinks to a controller action which returns the partial views.
In the first case, you can just put the #Html.RenderPartial call inside of an #if (myCondition == true) block. With that, the partial view will only be displayed if the condition passes.
In the second case, you can just always call the controller action. In your controller, only return the PartialView if your condition matches. Otherwise, return null.
I found a way of doing this using Method extension with IPrincipal
public static bool IsAllowed(this IPrincipal p, string menuid) {
if (p.Identity.IsAuthenticated) {
//Code here to verify privillegs against Database
}
return false;
}
This would keep it fairly neat in you Layout.cshtml.
#if (User.IsAllowed("menuchoice1")) {
...
}
#if (User.IsAllowed("menuchoice2")) {
<a href="#Url.Action(...)>...</a>
}
Hope this help others looking for similar options
I'm working on a ASP.NET MVC 3 application, but I'm rather new to MVC in general.
I have a partial view in a my application layout view that needs to have data passed to it. this will appear on every page. Is there a way to make this happen so I don't have to load that data into the view model for every action in the entire site?
As in, if a user navigates to Mysite/admin/settings, I would like to have the partial view on the layout be able to somehow receive the data that it needs without me needing to put that code in the Settings action in the Admin controller.
On this same note, how do you pass data to the layout view of an application anyway?
In these situations I usually use a base ViewModel for my Views
public class ApplicationViewModel
{
public string UserName {get; set;}
....
}
public class SettingsViewModel : ApplicationViewModel
{
}
all your views would inherit from that ViewModel. Your layout would expect it as well
_layout.cshtml:
#model ApplicationViewModel
....
<h1>hello #Model.UserName</h1>
hopefully this answers your question
Partial only renders a view. You need to provide the model manually.
You can create an action for the view you want and render it with Html.Action( actionName ).
Make an action for example menu which will create a model that will be provided to the menu view.
Now you can call the #Html.Action("menu") from wherever, and it will be rendered autonomously. (you can ofcourse provide a controller name as well, and even custom routeData)
You might also want to set Layout = null; in the view to avoid using the master layout of the whole site.
This is how I pass a value to the partial view from my layout page:
Layout page code:
Html.RenderPartial("_SubMenuLeft", new ViewDataDictionary { {"category", "MMG"} });
and in my _SubMenuLeft.cshtml (partial view)
#if (ViewData["category"] == "MMG")
{
...
}
Hope it helps someone for future reference.
I'm looking for the best practice on how to pass data from page to page.
In Page A I have a button that fires off Page B.
On Page B I have 6 textboxes that allow the user to enter information.
When the user is done, the click on a button that brings them back to Page A.
I want to pass that data back to Page A.
I've seen suggestions to:
build XML documents and save to Isolated Storage
use the App class to store information in properties
pass it like a query string
I'm looking for the Best practice. Is there one that Microsoft recommends or one that is generally accepted as the best way?
Thanks
PhoneApplicationService.Current.State["yourparam"] = param
NavigationService.Navigate(new Uri("/view/Page.xaml", UriKind.Relative));
then in other page simply
var k = PhoneApplicationService.Current.State["yourparam"];
Personally I'd store the values entered on Page B in a model(object) that is also accessible to Page A.
Depending on how you're navigating to Page A the second time, one or more of the following may be usful to help understand passing values between pages:
How to pass the image value in one xaml page to another xaml page in windows phone 7?
Passing a complex object to a page while navigating in a WP7 Silverlight application
How to pass an object from a xaml page to another?
How to pass a value between Silverlight pages for WP7?
How do I navigate from one xaml page to another, and pass values?
One thing you can consider is to use MVC: let your App be the controller, store all data in the model, and the pages are just views that contains pure UI logic. In this case your pages are painters and you pass your model object around. This gives nice isolation of business logic and the UI so that you can rev them easily.
BTW, Silverlight and XAML are great tools for MVC so it's a natural match.
There's a couple of things at play here. First of all, if/when the user uses the Back button to return to page A instead of your button, is the information in the text boxes exchanged or not (is Back = Cancel, or is Back = OK?)
That said, if you're using NavigationService.GoBack (which you should be instead of NavigationService.Navigate, because if you use the Navigate call, repeated hits of the back key will cause all kinds of bad UX for your users), then QueryStrings are not an option. Because pages really have no way to reference each other in the WP7 Silverlight nav system, you need to use a 3rd party to hold your data. For that, you can turn to (a) Isolated Storage (slow & heavy, but fail-safe), (b) Use the PhoneApplicationService.State dictionary, or (c) use Global properties of some kind, either hung off of the application object, or using Statics/Singletons...
Remember to watch for Tombstoning behavior when you do this - your page will process the OnNavigatedTo method when (a) you navigate into it in your application (b) you navigate back to it when you complete your work on Page B, or (c) you tombstone your app from that page and return to your application using the Back key.
Sorry I didn't give a more direct answer there - a lot depends on your specific circumstances. In the most general case, I'd strongly consider using the App State Dictionary on the PhoneApplicationService...it is lightweight, easy to use, and survives tombstoning. Just be sure that your keys are as unique as they need to be.
If you create a new Windows Phone project and use the Windows Phone Databound Template you will have most of the work done for you.
What you will want to do is set up the ViewModel to contain all the data for your app. You can serialize and deserialize this data using IsolatedStorage so that it's saved across application sessions and when Tombstoning.
In the template you will notice MailViewModel and ItemViewModel. MainViewModel stores all the data your application needs including an ObservableCollection of ItemViewModel, and ItemViewModel represents the individual data type for your application.
On the DetailsPage.xaml page you'll want to DataBind each textbox to the App.MainViewModel Items. Set the binding to TwoWay if you want the ViewModel to get updated as soon as the user manipulates the data on DetailsPage.xaml. You can optionally set the Binding to OneWay and then have an OK button that writes the changes back to the ViewModel and saves to IsolatedStorage.
Here is an example of what a Binding looks like:
<TextBlock x:Name="ListTitle" Text="{Binding LineOne}" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
In this case LineOne is a property in ItemViewModel and the page gets this data from the query string when the user selects an item from the MainPage.xaml. The DataContext for the page determs where the databound information comes from.
Here is the snippet where the MainPage passes the selected item from the ViewModel to the DetailsPage.
// Handle selection changed on ListBox
private void MainListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
// If selected index is -1 (no selection) do nothing
if (MainListBox.SelectedIndex == -1)
return;
// Navigate to the new page
NavigationService.Navigate(new Uri("/DetailsPage.xaml?selectedItem=" + MainListBox.SelectedIndex, UriKind.Relative));
// Reset selected index to -1 (no selection)
MainListBox.SelectedIndex = -1;
}
Here is how the DetailsPage gets the selected item.
protected override void OnNavigatedTo(NavigationEventArgs e)
{
string selectedIndex = "";
if (NavigationContext.QueryString.TryGetValue("selectedItem", out selectedIndex))
{
int index = int.Parse(selectedIndex);
DataContext = App.ViewModel.Items[index];
}
}
Play around with the default template above and ask any additional questions.
The beauty of databinding and the ObservableCollection is that you can just update the data and the UX will reflect those changes immediatley. This is because any changes to the data fires off an event:
public string LineOne
{
get
{
return _lineOne;
}
set
{
if (value != _lineOne)
{
_lineOne = value;
NotifyPropertyChanged("LineOne");
}
}
}
NotifyPropertyChanged() that broadcasts this information to the View.
You can also keep it simple and use PhoneApplicationService.Current.State which is basically a hashtable. You will need to implement your own marshalling to and from isolated storage if you want anything to outlive the app.
Omar's suggestion to use the Windows Phone Databound Template is probably the best idea on this page. It amounts to the same as my suggestion but you will get a better result (more maintainable code) at the cost of a longer steeper learning curve.
I suggest you do it my way and then do it again Omar's way.
as i implemented like this.. Whether its correct or not i dont know..
When u click news list page it should open the news detail page.
I want to pass the selected news item contents from news List-Page to news-details Page.
the News list page contains following method.
protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
NewsDetailsPage newsDetailPage = (e.Content as NewsDetailsPage);
if (newsDetailPage != null)
newsDetailPage.SelectedNewsItem = SelectedNewsItem; //Contains the news details
base.OnNavigatedFrom(e);
}
In the News details Page. U can access that(SelectedNewsItem) object.
This may or may not be correct.
One option is to use Application.Resources:
Store data:
Application.Current.Resources.Add("NavigationParam", customers);
NavigationService.Navigate(new Uri("/Page2.xaml", UriKind.Relative));
Retrieve data:
var customers = (List<Customer>) Application.Current.Resources["NavigationParam"];
Here's a blog post with describes this in more detail: http://mikaelkoskinen.net/windows-phone-pass-data-between-pages-application-resources/ (author: me)
I'm fairly new to SharePoint so apologies in advance for sounding like a 'Newbie'.
I have created a simple Webpart, which uses a Web User Control - [.ascx file] to provide all the controls for the Webpart. On the .ascx file, there is a DropDownList which is hard-coded at the moment and works well in the Webpart (within a SharePoint site).
However, I want the DropDownList on the .ascx file to be bound to a particular Column of a SharePoint List, so that when I update that column of the SharePoint List, the DropDownList reflects the update automatically.
Do any of you kind folk have any ideas on how to achieve this please?
Thank you very much in advance,
Ash 8-)
(p.s. Happy New Year to you All !)
I found the answer within minutes of posting the above article (typical).
The solution is to place the following code in the Page_Load event of the .ascx.cs (code-behind) file:
if (!Page.IsPostBack)
{
using (SPSite site = new SPSite("http://yoursharepointsite"))
{
using (SPWeb web = site.OpenWeb())
{
SPList list = web.Lists["NameOfYourList"];
dropSite.DataSource = list.Items;
dropSite.DataValueField = "Title"; // List field holding value - first column is called Title anyway!
dropSite.DataTextField = "Title"; // List field holding name to be displayed on page
dropSite.DataBind();
}
}
}
I found the solution here:
http://blogs.msdn.com/mattlind/archive/2008/02/12/bind-a-asp-dropdownlist-to-a-sharepoint-list.aspx
Thanks,
Ash