I'm developing ASP.NET MVC 4 application, that will be used to configure a complex application. I want to have one configuration page, with multiple tabs. Each tab will be used to configure a different part in the system, and when you click on it the right form (each configuration tab will be a different partial view) will be loaded with AJAX. I want to have "Save Changes" button in the bottom of the page, that will save the changes from the whole tabs.
Since the system itself is modular, I want to make the configuration site modular too. Which means, that i want each tab to be some kind of a plugin that expose to me the following methods (by inheriting from an interface): GetConfigurationPartialView (which will return the partial view with the view model for this tab), SaveChanges (which will save the configuration to the DB as a draft), and GetConfigurationXml which will export the full XML configuration and apply it on the system.
My questions are:
What do you think about that design? do you have better ideas?
How do you recommend to implement this one "Save Changes" button in the main view? How can I iterate all of my plugins and call each plugin's SaveChanges method, pass it the correct model object (which is the partial view's model) filled with all the data without having intimate knowledge of each plugin object in the main controller/view so i can keep this system easy to extend?
Some of the tabs includes grids with data. i started looking into Kendo UI grid. I want to let the user do everything on the grid, in the client (deleting and add new rows), and then i want in the SaveChanges method i wrote about to get list in the server side of all the changes that the client did (for example, in pseudo code: changes[0]={Action = Delete, ProductID = 1}, changes[1]={Action=New, ProductID=1, Name="aaa" }). How can i do it?
Thanks.
Just make a partial view for each configuration page and load it as needed. I concur KISS is best.
Related
I am trying to figure out what is the right solution for creating a menu in a ASP.NET. The menu has items and subitems and are subject to user rights. So I have a MenuService that returns the menu for the current user. However I do not know how to implement the menu.
So far I have found 3 possible solutions:
Define a base view model to add on the Layout, and every page view model should derived from this (This would mean that the IMenuService needs to be on every controller)
Use a base controller where I attach the IMenuService and that is going to be attached to the HttpContext.Items before every action (based on this https://dtoncode.wordpress.com/2012/07/30/strongly-typed-models-on-your-layout/)
Define a Controller for menu and in layout call a partial view to place the menu on it.
Which of these solutions are the right one for the job? Are there others?
You could use MvcSiteMapProvider for this - it is very similar to the Web Forms SiteMap provider model, but made for MVC.
Basically, the entire SiteMap hierarchy is loaded into a cache and shared between users. You can configure the nodes in many ways - to load them from a database, you can use one or more dynamic node providers. It has a security trimming feature that automatically reads the [Authorize] attribute on each request and changes visibility of individual items accordingly.
The menu and breadcrumb HTML helpers it uses are templated, so you can change them to output any HTML you need.
Full Disclosure: I made a major contribution to this project.
I am interested in general approach for building interactive GUI using MVC3.
The idea is to build set of different components that can be integrated (plugged in) into various scenarios.
Each Component MUST have it's own model definition, controller and views.
Component encapsulates not just the view but also behavior through it's controller.
All internal implementation details, model, behavior, etc... must reside inside component,
so that component becomes independent, modular - black box.
This allows component to be changed without breaking anything in context in which component is used.
Context in which component runs must not make any assumptions about internal details of component implementation.
On the other side the component does not make any assumptions about context in which it will be used.
Finally, the component must provide mechanism to "communicate" or "interact" with outside world. Beside internals, component must provide some kind of "external" interface (like parameters, data, functions, events whatever...) which would allow component to be integrated into execution context.
The Context (or scenario) is part which contains components.
Now, the basic challenge for the context is to manage interaction between components.
Real-world Categories component example:
Component displays list of categories and allows user to perform various actions such as sorting, paging and record selection.
Internally, it has it's own model which stores relevant information like current page, sort, selection, etc...
Internally, it implements all required actions (for basic render, for user actions response, etc...) in it's own controller.
Internally, it handles model state persistence in the view and model state restore in it's own controller.
Real-world Products component example:
Component displays list of products and allows user to perform various actions such as sorting, paging and record selection.
Internally, it has it's own model which stores relevant information like current page, sort, selection, etc...
Internally, it implements all required actions (for basic render, for user actions response, etc...) in it's own controller.
Internally, it handles model state persistence in the view and model state restore in it's own controller.
Real-world Dashboard page (context, scenario) example:
Page displays both Categories and Products components.
Products component displays all products for the currently selected category and thus must provide external interface (parameter or something) to receive selected category identifier from the context.
Categories component must provide some kind of external interface so that context can act when selected category changes and provide selected category identifier for the products component.
Technically, communication approach for page updates would mostly go through AJAX but if this is possible without AJAX, it would be even better.
In the case of AJAX, I would like solution which uses server side controller(s) which decides and renders what should be updated on the client (JSON or something).
I would not like solution in the client script (client side "like" controller) which decides what actions to call and what parts of page to update - this as said in previous paragraph must be decided by controller(s) on the server.
Important: It is not necessarily for the components to work when directly called via some route.
How would you generally implement described system?
I think you need to investigate real projects and see, what approach do you need to use. Try following project and u can find many best practices:
Here u can find implementing of security measures, services, auth and many many useful.
Kigg
http://www.nopcommerce.com/downloads.aspx
http://orchard.codeplex.com/
It's hard to say for me how it's should be implemented. Better to code it. But using of Dependecy Injectction of Views, Controllers, Services, and Repositories are must in your case.
Each controller handles a whole user-machine pattern. That is, roughly, each controller is responsible for orchestrating the user-machine interaction for a user-case(the user-machine patterns that are the result of the analysys phase).
Now if you put "standard behaviours" in controllers who will coordinate the user-machine interaction pattern?
This way you will have "components" without something that coordinate their execution.
In web forms you have pages that coordinates the execution of components put in them...but in Mvc thi coordination role is played by the Controllers themselves.
You can do black-boxes composed of Controllers and Views just if each of them is responsible of a whole user-machine interaction pattern. That is a "Big Components" not a small building blocks, as its is the case when you implement a CMS.
The Orchard CMS use a similar approach. However what you call components are actually pre-defined blocks that play the role of whole sections of the websites being built by the user.
It seems to me that you are trying to achieve something which may not be out-of-the-box compatible with the philosophy of web MVC (other implementations of MVC might support it).
However, if you wanted to go to the trouble of writing a framework on top of ASP MVC, I am sure you could achieve what you want. For example, by using Areas, you could achieve a form of encapsulation of your controllers, view models, and views.
To compose different areas for the same master view, you could write the equivalent of a front controller with its own view that took in a view model - that view model would be primed by the front controller to render actions from the different areas.
You might achieve more mileage by using a client framework such as Backbone.js on top of ASP MVC.
In my ASP.NET MVC site all pages share the same content (header & top menu).
What are my options to generate that content is only one place and reuse it in all pages. I also want the link the user is currently on to be handled appropriately (not show up as a link).
In MVC3 this is usually done in the layout page: http://weblogs.asp.net/scottgu/archive/2010/10/22/asp-net-mvc-3-layouts.aspx
In my ASP.NET MVC 2 application, I use a Master Page as suggested by Rich. I just wanted to add that I use a Master Model that all of my view models inherit from to return dynamic data that is needed in the master page (i.e. something to help you determine the active link to highlight). Every time I render a view I explicitly pass it a view model so those values from the master model are always available.
That master model gets its data from things that are globally available (i.e. my custom identity, http context properties, etc.) - because I don't want to manually initialize those properties every time I render a view (which defeats my goal of thin controllers).
You can also use ASP.NET Master pages. http://msdn.microsoft.com/en-us/library/wtxbf3hh.aspx
If you start a new ASP MVC project in Visual Studio I believe it'll give you a masterpage in /Views/Shared
If it's dynamic data; then you can always use a RenderAction() inside of a Masterpage. Is this dynamically generated data?
In our old system we had pages rendered from XSLT. In order to change the page into "edit" mode we would have a button of some sort, once clicked would have an EditYN flag which would be passed to the stored procedure. The stored procedure would simply give this variable back to indicate that the page was in edit mode. This meant that query strings, viewstate or session data were not required to indicate that the page is in edit mode.
I've been dealing with ASP.NET MVC only for the last week for RND purposes at work. I'm wondering what's the best way to have a page which displays data, to then turn into a page where you can edit all of that data? Should you move to a separate page? Should you stay on the same page and have rendering logic in the view to show the edit mode of the page?
Whilst on the same topic, I thought I'd also ask about GridViews and their place in the MVC architecture. Beforehand we'd simply use data sources and set them up with the GridView. Then the GridView could enter edit mode quite easily by itself with the UPDATE query set in the data source. How should this process be done using MVC?
Make a submit button for your edit mode. The controller action will respond to POST, set the "InEdit" flag in your model, then return the same view again. The view can then render based on the flag. But I would rather create two different views, for view and edit modes, then based on the flag analysis done in the controller action just return the one or the other view.
Whilst on the same topic, I thought
I'd also ask about GridViews and their
place in the MVC architecture.
How should this process be
done using MVC?
You can use javascript, something like jqGrid or Yahoo´s datatable. For simpler datatables, you can use jQuery´s tablesorter.
On the backend, your controller returns json objects that can be modified by the client, ie. the javascript grid which then sends the data back to the controller to be saved.
I'm looking to build a rails web app with an admin control panel. I'd like the control panel to use a tabbed interface for controlling users, projects, tasks etc, and I'd like to switch between tabs using jquery tab UI controls with ajax. Also using restful authentication for users and my own code for projects, tasks etc.
Here's what I can't wrap my head around. Normally, I'd have a controller for each tab, so validation is simple, if there's an error (say in the user) i just render the proper action with the object and it's errors and we're set. However, if I'm not refreshing (to different controllers between tabs) how does this work? Do I need to have one massive controller with all the user, project, task validation and controls (ie. crud operations)? Seems like not the greatest design.
Or is there some way I can use an 'admin' controller that encompasses separate controllers for proper crud/error checking etc.
Hope this makes sense?
I would make the contents of each tab be called in by a separate ajax request. This would give you the following benefits
Now each tab can easily be a different view/controller
You only need to load the contents for a tab when it is used; you won't be processing code/downloading html for tabs that the user doesn't use.
If you don't want to use this route, (i.e. you feel you need to load all the contents of the tabs on page download in a single request) then you could separate out the code using helper methods and partials. See my answer here: Rails Sub-controllers?
I would personally use inline validation in the forms. Jquery does that pretty well , but there are a lot of library that can help you with that.
I guess it's not exactly what you were looking for, but it would make your job easier. Of course still keep validation in the models so that no one can bypass the validation (using firebug or something like this)