Passing data from controller to master page - based on currently logged in user - asp.net-mvc-2

Using MVC2
Have a master-page that needs to hide certain menus if currently logged in user does not have correct flags set.
Seems like a common problem. Found examples that require that all controllers inherit from a base controller (I have that) and where in constructor of the base controller, the passing of certain parameters to ViewData can occur. This is great and would be easy for me to do, but User.Identity and Request objects are NULL during the construction of base controller.
How do I get to User.Identity of the currently logged in user so that I can query database & modify the ViewData collection accordingly before Master Page view is rendered?
Thanks

You could use child actions along with the Html.Action and Html.RenderAction helpers. So you could have a controller action which returns a view model indicating the currently logged in user info:
public MenuController: Controller
{
public ActionResult Index()
{
// populate a view model based on the currently logged in user
// User.Identity.Name
MenuViewModel model = ...
return View(model);
}
}
and have a corresponding strongly typed partial view which will render or not the menus. And finally inside the master page include the menus:
<%= Html.Action("Index", "Menu") %>
This way you could have a completely separate view model, repository and controller for the menu. You could still use constructor injection for this controller and everything stays strongly typed. Of course there will be a completely different view model for the main controller based on the current page. You don't need to have base controllers or some base view model that all your action should return.

Related

confusion while creating controller in Code igniter

I'm Just confused while creating controller in code igniter.
I have two main modules in my project.
menu in header section.
contact us form.
for menu i have created one controller naming devot in devot class i have called all the views for menu, now for contact us form i should go with same controller or i should create new controller.
I'm bit of confused on selection of controllers, how many controller should be there in one application. With only one controller can we complete one application is that possible. ???????????
example:
class SampleController xtends CI_Controlle{
public functin index(){
$this->load->view('header.php');
$this->load->view('yourpage.php');
}
public function page1(){
$this->load->view('header.php');
$this->load->view('yourpage1.php');
}
}
codeigniter Read the Manual
refer

Who should create view model instances in MvvmCross

Just to make it clear: I know MvvmCross is very flexible about where and how view models can be created. My question is more about proper separation of concerns, to simplify design of complex cross-platform applications.
Consider we have an app with customer list and customer details. On iPad and Surface the list and details are shown on the same page, but on smaller devices customer list and details for a selected customer are split between separate pages. So we have a PCL with CustomerListViewModel and CustomerDetailsViewModel. Now how should we manage view model lifetime from within the portable class library?
I originally did it using code in CustomerListViewModel implementation that looks like this:
public ICommand SelectCustomerCommand
{
get { return new MvxCommand(SelectCustomer); }
}
public void SelectCustomer()
{
if (formFactor == FormFactor.Phone)
{
ShowViewModel<CustomerDetailsViewModel>(new CustomerDetailsViewModel.NavObject(this.SelectedCustomer));
}
else
{
this.CustomerDetails = new CustomerDetailsViewModel(this.SelectedCustomer);
}
}
What is essential here is that we either call ShowViewModel that in turns asks a presenter to construct a CustomerDetailsViewModel object and render it in a new page or explicitly create an instance of CustomerDetailsViewModel and bind it to CustomerDetails.
After having seen episodes 32 and 42 of N+1 MvvmCross video series I am not quire sure this is the right way to do it. Of course it works, but should a view model care about instantiation details of other view model?
My second thought was to refactor this code and put this logic into a presenter, so I can simply write in CustomerListViewModel implementation:
public void SelectCustomer()
{
ShowViewModel<CustomerDetailsViewModel>(new CustomerDetailsViewModel.NavObject(this.SelectedCustomer));
}
... and presenter will do the rest inside the code triggered by ShowViewModel call. However, in the episode 42 it's shown how to control view model lifetime right from the associated view:
protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedFrom(e);
VisibleViewModel.IsVisible(false);
if (e.NavigationMode == NavigationMode.Back)
KillableViewModel.KillMe();
}
But if a view model lifetime is controlled by a presenter, shouldn't we try to place KillMe call inside presenter's logic? I know so small piece of code doesn't make much difference but couldn't this be an advantage to put it in presenter's class and reduce code-behind?
Definitely the ViewModel should not handle anything in regards to view (screen).
One quick idea I have is use a custom presenter which is able to create views based on the ShowViewModel<> requests.
The custom presenter is a view responsibility so you can test for screen orientation.
http://slodge.blogspot.co.uk/2013/06/presenter-roundup.html
For the second part of this question:
But if a view model lifetime is controlled by a presenter, shouldn't we try to place KillMe call inside presenter's logic? I know so small piece of code doesn't make much difference but couldn't this be an advantage to put it in presenter's class and reduce code-behind?
Currently view model presentation is orchestrated by the presenter - it gets ViewModelRequest objects and decides what to do with them.
However, it doesn't normally create the ViewModels - instead:
the presenter normally creates/shows a View
then the View creates (or locates) a ViewModel as part of the OnCreate, ViewDidLoad or OnNavigatedTo handling.
And so I don't think a ViewModel's lifetime is normally "controlled by a presenter" - instead I think a ViewModel is a "Model for a View" - so it's lifetime is "controlled by its view".
For the occasions where you need shutdown/dispose/killMe logic in your ViewModel, if you wanted to move that logic back inside the presenter - or into some other object - then you definitely could do so if you wanted to - it's your app and the app is king.
However, in these cases I suspect you would need the presenter to get some kind of notification from the View - as often the presenter doesn't know when Views are removed (when a modal is dismissed, when a Back button is pressed, when Android clears up stack views to save memory, etc).
As another way of thinking about this, if the presenter were renamed as INavigationService then what roles do you want that INavigationService to own within your app?

Call ActionResult of Another View from form

I am trying to create a search form in my MVC application in View 1. The form was working very well when I used to submit the form to same page (View1). That way I can have two ActionResults - one of which accepts HttpPost requests. Everything is cool here
Now things have become slighly complex and I wish to separate the views. So in View1 there is a form and I wanted the results to be displayed in View2. So how do I call ActionResult of View2 from a form in View1?
In short - User enters keyword in View1. Hits Enter. Form in View 1 calls View2. ActionResults in View2 calls some logic to search and return View2 as the view and then I can display the results.
I tried some basic things like action="/View2" but I was pretty sure it would fail. It says 'the resource cannot be found'. Is it even possible to do this? Kindly advice.
*UPDATE*
It can be solved as answered below.
use Html.BeginForm(Name of the ActionResult,Name of the controller)
You need to specify the URL of the other action in the form, preferably by calling the Html.Form("ActionName", "ControllerName") helper.

Showing another View from my current Viewmodel and closing a view from my viewmodel?

I have another view setup and ready and waiting with its viewmodel. My RelayCommand arrives in my "Current" viewmodel. What is the best way to show the new view from my current viewmodel?
I have been reading and it appears that I need to use the Messenger to send a message from my viewmodel to ??? my new viewmodel that is associated with my view I wish to show? But how would I show the View?
Also is there a way to support closing a view from a viewmodel? I wonder if mvvm-light brings anything extra to the table - ie.. Triggers to force the viewmodel to close the view?
In WPF, you have two ways (out of the box) for "showing"/"closing" views. The first, is simply, by showing a Window, or Dialog via the .Show() or .ShowDialog() methods, and they can be closed with the .Close() method. In this case, you can use the MVVMLight Messenger class as you mentioned to send the show/close messages to the view in a decoupled way. here's an example with "closing".
In the ViewModel:
CloseTheView()
{
Messenger.Default.Send(new CloseTheViewMessage);
}
in the code-behind of your view:
//Constructor
public TheView()
{
...
Messenger.Default.Register<CloseTheViewMessage>( () => this.Close() );
}
as you can see, this involves some code in the code-behind file, but it's no big deal, since it's just one line of functionality.
The second approach is to use the Navigation Framework (which is available for both WPF and Silverlight). You define a "Shell" which is the main Window (or UserControl), you put a frame inside of it, and you make your other views inherit from Page, and then initiate the navigation from your ViewModel using the instance of the NavigationService associated with Frame (or directly the one associated with the page itself).
Hope this helps :)

MVVM - Should the View have a reference to the Presenter/ViewModel?

I've been looking through the PRISM 2 samples for ideas about how to best approach a new application I'm working on, which will be a PRISM 2/WPF app. Looking in particular at the View Injection sample application that ships with PRISM I've noticed that all of the views implement an interface which allows the presenter (or ViewModel) to interact with the View.
In the past I've done this the opposite way round, I inject the presenter into the view so that the view can directly call to methods on the presenter a bit like this:
public partial class SomeView : ModuleBase
{
private ISomePresenter _somePresenter;
public SomeView (ISomePresenter somePresenter):this()
{
// Give the view a reference to the presenter
_somePresenter = somePresenter;
// Bind the View to the presenter
DataContext = _somePresenter;
}
private void btnSubmit_Click(object sender, RoutedEventArgs e)
{
// The view can call actions directly on the presenter (OK I should probably use a command for this)
_somePresenter.SomeAction();
}
}
The technique above seemed reasonable enough to me, but looking at the samples I'm starting to question the approach. Does anyone have views (no pun intended) on the best way to go about this?
Add the presenter to the view and get the view to interact with the presenter
Add the view to the presenter and get the presenter to interact with the view
Something totally different that I haven't thought of yet?
The most common approach to map a ViewModel to a View in MVVM is to use a DataTemplate :
<DataTemplate DataType="{x:Type vm:SomeViewModel}">
<v:SomeView />
</DataTemplate>
When you display a ViewModel instance in a ContentControl or ItemsControl, WPF will automatically instantiate the appropriate View for the ViewModel, and set the View's DataContext to the ViewModel instance.
That way, you don't have any reference to the View in the ViewModel, and the View only references the ViewModel through the DataContext property. In case you really need to access the ViewModel in the View's code-behind, you can always cast the DataContext (but this implies that the View knows about the ViewModel's actual type, which induces coupling)
I think it's all a matter of taste. Personally, I enjoy the way you see it in samples you are looking at. IView has one method, thats SetViewModel(...). IViewModel has a property called View of type Object, that essentially returns the DI instantiated IView.
The reason I like this way is I almost always want to create a ViewModel first and I want nobody in the code to be able to do anything with my IView, except get reference to the instance (for view injection or binding the view to say a ContentControl), which is why its of type object. If any code needs to talk to the View, for me, it's always via the VM...and even then the view gets updated usually via binding. It would feel odd to go from the View->ViewModel->UpdateBinding->View, than it is, VM->UpdateBinding->View
To answer the question, I generally don't need a reference to the presenter in the codebehind. Usually I can handle that with commands from the view being bound to the VM.
In some cases, you might want to keep reference to the presenter to do what you have in your example, but it is avoidable given the correct toolset (makes SL harder that it doesn't have built in commands).
Like I said, it's all a matter of taste...
-Jer