ASP.NET MVC 2: Use [Data Annotations] to reference methods that could feed DDL lists? - asp.net-mvc-2

A generally accepted way to pass all data to a view is to have a single data model with references to both your domain model and additional data for things like drop down lists (DDL).
However, partial views (view templates too) receive only a portion of the main model, not able to access the root of the Model sent to the original view. So if your DDL lists are not static, how do the partial views get the data?
Is there a way using [Data Annotations] to reference a method which could return the possible values of a field, then use this in the partial view's DDL? Where would this method exist, in the repository?
Links or C# code examples would be very helpful.

There is no built in Data Annotations attribute that could do what you ask.
You could create your own attribute that contains a reference to a Type and the name of a static method that you can then invoke via reflection from your partial view.
Where you would place such a method depends on what you are doing, though I still think that gathering all the inputs in your controller would be better. You can always set extra items in the ViewData collection and pass those into your partial views.

Related

Symfony2: where to put "pre-set" and "post-get" entity methods?

I have three different entity attributes which have to be "pre-parsed" before they get saved in the datebase.
Same attributes have to be "post-parsed" before being shown to users.
There are several different controllers actions which are setting/getting these attributes. Currently I preparse/postparse this attributes basicly in every of these methods.
How should I handle this? I was thinking about putting it directly into entity but that is not the place for that. Especially because I need the same pre-parse functions in a few entities.
Basically these function has to run before every setter and getter call.
if you have a t4 template that generates the model code, then it's relatively easy to change property setters/getters to do the data pre and post-processing.
You may want to look at Data Transformers - http://symfony.com/doc/current/cookbook/form/data_transformers.html
UPDATE:
Another, and probably the most appropriate, method would be to use Doctrine EventListener or EventSubscriber.
http://symfony.com/doc/current/cookbook/doctrine/event_listeners_subscribers.html
http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/events.html
In your case, you need to listen/subscribe to prePersist, preUpdate, and postLoad events.

Best practice for MVC 4 Edit Views and "Hidden" parameters

I have recently added some fields for auditing purposes to existing models in an MVC 4/ Entity project. I don't need these fields to be displayed on the edit page. However, they are required fields on the model.
As it stands, the edit page still works, but on the controller side, the ModelState.IsValid check fails because the required fields that are actually set on the item are not output to the view and therefore not re-submitted when the edit page is submitted.
Is there an easy, built in way to rectify this, or if not, which of the following is best practice for this scenario? Are there more options?
1) Set up hidden fields on the view to hold the information (Not a fan of this option, passes data around too much)
2) in the controller, on submit, first load the model by ID, then set each individual parameter based on the fields present on the view (Seems like extra unnecessary work)
3) Create a constructor for the model that takes itself as a parameter and pulls any non-default values and returns a new object. Basically a merge. (Best I think, still a lot of extra work)
4) ???
Best practice is to not use your domain model inside the views. Create a view model class that contains only the id and the fields you want in the view. Pass this model to your view. Change the parameter type of the form submit action to match your new view model. This will then pass the model validation without using hidden fields. In your action method, you can then retrieve the object from the database using the id property of the view model class and update fields as required.
Hope that makes sense.
I prefer to do the 2nd option as long as I can get the existing object with a single query or db call. This lets me to keep my view clean(no hidden fields for all those other properties) and use the existing update method which updates the domain model.
Look into your code. If the update method is making updates in lot of other places(many other tables) which is really not needed, then you could possibly write a short version of the update method which updates only the relevant parts ( ex: UpdateContactDetails).

Entity Framework, Link tables and mapping multiple tables to a single entity

I have an Entity called "Product", this entity, through table mapping, merges 6 tables that have a 1 to 1..0 relationship with "Products". This all works wonderfully. There is another property I want to add to "Products", which is sBBR_rate, this value is not in a table that has a direct 1 to 1..0 relationship, it is related through a link table as below:
When I import the two tables into the EDM, I can't see a way in the "Mapping Details" of
"Product" to reference the sBBR_rate. I can reference RatesLink and link that to the "Products" primary key, however, I cannot reference the BBR table.
The methods I can think of to work "around" this is are as follows:
Create a view, reference the view in the EDM.
Create an SP and use a function import to retrieve the BBR when it is required.
Create a "Rates" entity in the EDM that can then draw down the sBBR_rate into it. Navigate to the Products BBR through Product.Rates.sBBR_rate.
Is there a better way I can do this that doesn't feel so much like a fudge? Perhaps by directly editing the XML of the Mapping or Conceptual layers of the EDM?
Thanks for your input.
Because the multiplicities on the Product -> RatesLink and RatesLink -> BBR relationships are 0 to 1, you should be able to access the sBBR_rate from a Product instance like this:
myProductInstance.RatesLink.BBR.sBBR_rate
I can see on the EDM screenshot that RatesLink has a Product and BBR property, which would indicate this should be available - is it?
On a side note, if it makes sense for the sBBR_rate property to commonly be accessed directly from Product, you might want to follow the law of demeter and create a property on Product which returns it directly.
The model we are using is to extend entities by using partial classes which we've found useful so we can get additional properties in the autogenerated classes (we are using a POCO T4 template to autogen but I believe this would work just as well with the default entity object generation).
So we would have
//.. this one is from the T4 template
public partial class Product
{
//.. all the autogenerated methods
}
and in a separate file that isn't autogened
//.. now in a separate file created by me
public partial class Product
{
//.. my custom properties and methods to make the entities more usable
public string BBRRate
{
get {return this.RatesLink.BBR.sBBR_rate; }
}
}
This means that I can just do
myProduct.BBRRte
I know there are other ways to do this by amending the edmx file but this one we found easy to implement. You just need to watch performance because you are potentially loading extra data. Also we did this with LazyLoading turned on but with more work you wouldn't have to
We also experimented with hooking into the ObjectMaterialized event in the ObjectContext class to preload some of these properties. Using a custom interface i.e. IMaterialisable we could check if the object was of that type then call a method (Materialise) to prepopulate some of the properties. This seems like a good idea but we didn't widely use it - it was easy to load up too much stuff. If you do the load on the properties in the partial classes then it becomes more efficient. Just my experience.
Anyway - as always an interesting question and good luck again with your dev.
EDIT
There is a rule that everything in the store layer must be represented some way in your conceptual layer. Therefore removing the tables from the conceptual layer but bring through some of the properties I don't think will work in it's gross form. Therefore I can think of two further options
Create a View on the database and bring that in as you have already mentioned. TBH this is what I would do.
Use the DefiningQuery element directly in your xml (the store layer) and map the query through to a custom entity of your exact design. Julie Lerman describes this as the ultimate escape hatch for Entity Framework.
Remember though - if you manual amend the XML in point 2 then you lose the ability to automatically update the module through the IDE
I ended up creating a view and then linking this view in the EDM, this worked a treat.

Best approach to control access/handle objects/models data passed to View in Zend Framework

I want to pass data to views, and I've two options in my mind (if you know a better approach, please mention).
I am using Zend_Based ORM system, and coded in a way that if I add a new field in database, its automatically available within the model.
1st: I convert the model's data into array and pass the array to the view. This way I will have all the data available within the view, but model's function/operations will not be available. And incase I need specific functionality, i will be coding view helpers while there are chances that the same functionality is already coded within model. e.g. a getting a date in specific format.
2nd: Or I pass the complete model object to the view, this way I will have all the model's functions available, but view will be able to access model's save function which is a bad thing. I can add some more functionality within model to make it read-only, but it will be extra work.
any suggestions which approach is better.
According to the MVC principle it's perfectly fine to let the View allow access to the Model. So, pass the complete Model to the View.
By the way, passing arrays around will copy your data (by value), while passing objects around will not (by reference). (Assuming PHP5). Large arrays might affect your performance.

ASP.NET MVC 2: Any way to pass two Objects to a Template?

A "Lookup" in this example is an IList<string> of state abbreviations. Generally, your Domain Model POCOs won't include these options. ViewModels usually take this responsibility referencing both the original Domain Model as well as the Lookup object, but what happens when the Domain Models are nested and you are using MVC templates (which won't have access to the original Model's root properties?
Is there a way to include the Lookups in one object and the Model in a different object for the template? Is it permissible to assemble on-the-fly a ViewModel specific to that Template within the View (which would have to include any nested data from there)? I would think static methods to pull down Lookup values is bad.
Any ideas?
Notes (to my knowledge):
A Domain Model POCO from a repository doesn't change in structure. If you need a single Model to have both the Customer object and the DDL options for US State for example, you normally have a ViewModel that references the Customer object and the Customer Lookup lists.
However, when you have a nested Domain Model (aggregate root), the nested objects have no where to put the Lookup Lists, and the MVC templates cannot access the root level View Model (their view model is the partial Model).
Edit:
Is there some way to put the DDL lists in the root level of the ViewModel, then when you get to the Customer object, construct a new ViewModel that references the root level DDL lists and the current Customer object to send to the template? This would eliminate duplicate data in the Model as well as use a single Model for all the Views. The only bad would be Controller like data assembly code in your view (which is just as bad).
A couple of suggestions. First, use separate view models for your views -- don't directly use your domain models. These view models can, and should, carry the extra data needed by the view. Second, you can use the overloads on DisplayFor/EditorFor to pass additional view data to the template. That way your template can be specific to a particular domain model and yet have access to the additional data in the view model.
For static, unchanging lists like state abbreviations, you could use Application state or Cache entry. These types of lists could be loaded in Application_Start from a database.