I am using .NET MVC 4. Let's say I have a Pinterest-style social media site. Users can pin content (ie., images), and decide the layout of their pinboard by dragging/dropping images around the board.
How do I persist the layout they've made so that when they log-out/log-in, the content appears exactly as before? All DOM elements with associated IDs, classes, styling, etc. need to be saved. I would need to "auto-save" these layouts as well.
The best answer I could find was this one:
How to persist changes made to Rails view rendered at client?
But this fellow seems to be saving the actual HTML mark-up. I think that will become very inflexible very fast. I thought I should be persisting the DOM tree itself, or possibly take the ReactJS route for designing my views, assuming ReactJS lets me save its VirtualDOM (or an instance of the actual DOM) to a database that it can then re-render upon log-in.
What am I missing? I've searched high and low for this but with out much luck on how to solve this problem. Any help is much appreciated!
Related
I have an ASP.NET Blazor server-side project, using EF Core. One of the pages is getting quite large. Apart from any other reasons for keeping code files a reasonable size, the large size causes significant delays when recompiling.
I would like to split it down into smaller components, but the problem is that the whole page represents a fairly large object graph, parts of which are used in multiple places on the page.
Imagine a page that shows details for a company. The company has many employees, each of whom can claim expenses, which are added to the company's transactions list. The company itself has income and expense, so that adds more transactions. Other parts of the company object graph might also have associated expenses. This is a very simplified (and fictitious) sample of the idea. The page has various sections, such as one for employee details, which shows their transactions, as well as an overall transaction list.
At various places, you can add transactions, which get associated with the employee (or whatever), and are shown on both that transaction list and the main one. All of this is done with individual forms for each action, it's not one huge form for the whole object graph.
If I were to split the component down, I would be faced with one of the following choices (unless someone can suggest another)...
Have each smaller component inject its own DbContext and handle its own data access. This is fine in theory, but would cause concurrency problems as it would mean that different components were saving changes to the same entities. It would also require a lot of events to inform the parent component that data had changed in the subcomponents, which would end up very messy.
Have each smaller component have parameters for the bits of the object graph they handle. This avoids any concurrency issues, as only the parent component would be doing any data access. I'm not sure if it would avoid the need for events, as it depends on how well Blazor would notice if a part of the graph passed to a subcomponent changed.
Pass the DbContext in to each smaller component as a parameter. Again, this avoids any concurrency issues, but really feels like the wrong way to do it.
Anyone able to guide me as to the best way to split this up?
Thanks
If you have lots of sub-components accessing the data in the Form [your top level component - some sort of dashboard?] then you probably have quite a bit of plumbing to try and keep everything in sync, or lots of rendering going on if you are cascading objects. How often are you calling StateHasChanged?
Without some code I can only answer in very generic terms.
Your first step is to separate out your data and data management from your components and form. Move the data and the database into a DI service. The scope depends on what you're doing: Transient or Scoped. You can then use normal events to signal updates to components that need to render if something changes. There's an answer here that shows how to do this - https://stackoverflow.com/a/69562295/13065781.
[Opinionated] You also need to understand that by building a complex object (your DataGraph) and then letting EF manage it's state, [in Clean Design terms] you're building core application logic (the relationships between your basic data objects) into your infrastructure layer. The advantage is it makes things easy, and saves a lot of coding. The disadvantages come to light over time.
I have an edit page which is grows with the size of the app. We're now running in to a situation where the server side action (MVC) is handling image uploads and conversions alongside regular text saving to database.
What's the best way to make this more maintainable? Separate controller for images uploads, so that we create an writeable API? Or more actions within the same controller?
There are few ways, which could let you mitigate the problem with rising complexity :
Implement HMVC, where each controller calls sub-controllers. This would let you to split up the "update" tasks in logical and manageable chunks. Especially, if i am correct in thinking that there is more the one "update page". The HMVC structure would let you to assemble different update pages from existing fragments with quite minor additional hustle. Main disadvantage: relatively large change in architecture.
Split the update page(s) in smaller forms, each submitting to a different controllers action (or maybe a different controller altogether). Main disadvantage: user can update only one part at the time
Evolve the model layer, so that the API you use interacts with service layer instead of domain model layer. This will let you isolate the complexity of updated and provide a simpler interface to use in controller. This too would have the added benefit of composing update form(s) from manageable pieces. But i don't know the penalties that come with this approach .. never have used it myself.
The bottom line is: you will have to change one part of MVC. In your situation i would choose the HMVC way, but mostly because i am familiar with it, and multiform page might induce rage from users.
As I have a complex domain model (DDD) where I need to create a few hundred forms in the user interface, I'm looking for a generator, preferably embedding the apple layout rules, and data binding. This is crucial to get a uniform application appearance.
I would prefer the generating to be of run-time instances (introspection), not static source code.
I do not want to build from a data model, as that doesn't have enough information to create something useable. I have information on grouping, validation, roles and rights, navigation, filtering, actions, workflow so I should be able to do much better layouts.
Even better would be the ability to also generate forms for the iPhone/iPad, using the default navigation.
[Results]
Sensible TableViews looks like the right kind of solution for iPhone. The descriptions are not yet sophisticated enough but provide a good starting point.
Interface Builder will do this for Core Data models if you option-drag parts of (or all of) your data model from the Data Modeler into a window or view in Interface Builder.
When you drop the managed object(s) you dragged, you're given an option to create a Single Item View, a Master/Detail View (with search and detail fields and add/remove buttons), or a Collection View (with box + search field).
I don't know of any third-party solutions to do this from "just any model." It'd be a great tool, but would likely require using an object model to define the entities (like Core Data's Managed Object Model).
Sensible Tableviews Might be able to help you. I haven't used them myself but it looks solid. It also supports generating forms from core data entities.
Maybe Echasoft Reports would work for your problem? (Plugin for Interface Builder that gives you easier reporting capabilities). I saw this demoed at NSConference, and it looks pretty awesome. Commercial, yes, but for 100+ forms it might be worth the money...
I'm developing an ASP.NET MVC application where the content for any page can be pulled from the database, if it exists, and displayed on the page.
This is to make it possible for non-technical persons to edit the content without having to go into the source code (e.g. views) and change things.
The way I'm doing this is, each controller derives from a base controller. The base controller overloads 'OnActionExecuted' and takes this opportunity to pull any content assigned to the current Action/Controller.
If the action returns a ViewModel that derives from 'ContentViewModel', it populates the 'Text' property of the ViewModel with the text from the database.
And then the text gets rendered by the View.
Can you see any weakness to this design?
Would it be better if, rather than having a base controller, I had HtmlHelper extensions for pulling content, which I call from the View?
One reason I'm asking this is, having my own base controller seems to interfere with calling 'Html.RenderAction', which seems to expect the specified controller to directly inherit from 'System.Web.Mvc.Controller'.
ActionFilters should not be used to pull the content.
Controllers should not be used to pull the content but only to dispatch the incoming requests by applying simple logic.
HTML helpers should not be used to pull any content. They are meant to render UI elements prefilled with the supplied data.
application where the content for any page can be pulled from the database
That's basically how most applications operate.
This is to make it possible for non-technical persons to edit the content without having to go into the source code (e.g. views) and change things.
For non-technical persons to edit content there should be an appropriate UI. Independently of the project underlying technology, non-technical personal is never supposed to edit the code.
I suggest you don't make anything weird but keep things clear. Implement your business layer that will supply the data to models which the view will render. Create a UI for other people to edit the content.
I am in the process of building a website content management system for one of my clients. It's a highly customized system, so I cannot use any "of the shelve" solution.
I need to allow my client to add pages to the website on the fly. I have two options here:
(1) Create a database driven page in the format of www.mycompany.com/page.aspx?catID=5&pageID=3 (query the database with the category and page ID's, grab the data and show it on the page) - or -
(2) Allow the management system to create static pages, something like www.mycompany.com/company/aboutus.aspx and www.mycompany.com/company/company_history.aspx , etc.
I believe that, while the former is much easier to implement, the latter is a better both for the user AND for Google.
My questions are (finally): (1) Would you agree that the latter is a better solution, and (2) What is the best way to implement such a solution? Should I create and update each file using the FileSystem (i.e. - the site's management system requires the user to supply a page/file name, page title and content, and creates the page on the fly based on these parameters)? Is there a better way?
Thank you!
It's entirely possible to have database driven pages with nice URLs. StackOverflow itself is a great example - this question's URL is http://stackoverflow.com/questions/1119274/adding-pages-on-the-fly-with-a-cms-system, but the page is built from the database, not static HTML.
I would use the first solution, but mask the addresses using a custom request handler. Basically, give each of your pages a unique string ID (such as about-us) and then, with your request handler that takes all requests, find this particular page in the database and render it.
See this article for some additional info (found it when googling for custom http handlers in ASP.NET.) In that article, it has the following handler added:
<add verb="*" path="*.piechart" type="PieChartHandler"/>
You would probably want to catch all paths (*), excluding certain media paths used for CSS, images and JavaScript.
More resources:
Custom HTTP Handler
HttpHandler in ASP.Net
I'd stay clear of static pages if I where you. Dynamic Data, MVC and some good planning should take you a long way!
What you need to do is to create some or many templates that each view/controller in mvc can use. Let whoever is responsible for the content handle it through dynamic data entities.
I would use the first idea, but work out a better URL scheme. If the system doesn't provide nice URLs (without ?), you'll have trouble getting the search engines to parse the whole site. Also using numbers instead of words make it hard on users to pass around URLs.
If you start to have performance problems you could add caching that would generate static pages from time to time. I would avoid doing that until you have to; caching can cause many headaches along the way to getting it right.
Although the existing advice is more-or-less sound, the commentators have failed to consider one factor which, admittedly, you haven't given much detail on. Are these pages that they'll edit once they're built, or a they one-shot creations? If the latter, your plan of generating static pages isn't quite so bad as they suggest. Why bother even having to think about database schemas and caching, when you can just serve flat content.
It will probably make for pretty lifeless, end-of-the-road pages, but if that's what you want ...