Razor view display domain model properties without knowing the domain model - asp.net-mvc

Background: I have a simple mapping app (backed by GeoServer) that allow a user to click on a feature and select a data table displaying information about the selected feature. A HTML table would then be inserted under the map to show the query results.
Problem: Since there are at least 40 something tables that the user can select, I don't want to build 40+ partial views. Is it possible to build a Razor view that can handle any model passed to it and build a HTML table without knowing the domain model's structure? I'm leaning toward no after some poking around.
Reference: Related to my previous question of
Dynamic DBSet lookup and query

Practically, asp.net mvc already does that when you call EditorForModel, DisplayForModel or similar. If there is no developer defined view for corresponding model type, it calls object template, which uses reflection to render editor and display views. That template does not have predefined knowledge of model type.
You could set model type to object for view, and make use of reflection to generate tables.

Related

Create a View of type List in ASP.NET MVC 2

I am practicing MVC 2 (I'll do MVC 4 in just a bit) after almost 2 years, just to revise before I jump to MVC 4.
I am creating a strongly typed view of one of my data objects called Category. I want to create a list type view, i.e. a view that displays all records from the Category table.
I recall there used to be T4 templates of each type of view -- Index, List, Create, etc. that you could choose from.
But I can't find them. When I create the View, the Add View dialog shows a disabled input field for View content.
I don't think you can have Visual Studio generate the list for you. After all, you need some lookup logic to get all the objects you want to display in the list.
You might want to check out this blog post for a nice way to pass a list of objects into your drop down list. You will, however, need to supply the objects yourself.

Should I render optional sections of a form via partials?

As an exercise in learning .NET, I'm moving some simple forms over into MVC, and have run into an issue. The form in question is a multi-part form that has option sections. For example, Section 0 is static and contains information like username, real name, email address. After that is a radio button with several options. If you click the first radio, it displays Section 1. If you choose the second, it displays Section 2, and so on.
In WebForms this was no biggy, as I just validated on postback and said if Radio1.Selected validate this, if Radio2.Selected validate that, etc. So now I've got a strongly-typed view with [Required] members, which obviously isn't going to work - I can't require members that aren't always going to be required.
With that said, is this the correct approach to the problem:
Create the members that belong in Section 0 in my strongly-typed view model class.
Create references to each partial's strongly-typed class in my view model class.
Create the partial views and then render them in the main view.
Depending on which radio button is selected, render the appropriate partial view.
Validate the model like usual...which hopefully will cascade to the partial models.
Does this make sense, or is the approach wrong?
That's a typical scenario where you need conditional validation, i.e. if some value is set then validate that some other value is required. Achieving this with static data annotations which are simple attributes baked at compile time can quickly turn into a nightmare due to their declarative nature. Well, you could always roll your own custom validation attributes but the problem with attributes is that you will have to specify property names as strings as they need to be known at compile time.
That's one of the reasons why I use FluentValidation.NET. Not only that validation rules are separate from the view models and that it integrates really nicely with ASP.NET MVC but handling scenarios like this would be very easy. You could have a sub-view model containing all the properties of the sub-section and then conditionally include it based on the value of a given property on the main view model inside its validator.

How do you elegantly program ASP.NET MVC when the View needs more than one Model?

A View accepts one Model.
But I need to draw HTML input controls for two models.
An example will illustrate:
I have a screen where I add Employees.
After adding their first name, last name and so on, I need the user to choose a number of Companies the Employees could be in.
The Companies are in one table.
The Employees are in another.
And a linking table joins them.
So it seems I need to pass the Companies to the View.
Can I pass multiple models to the view?
Or do I have to do an ugly database lookup in the View to find the Companies and manually spit out HTML for checkboxes without HTML helpers?
A Model doesn't have to consist of just one object or a single collection of one type of object. It can contain many objects and/or collections of objects. It seems that the model required for your page consists of at least collections of both employees and companies. If you have no type which fits this bill in your business object abstraction then you need to create a ViewModel for this page which can do the job.
This answer may help to explain how a ViewModel fits in MVVM ViewModel vs. MVC ViewModel
This is not entirely obvious - I'm sure it is to some guru types but for the rest of us trying to work things out its a bit more interesting.
Without going into detail I see a number of ways of solving this:
You need both sets of data so you need a view specific View Model
Your model is the Employee but you can still add other data to the ViewData - so make the Employee the model and pass the company data in as well as view data but not part of the model
(You may want to do this regardless of what model you use) Render the company selection elements as a separate view - which is where things get interesting - you obviously have to pass the existing selection, or a means to identify same, to the component view but do you have to pass the company list or could you, at this point, cheat a bit (prgamatically)? My feeling is that this is a partial view and that you need to pass it a company selection model (list of companies with selection indicated) but you could in theory do RenderAction and have an action that returns a view that goes to get the company selection for the specified employee - that way the overall view never sees the company data, that becomes a separate encapsulated problem - at least in terms of loading the data.
I think in this case where you're adding the employee either tweaking the model or adding the company list as supplementary data to the ViewData is sufficient, but for editing - assuming its required - rather than inserting you want a company selection list (all the companies with flags to indicate which are currently selected) rather than just a list of companies and at that point it all gets a bit more interesting

MVC reusable propertygrid

In my web application framework (currently WebForms) I have a control that behaves like a classic propertygrid. It is initialized with an object ID (database key), then it reads metadata to determine the type of the object and the attributes of the object. It displays the attributes, string attributes as textboxes, bool attributes as checkboxes, enum attributes as dropdown lists. On page submit there is a method of the control ctrl.SaveData() that saved the changed attribute values back to the database.
The WebForm control tree and event model supports this approach quite nicely. Now I am asking myself if it is possible to achieve a similar solution for ASP.NET MVC. The main objective is to have a generic, reusable component that can be applied in a variety of situations with not much hassle. Additionally the solution must be flexible enough to put multiple instances of the component for multiple objects on a single page. Here the auto-generated WebForms HTML IDs also helped.
I am very curious about your ideas! Thanks a lot for answering!
You could achieve this effect using a custom ViewModel that contains enough metadata to identify the object being edited/saved. You would use this in conjunction with a partial view that renders the ViewModel. The main page would use the metadata in the ViewModel to either direct the post to a specific controller action to save that particular object or pass the metadata back to a common action (as hidden inputs, perhaps) in order that that action can choose the proper table in which to persist the data.
Personally, I would not take this approach. My feeling is that the more general you make a view/action, the more work it becomes to adapt it for different circumstances. I have done similar things for viewing sets of objects, but for a detail view or editing I like to work with more specific models and views.

MVC Model: submitting multiple objects to the View

I'm not sure if there is a difference in these two methods. If so, which would be considered the better practice when submitting more than one object to the View.
Having the controller make separate calls to the datalayer for each object model and then wrapping the objects in a model to send to view.
Defining a "presentation" model and having the controller call that single model to send to the view.
other...?
I'm assuming here that you have a view that presents some information from more than one model, perhaps in a list format. For example, you may have a model of a customer which has a set of contacts, but in your list you want to choose to show some of the customer details along with the name and phone number of the primary contact. What I would typically do in a situation like this is define a specific "presentation" model that consists of just those details that I may want to show in this combined view. It would typically be a read-only model. Using LINQ to SQL I might even define this as a table-valued function (to support search) and associate it with a view that encapsulates the join of the various tables. With both you can add the view-based "presentation" model to your DBML and associate the table-valued function with it as a method on the data context.
I prefer doing this because I believe that it is more efficient in terms of queries to construct the query on the server and simply use it from the code. If you weren't using the table-valued function for searching, you might be able to construct the query in code and select into a "presentation" class. I would favor an actual class over an anonymous type for ease of use in the view. Getting the properties from an anonymous type in the view would be difficult.
You should send to the View a single object, sometimes termed a ViewModel object, containing all the data (including domain model objects) that the view will need.

Resources