Navigation pulled from database and displayed in master layout - asp.net-mvc-4

I'm working on a web application in ASP.NET MVC. When the user logs in, I want to retrieve his navigation (varies between user accounts) and his information from the database, and keep the info between controllers.
I'm displaying the navigation in _Layout.cshtml so I'm wondering best practices to pull the navigation and other user info from the database and storing it between controllers. This information is only retrieved once and stored through-out the user "log-in session".
What is the ideal solution? Should I create a BaseController which other controllers inherit and put my logic in the constructor and put the info in a global ViewBag? Or should I use the Session object in the Login method? Or should I create a static method and call it directly from _Layout.cshtml?
What should I do? I want to do this globally once, so I don't have to do this in each controller action.

Related

Access ASP.NET 5 View Component via URL

With the replacement of partial views in ASP.NET 5 with view components, how does one access the view components via URL?
I know you call them like...
#Component.Invoke("SomeList", 1)
...but what if you need to have like ajax paging, where you need a callback url to request the next set to be displayed in a partial view? So, a user can click "Load More" and it loads more from a 'partial view'.
You cannot access a view component from a URL directly. A view component is just a component of a view and that view could be a regular or partial view.
Based on your question, I believe you are trying to show the first page by default when the view (having the view component) is rendered? I have tried to put some scenarios here.
Example scenario:
Show a snippet on layout page which shows list of available job positions.
Usage cases:
Render the html related to a job list at the server side :
Layout page would have something like #Html.Partial("JobsListPartial").
This "JobsListPartial" would have something like await #Component.InvokeAsync("JobsListViewComponent", pageNumber). This partial view also sends ajax script to the client for users to navigate through the pages.
At the client when user tries to navigate to a different page, the ajax script makes a call to a JobsController having an api like IActionResult GetJobs(int pageNumber) and this action returns a PartialViewResult by doing something like return PartialView("JobsListPartial", pageNumber).
Render all pages at the client side only :
Create a partial view (having your ajax scripts) and render to the client.
Create a controller exposing api for navigation through pages of available job positions.
Call this api(returns json) from the ajax script.
Use the json data to dynamically change the UI at the client.

How to expose and call methods on MVC 4 user controls

I am converting my asp.net site to MVC 4. My site has a control called loginbox that prompts the user for username and password. The control also exposes a method called IsLoggedIn that a hosting page can call. I want to continue to encapsulate the login logic in my loginbox control and call it in a similar fashion from a parent level page (i.e loginBoxInstance.IsLoggedIn()). How do I do that?
MVC doesn't have a concept of user controls. The whole setup of MVC is to separate logic from the view. You could achieve a similar setup by creating a separate controller and a partial view.
Then in your main view you could call RenderAction on the controller, which renders the partial view. However, this is only valid for the rendering stage, so something like IsLoggedIn() is not something you can (or should) do in MVC.
Example:
Controller
public class LoginController
{
public ActionResult Login()
{
return PartialView();
}
}
Partial View
// Place this file in Views/Login/Login.cshtml
<div>
<!-- Your markup -->
</div>
Main view
#Html.RenderAction("Login", "Login")
This will allow you to separate the view part (and also the logic) of the login rendering into a separate controller and view, which can be included in another view.
However, what you probably want is something like Action-attributes or inherit from a base controller class which handles all this for you.
The paradigm of MVC versus Web Forms is very different, and I think you should look into a more appropriate way of doing this.

Vaadin 7 - Set and get attributes into VaadinSession

I'm currently using Vaadin 7 for creating a RIA and I'm designing the Login functionality.
The application design is simple:
A UI class performs navigation beetwen different View classes. In particular, the first displayed View is a LoginView class and after a user has been authenticated the UI class redirects the user towards a MainView.
After authentication I'd like to set User data (eg name and surname) into the session and display it always (no matter what specific view) on the top right corner of the Web Application.
As a begginner I read the Vaadin Book and I firstly used the scheme illustrated in chapter 11th https://vaadin.com/book/-/page/advanced.global.html, but it doesn't seem to work as expected, probably because I'm using View navigation scheme.
So I use the following approach:
Once authentication is correctly completed LoginView tries to store user data as a VaadinSession attribute with the following code:
VaadinSession.getCurrent().setAttribute("name", name);
then UI navigates to MainView and tries to get the name of the user with:
VaadinSession.getCurrent().getAttribute("name");
but it gets a null value.
Does anyone know why? I appreciate any help.
Thank you.
I would suggest storing the values on the HTTP session instead.
VaadinServletService.getCurrentServletRequest().getSession().setAttribute("name", name);
and
VaadinServletService.getCurrentServletRequest().getSession().getAttribute("name");
Use the #PreserveOnRefresh annotation on main class which is extends the UI.
Then you can store variables data in the main class.
You can give it from anywhere (in any View) with ((MyUIClass)UI.getCurrent()).getSomeVariable method expression.
I have a guess as to why you get your null value. In most tutorials of modern Vaadin, the navigation pages are created first-thing in the UI as objects. If one of these views instantiated in this process is the MainView. If the label displaying the name sets the String in the constructor of the class, the line:
label.setValue(VaadinSession.getCurrent().setAttribute("name", name)); will be null is the attribute has not been set by the login function yet.
You need to either update the label showing the user string in the #override enter() function, or handle it otherwise.

ExtJS 4 MVC multiple instances of views and sub/child controller difficulties

I have encountered a problem with the MVC pattern in ExtJS 4. At least, I think I have. Having approached multiple people with this question, and having posted numerous times in the Sencha forums, I am now turning to a broader audience in hopes of getting either a light bulb or a confirmation.
Problem
Your application has the ability to open many different views, some of which themselves are mini-applications. Additionally, a user may wish to have multiple concurrent copies of a view open.
This application is a single-page client-side Javascript application.
The ExtJS 4 MVC model expects you to define all of your controllers in your Application class. These controllers are then initialized when the Application loads. Controllers keep track of views, models and stores.
When you initialize controller A multiple times, say to create more than one copy of a view, you end up with two views that reference the same data stores, and functionally send duplicate events to the Application event bus.
I have refactored my application by adding new prototype methods to Component and Controller to allow for both a) sub controllers (some of my controllers were getting pretty huge) and b) defining stores specifically for the view they work with. The models can still be defined on the controller, just for ease of use by handlers if you need to do something like grab a record from the server.
Question
My understanding of MVC would lead me to believe that models more directly relate to the View than then Controller. I asssssume that ExtJS 4 decides to attach stores (which I think can be seen as wrappers to a more classic model) to Controllers for purposes of encouraging re-use of loaded data, and to optimize away from having many copies of the same class instantiated. It seems to me, however, that one cannot do this if one intends to have many instances of a view available to the user. To my thinking, having many instances is an important option in an OO framework, hence why I have bucked the trend and implemented prototypes on some of the Ext base classes. (Thank you Ext.implement!).
Is there any way to have multiple concurrent instances of a view with different data loaded into them using the out of the box MVC classes and making uses of the provided setters, getters, etc?
I was faced with a similar problem:
Consider a tabpanel for a CRM type application which opens new instances of a view for each client. And say that tab view contains 3 or 4 row-editing gridpanels for interacting with different collections of data relating to that client.
The solution I came up with was based on this from the Sencha forums. In a nut shell, almost all events that are dispatched from a view contain a reference to the view itself. The handlers in my controller's control function all use these to get a reference to the correct view instance.
For dealing with the multiple instances of the same store needed for this, I took this to heart from that post:
For the Store instance on the view or a global one... depends on the
needs. If you are going to use globally then make it global. If you
only are going to need it on the view then put it on the view. MVC is
not a law, you can change it to fit your needs. Technically the
Controller part of MVC is suppose to be the middle man between the
View and Model parts but sometimes that's just not needed. I create
the Store in the view 95% of the time. I'll give you an example...
If you have a Store for products, you probably only need to reference
that Store in your Grid. That usually isn't needed for other parts of
the application. However, if you have a Store to load countries, I
often need it globally so I only have to load it once and can then
set/use that Store in several views.
So I just created the needed store's that relate to a view instance specifically, inside the view's initComponent method. The application did have a few global stores that I created as store classes following the MVC recommendations. It worked out nicely to encapsulate the view instance stores inside the view. Then I only needed one instance of the controller.
To answer your question specifically, currently, there is no ExtJS official recommendation or config for dealing with multiple instances of the same view that use the same store constructor. I have spent some time looking for something like that and the best I have found was this recommendation from one of their forum moderators.
I don't think you ever need more than 1 instance of a controller, regardless of how many views/models you have. See functional example here:
http://whatisextjs.com/extjs-4-extension/fieldset-w-dynamic-controls-7
This can be done, reasonably easily. You need to follow a few rules:
load your controllers at app startup. Don't unload them. Don't worry about the memory or time, it's pretty small even for hundreds of controllers, as long as you minimize and concatenate your js.
Never use the refs or views properties of a controller. You are going to use one instance of a controller, but multiple instances of views, so you never want a reference to a view.
only use event listeners in controllers. You are only going to listen to events on your views. You can always get a (temporary) reference to a view in the event handler via the "cmp" parameter in the handler.
To "launch" a view, create it and add it to another view. To destroy it, destroy it. You don't use a controller to launch a view. You can use the afterrender and beforedestroy events in the controller to add logic.
In ExtJS' MVC the controller is a Singleton for you view. I like how DeftJS thinks about MVC. Each instance of a view has an own instance of a controller. In this way you can put all "controlling rules" in a controller for a particular part of your view, and this will be instantiated only when the view opens.
I did not have any experience how I could use multiple Defts JS apps in the same project.
Of course. What led you to believe otherwise?
Here is an example of creating a custom View which extends from a Window component. You can run this method many times from the same controller and each time you will get a new instance of a View.
"this" refers to a controller that code runs in:
this.getRequestModel().load(requestID,{ //load from server (async)
success: function(record, operation) {
var view = Ext.widget('requestEdit',{
title: 'MyRequest '+requestID
});
var form = view.down('form');
form.loadRecord(record);
}
});
How do you create your views? I see no reason why you cannot pass a different store or config data to every object. Some code samples would help for what exactly you are doing. For example, we have a similar sounding application, and everything is done with extensions. So, if we need a grid, we run
Ext.define('MyApp.grids.something',{
extends:'Ext.grid.panel'
//...
These classes are predefined. Then, when a controller or view is loading this grid, they are using
var grid=Ext.create('MyApp.grids.something',{id:'unique',store:mystore});
As you can see, we can pass in different config options to the same grid each time it is created. We can treat this exactly as you would treat
Ext.create('Ext.grid.Panel');
Except of course that we make some options predefined, and some non-override-able, and so on.
Hope this helped.
Check out this post. The idea there is to take some configuration (like store and itemId) from view config and put it into the viewport config:
// .../app/view/Viewport.js
Ext.define('MyApp.view.Viewport', {
// ...
items: [
// ...
{ xtype: 'testview', store: 'Store1', itemId: 'instance1' },
{ xtype: 'testview', store: 'Store2', itemId: 'instance2' }
]
});
The problem with store will be solved, obviously. Different itemIds will enable you to handle events properly.

Rails 3.1. Organizing partials

Assume I have a small and simple weblog written on Rails 3.1. So I have HomeController that is for displaying my blog's main page with navigation menu and news displaying in a main block. And I have NewsController that is for managing news. But I want to be able to manage news from my main page in central block if I'm an admin. For that purpose I need a remote form that will be displayed to the user with admin rights only and Edit/Delete remote links to manage existing news. Where I should place this form? It can be home/_news_item_form or news/_form. How do you think from the architectural point of view what place fits more for that purpose?
I think news/_form, because this form should applies in NewsController