MVC - How best to organize commonly used drop-down lists in many views - asp.net

I am trying to understand how best to organize some common Dropdown lists used in several views (some are cascading)
Is it best to create
a single \Models\CommonQueries
then create a webservice for each dropdown used in cascading situation
then have a single controller that contains actions for each dropdowns
This way I can follow DRY principle and not repeat the dropdown logics since they are used in various views.
Much Thanks and Regards for reading my question and taking the your time.
+ab

When you say your dropdowns are used in several views, do you still consider these dropdowns as part of the view that is rendering them? If so, I think using a custom HTML helper or a partial view (ascx) is appropriate. Then, like you suggest, you can populate the data for the dropdowns using a common service from your domain layer. I think that is a very reasonable approach.
However, if you feel the dropdowns are somewhat external/unrelated to the view, then you might find that using Html.RenderAction() gives you a much cleaner result. Using Html.RenderAction(), you can output the result of an Action method directly into any other view. Therefore, you can create 1 controller with the necessary Action method(s) to populate those dropdowns. For example, let say you have a view with roughly something like:
<div>
<div id="coreView1">
<!-- some view code here -->
</div>
</div>
<div id="commonDropdowns">
<% Html.RenderAction("Create", "Dropdown"); %>
</div>
where Create is the name of your method in the DropdownController.
For example:
public class DropdownController : Controller
{
public ViewResult Create()
{
// do stuff here to create the ViewResult of the common Dropdowns
}
}
Note: Some people dislike this approach as it doesn't fit the typical MVC seperation of concerns. However, it can be a really great fit for some cases.
Hope one of these approaches can help.

Related

Looking for a way to implement a polymorphic view in ASP.NET Core

I'm working on an ASP.NET MVC Core web app that would have a lot of similar views. Each view is just a simple form that has a list of label&control pairs.
An "Object" editor template has been built in order to generate the content of such views automatically based on view model properties.
Each view would basically have just one line of code:
#Html.EditorFor(m => m)
Each view model is derived from a base class.
Is there a way to get rid of duplicate views and controller actions?
Ideally, I'd like to have just one view where the model is the base model class and one controller action that would receive that base model.
Himanshu's comment steered me to use Partials for the child classes and use the base class as the model for the main views. You may be able to just use reflection/property annotation to populate the views according to the given Model, though I have not tried it.
What I have tried successfully is using a base class that is not abstract and thus will not duplicate properties in the child classes, then using generics like...
List<T> GetChildClasses<T>() where T : BaseClass;
which is called by the controller method and supplies the View Model, and then displaying like this...
#model MyApp.Models.BaseClass
<div class="show_base_class_properties_here">
</div>
#if(Model is ChildClass)
{
#await Html.PartialAsync("_ChildPartial", Model);
}
<div class="whatever_comes_next">
</div>
I suspect there is a better way but this works. Apparently there can only be one #model in a view file.

How to inject a child component into a razor generic component like react.js

I would like to know if it is possible to create components (Razor / Asp.NET) like the react style. I'll illustrate:
<GenericDadContainer>
<ChildComponentDinamic />
</GenericDadContainer>
I want to do this so that my parent containers have dynamicity. They will serve only as containers, and your children need to be dynamic regardless of their models.
If possible I would also like to know if in this context it would be possible to pass parameters to the same besides the child itself.
I understand little of Razor, and I didn't find anything from the internet on a way to reuse the layout better.
Not exactly the same style, but the same idea: in Razor, you can use the so-called "partial views" to divide your page up into "components", and yes, you can pass data to a partial view.
Here is a mini-example:
<div class="container">
#Html.Partial("view-name-here", model)
</div>
The model variable could be any object you choose.
Read up on partial views in ASP.NET/MVC, for example here.

How to stop knockout.js bindings evaluating on child elements

Using knockout, when you call ko.applyBinding(viewModel, "divId") it does a recursive binding down through the children of the element you bound to ("divId"). I would like to stop this evaluation at a child node. Is there a way to do this?
the reason why...
I would like to bind the entire page to a navigation view model, this will handle basic layout and ...smile... navigation. On the various pages I would like to bind certain regions to different view models that are not properties of the navigation view model. At the moment if I do this I get "unable to parse binding" errors as the navigation view model does not have the required properties. If I could stop the binding walking down the dom, I could just bind these items separately.
There are several ways that you can go on this one. Typically, you would add multiple "sub" view models to a main view model and then use the with binding on the various areas with the actual view models to bind against them.
It is possible to technically do what you are after. You can create a custom binding that tells KO that it will handle binding the children itself. It would look like:
ko.bindingHandlers.stopBindings = {
init: function() {
return { controlsDescendantBindings: true };
}
};
When you place this on an element, then KO will ignore the children. Then, you could call ko.applyBindings on a child of this element with a different view model.
Sample: http://jsfiddle.net/rniemeyer/tWJxh/
Typically though, you would use multiple view models underneath a main view model using the with binding.
One way I have done this is to create a section for the navigation (or just a ) and bind the navVM to it. Then create another section for the content and bind the contentVM to it. That way there is no conflict and its all very separated.
<body>
<div id="navSection">
</div>
<div id="contentSection">
</div>
</body>
Then do ko.applyBinding(navVM, "navSection") and ko.applyBinding(contentVM, "contentSection")

ASP.Net MVC 3 Razor: how to create and pass info to a dynamic layout

In other languages (PHP/Python), I am used to creating a class which represents a given HTML page layout. These classes can have an unlimited number of attributes and dynamic features, such as Navigation (multi level), error messages, info messages, footer text, etc... Most of these items have defaults, but may be overridden on a per-page level. For example:
Layout = MainPage()
Layout.Title = "Google Image Search"
Layout.Nav1.Add("Google", "http://www.google.com", Selected=True)
Layout.Nav1.Add("Yahoo", "http://www.yahoo.com")
Layout.Nav1.Add("Bing", "http://www.bing.com")
Layout.Nav2.Add("Google Image Search", "http://......", Selected=True)
Layout.Nav2.Add("Google Shopping Search", "http://......")
Layout.Nav2.Add("Google Video Search", "http://......")
Layout.Nav2.Add("Google Web Search", "http://......")
or, handling errors:
try:
# do something
except ValidationError as e:
Layout.Error.Add(e)
or a php example:
$Layout->Info[] = "Your changes have been saved!";
My question is: how do I implement similar functionality into ASP.Net MVC 3 Razor (VB)?
So far, I have been able to see how you can use ViewData to pass various bits of data to a view. Also, I have been working with strongly typed views.
Frankly, I'm not sure who's job it is to have this logic, the controller or the view (or is there a model that should be in there somewhere).
Here is a summary of what I am shooting for:
A single place to initialize the default values for the layout (like the first layer of navigation, etc...)
Strongly typed attributes, such as Public Readonly Property Nav1 as List(of NavElement)
And a single place to render these layout elements (I assume _Layout.vbhtml)
Please forgive the here-and-there of this post... I'm trying to figure out the "right way" it's done on a platform that is both new (Razor) and new to me (ASP.Net MVC).
General advise very welcome!
I usually have a controller property (MainMenu) which I add to the ViewData dictionary in Controller.OnResultExecuting in my BaseController. Note that it's named ViewBag in mvc3 and it's a dynamic object.
Another approach would be to use sections in razor. Look at this question: ContentPlaceHolder in Razor?
I lean toward the fat models, skinny controllers perspective. If it were me I would create a base class for your page models that provides support for your common data. You can then inherit from that for individual page models and store your page specific data there.
The MVC implementations that have worked well for me usually have relatively clean Controllers. The controller is just the connector, getting the data from the request into the model and then handing off the prepared model to the correct view.
As for how you store collections of things in .Net - look at the classes that implement IEnumerable interface. Specifically focus on the Dictionary and the List classes. Dictionary objects store name/value pairs and can include nested dictionaries. You can work with them almost exactly like you can use multi-dimensional arrays in PHP. List objects are just indexed collections of items of the same type. You can work with them just like a simple array in PHP.
One side note - if you're just getting started in .Net and coming from a PHP/Python background, it might be better if you can switch to C#. You'll find the syntax much more comfortable and the tutorials/examples more plentiful (especially in the asp.net mvc world)
It's not difficult! :-)
If layout model is of the same type of the content page, the association is automatic! Here is the simplest example...
This is a test layout:
#model string
<style>
.test
{
background:#Model;
}
</style>
<div class="test">
Ciao
</div>
#RenderBody()
And this is a test content page
#{
Layout = "~/Views/Shared/_Test.cshtml";
}
#model string
...blah blah...
Just call the View with something like:
...
return View("Name", (object)"Green");
and it's done! The model is the same in the content page and in the layout page!
Andrea
P.S.: Believe me! This is useful!!! Maybe it's not the best for purists, but it's really useful!!! :-)

MVVM - what should contain what... what should create what

I'm having a right barney getting my head around how everything fits together using the MVVM pattern. It all seems quite simple in practice but trying to implement it I seem to be breaking various other rules that I try to code by.
Just as a side note, I'm trying to implement the pattern using Flex, not Silverlight or WPF, so if anyone can come with good reasons why this shouldn't be done, then I'd like to hear them.
I have a problem where I have several views. Sometimes I have to display two views on the page at the same time; sometimes I switch back to a single view. In my normal Flex brain I would have a main view with a code-behind which contained all my other views (equally with code-behinds). That main view would then do the switching of the other individual views.
When I try to implement this in MVVM I'm trying to stick to the principles of MVVM by using binding which decouples my Views from the ViewModels. Let's say I create a ViewModel for application-wide state and my ApplicationView binds to that data and does all the switching of the sub views.
Now, where should I create my view models for my subviews? I've tried inside the ApplicationView -- that didn't seem right. And then I've tried outside of the application view and passing and instance of it into the ApplicationView and then my sub models a bind to it. Am I missing something? None of these methods seem to fit the whole point of trying to decouple this.
Any good books or links that explain this problem would be much appreciated.
Cheers,
James
The approach you are referring to is ViewModel composition. Its where you have multiple complex view parts that need to bind to their own ViewModel entity. The approach entails constructing a root ViewModel with properties for each child ViewModel. Then the root View is bound to the root View Model and each View (whether displayed or collapsed) is bound to the corresponding property on the root ViewModel.
The ViewModel would look like this:
public class RootViewModel
{
ChildViewModelA ChildA { get; set; }
ChildViewModelB ChildB { get; set; }
}
The View would look like this:
<Grid>
<ChildViewA DataContext="{Binding ChildA}" />
<ChildViewB DataContext="{Binding ChildB}" />
</Grid>
You could also implement this in away to allow yourself to select an active workspace.
The ViewModel would look like this:
public class RootViewModel
{
public List<ViewModel> ChildWorkspaces { get; set; }
public ViewModel ActiveWorkspace { get; set; }
public RootViewModel()
{
ChildWorkspaces.Add(ChildViewModelA);
ChildWorkspaces.Add(ChildViewModelB);
}
}
The View would look like this:
<Grid>
<Grid.Resources>
<DataTemplate DataType="ChildViewModelA">
<ChildViewA />
</DataTemplate>
<DataTemplate DataType="ChildViewModelB">
<ChildViewB />
</DataTemplate>
</Grid.Resources>
<ContentControl Content="{Binding ActiveWorkspace}" />
</Grid>
This will result in the appropriate visual representation being selected implicity based on the type of the actual object stored in ActiveWorkspace.
Pardon my response was in WPF. I tried my hardest to not get caught up in the syntax of it all :-)
As you can see the plurality of "ViewModel" can be ambiguous. Often times we find the need to construct multiple sub-entities to structure the ViewModel appropriately. But all ViewModel entities would be somewhere within the root View Model object.
When implementing MVVM in WPF, I prefer to infer what visual element to apply data context implicitly (as illustrated in the later half of this response). In more complex scenarios I prefer to use a DataTemplateSelector to conduct that decisioning. But in super simple cases you can explicitly apply DataContext either imperatively in C#/ActionScript or declaratively through bindings.
Hope this helps!
I've seen variants of the MVVM approach used on a couple different Flex projects, but I haven't seen an approach that feels perfectly right to me. That said, I think using Presentation Models makes testing in Flex a lot easier, so I'm pretty sure that there will start to be more applications designed around this pattern.
The easiest approach I've seen to implementing MVVM in Flex is to place the individual ViewModels within the application Model / ModelLoactor. The ModelLoactor contains any global data and also serves as an accessor to all ViewModels. ApplicationViews can then bind to their particular ViewModel through the ModelLocator, while ViewModels can be updated both through Commands and through bindings to their parent ModelLocator. One benefit of this approach is that all of the data logic is localized; of course, this could also be seen as a drawback, with the central ModelLocator being a touch brittle due to its hard coded references to all ViewModels.
I've seen cleaner approaches work by using the Mate framework. Mate allows for a much more decentralized injection of ViewModels into the appropriate ApplicationViews. (I suppose this could also be accomplished with Swiz, I'm just not as familiar with that framework). With Mate, each ApplicationView has its ViewModel injected via a Map. What's cool with this approach is how ViewModels can be updated using an EventMap (the Mate version of a FrontController). Essentially, your ApplicationViews will dispatch events that are handled by one or more EventMaps, and these Maps can then make changes to one or more of the ViewModels. This approach allows for a user gesture or event from one ApplicationView to change the state of several ViewModels at once. In addition, because this logic is extracted into Mate's EventMaps, it's very easy to change how events are handled or which ViewModels are changed. Of course, the major drawback of this approach is that you're committing to using Mate as a framework, which may not be an option depending on the requirements of the project.
I hope that helps!
I wanted to share a comparison I wrote up of MVVM (Silverlight) vs PresentionModel (Flex). It shows how the two implementations of the same pattern differ/compare:
http://houseofbilz.com/archives/2010/12/29/cross-training-in-silverlight-flexmvvm-vs-presentation-model/

Resources