I am coding an MVC internet application, and I have a question in regards to using the ViewBag.
In many of my controllers, I have SelectList objects, where the user can select an object. The object that is selected is a foreign key value for my model.
My question is this: Should I use ViewBag for this? How secure is the ViewBag? Should I use values in my ViewModel instead of the ViewBag?
Thanks in advance.
Use your view model.
When the ViewBag was implemented (MVC 3) dynamic typing was new (.NET 4.0) and it was put in just as a side-option to ViewData or to quickly generate a view without the need for additional classes.
Any serious MVC project will take advantage of a model/viewmodel with a strongly typed view.
There are no security concerns with either because both essentially only exist through the controllers lifespan.
There are no security concerns with ViewBag since it is disposed once rendered in the View.
I think the answer really should be "it depends". For example, if you have 6 collections required to populate dropdown lists aand you want to get the data posted back, you should definitely use a ViewModel for this. Since 6 collections will be hard to manage if they are stuffed in ViewBag with no strong typing in the view, especially if another developer comes along later needing to do maintenance to the view.
Generically everything should be done inside a view model. That's what a view model is. A class that you specifically define to meet the requirements of your view. Here is an image depecting when to Use TempData, ViewBag or ViewData
Related
I have a general JSF problem, I found no nice solution for yet. See the picture for a general idea. I have a workaround solution (sorry for the typo in the image) in place that solves the problem by a listbox. However the desired solution is to display all existing versions next to each other (probably always around 1-3).
I have a view with a tree and picklist. There is a complex flow regarding the interaction between list and tree, e.g. you can only move models to subgroups, not top-level-groups and much more. I created a handler class that manages this behavior and translates it to service calls.
Now, a new requirement came up. There are several versions of this tree that should be displayed all together on one page. My gut feeling is that managing n versions in one handler is a big mess as I need to store several things in the handler already for one version.
In React, I would create a component that wraps the tree and all of the interaction. However, in JSF I'm not so sure what is the best practice here?
I would be happy about suggestions and ideas, I'm not expecting Code :)
I found a solution that fits my needs and I post it here hoping that it might help other people as well :)
So on my view I have several tree views with complex interactions. For example, if an item within the tree is moved, the operation is immediately reflected in the database. As I use JPA, I need to translate this to an entitymanager call.
The views are either displayed in a list or just one-at-a-time via a dropdown select.
Anyway, the idea is that every complex view component has its own controller with a reference to an entitymanager and a transaction, while having just one JSF handler class. If JSF would allow to create multiple handlers (like #{handler_1}, {handler_2}), the problem could be solved in a different way. But as JSF works name based and the name {#handler} always refers to the same container managed thing, this is no option.
The handler class is ViewScoped (or SessionScoped, if you prefer). For each tree component it has a ComponentController class that receives the EntityManager and the UserTransaction as well as the related data form the handler via constructor injection. This way, the handler can delegate all commands to the Controller while being DRY.
With this solution, the controller logic can be re-used regardless how many tree components exist. Each view elements binds a specific controller via handler.controllers.get(id).
All other solutions did not work for me as they are not able to perform database operations on view interactions.
To not have to keep repeating some validations, for example, who can see a button in a certain status of a document in the worlflow, I'm using session, scope, and session variables to store the user roles and application variable to store the Status related to each area.
I was evaluating whether it would be better from a performance and build point of view to implement a managed bean, to return the user roles and the possible statuses of each participating workflow area. Would it be the best structure in fact? What do you think? I do not have much experience in java. How could I construct the structure in java, several methods, one for roles and the other for set of status associated with the area that would name the related method? You could return the results of this method in arrays, or there is a better return structure.
Thanks a lot!
My best suggestion is to adopt the pageController Methodology. Then it's more like true MVC. This has been talked about on NotesIn9 screencast many times but basically you have a java object that's bound to your XPage. In effect it's a viewScoped bean that holds all your page logic. Then you can have methods like isGroupMember(), hasRole() etc and calculate that on the pageInit. There's little need to hold onto that in sessionScope in my opinion. So for example I have this in my pageController :
public boolean isGroupMember(String groupName) {
return JSFUtil.getXSPContext().getUser().getGroups().contains(groupName);
}
So that's available to each page. BUT I don't need to copy that snippet onto every page controller. In Java you can have your page controllers extend a more generic class. so I have a "base.pageController" class. All the specific page controllers extend that. So this isGroupMember() code goes into the base and then it's available to be used on every XPage. Doing it this way gives you the ability to have generic functions like this and then hold more specific function that are only for the individual page.
You can also have a hasRole() function etc...
Recommend you check out this video : http://www.notesin9.com/2016/08/25/notesin9-196-no-dependency-page-controllers/
Also for a question like this, I recommend you just use the xpages tag. Adding others like javabeans can bring people in who know nothing about XPages and XPages is unique enough of a beast that outsiders can cause some confusion on occasion.
i'm developing an asp.net mvc 5 web application using a page that is compose by around 10 module.
I'm implementing each module using a partialview with Html.action, that calling an action that get data from a web api
My doubt is about performance. Can Html.action destroy performance ?
Thank you
I think it depends upon the data and its dependency over the populated view
Html.Action
Action method is useful when the displaying data in the partial view
is independent from corresponding view model.For example : In a blog
to show category list on each and every page, we would like to use
Action method since the list of category is populated by the different
model.
#{Html.Action("Category","Home");}
Html.Partial
Partial method is useful used when the displaying data in the partial
view is already in the corresponding view model.For example : In a
blog to show comments of an article, we would like to use
RenderPartial method since an article information with comments are
already populated in the view model.
#Html.Partial("_Comments")
Is it possible to associate a view with different documents (not simultaneously of course)?
What I want to achieve: the application can have multiple documents of the same type, that can be added during runtime, and set of suitable views, the main of which is CFormview-based. The user can choose the number of the document to show per combobox in the toolbar. The views then associate themselves with this document and update with data from it.
Is it possible to achieve with CMultiDocTemplate?
If yes, how? especially is it possible to retrieve a document by it order number?
If not I'll probably have to abstain from using the templates altogether, which of course means more coding (and more questions to friendly community), but it will do what I want it to do and not Microsoft thought I should be doing
Yes, you could but not out of the 'box'. Instead I'd recommend a different strategy. Rather than trying to attach a View to an existing CDocument derived class LOAD the Views CDocument with the information you want. That could done by adding a simple Copy method to the CDocument or you could move your actual data into a separate class then just point the CDocument to 'data' you want.
Trying to change the CDocument instance for a CView is going against the MFC grain which normally means lot of ASSERTS.
I want to serialize an Entity Framework Self-Tracking Entities full object graph (parent + children in one to many relationships) into Json.
For serializing I use ServiceStack.JsonSerializer.
This is how my database looks like (for simplicity, I dropped all irrelevant fields):
I fetch a full profile graph in this way:
public Profile GetUserProfile(Guid userID)
{
using (var db = new AcmeEntities())
{
return db.Profiles.Include("ProfileImages").Single(p => p.UserId == userId);
}
}
The problem is that attempting to serialize it:
Profile profile = GetUserProfile(userId);
ServiceStack.JsonSerializer.SerializeToString(profile);
produces a StackOverflowException.
I believe that this is because EF provides an infinite model that screws the serializer up. That is, I can techincally call: profile.ProfileImages[0].Profile.ProfileImages[0].Profile ... and so on.
How can I "flatten" my EF object graph or otherwise prevent ServiceStack.JsonSerializer from running into stack overflow situation?
Note: I don't want to project my object into an anonymous type (like these suggestions) because that would introduce a very long and hard-to-maintain fragment of code).
You have conflicting concerns, the EF model is optimized for storing your data model in an RDBMS, and not for serialization - which is what role having separate DTOs would play. Otherwise your clients will be binded to your Database where every change on your data model has the potential to break your existing service clients.
With that said, the right thing to do would be to maintain separate DTOs that you map to which defines the desired shape (aka wireformat) that you want the models to look like from the outside world.
ServiceStack.Common includes built-in mapping functions (i.e. TranslateTo/PopulateFrom) that simplifies mapping entities to DTOs and vice-versa. Here's an example showing this:
https://groups.google.com/d/msg/servicestack/BF-egdVm3M8/0DXLIeDoVJEJ
The alternative is to decorate the fields you want to serialize on your Data Model with [DataContract] / [DataMember] fields. Any properties not attributed with [DataMember] wont be serialized - so you would use this to hide the cyclical references which are causing the StackOverflowException.
For the sake of my fellow StackOverflowers that get into this question, I'll explain what I eventually did:
In the case I described, you have to use the standard .NET serializer (rather than ServiceStack's): System.Web.Script.Serialization.JavaScriptSerializer. The reason is that you can decorate navigation properties you don't want the serializer to handle in a [ScriptIgnore] attribute.
By the way, you can still use ServiceStack.JsonSerializer for deserializing - it's faster than .NET's and you don't have the StackOverflowException issues I asked this question about.
The other problem is how to get the Self-Tracking Entities to decorate relevant navigation properties with [ScriptIgnore].
Explanation: Without [ScriptIgnore], serializing (using .NET Javascript serializer) will also raise an exception, about circular
references (similar to the issue that raises StackOverflowException in
ServiceStack). We need to eliminate the circularity, and this is done
using [ScriptIgnore].
So I edited the .TT file that came with ADO.NET Self-Tracking Entity Generator Template and set it to contain [ScriptIgnore] in relevant places (if someone will want the code diff, write me a comment). Some say that it's a bad practice to edit these "external", not-meant-to-be-edited files, but heck - it solves the problem, and it's the only way that doesn't force me to re-architect my whole application (use POCOs instead of STEs, use DTOs for everything etc.)
#mythz: I don't absolutely agree with your argue about using DTOs - see me comments to your answer. I really appreciate your enormous efforts building ServiceStack (all of the modules!) and making it free to use and open-source. I just encourage you to either respect [ScriptIgnore] attribute in your text serializers or come up with an attribute of yours. Else, even if one actually can use DTOs, they can't add navigation properties from a child object back to a parent one because they'll get a StackOverflowException.
I do mark your answer as "accepted" because after all, it helped me finding my way in this issue.
Be sure to Detach entity from ObjectContext before Serializing it.
I also used Newton JsonSerializer.
JsonConvert.SerializeObject(EntityObject, Formatting.Indented, new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.Objects });