Breeze doesn't post navigation properties - breeze

I inherited an OData service that exposes - among other things - a type called Evaluation. This type contains a lot of primitive type properties (int, bool mostly) and two navigation properties/links to other entities.
Breeze is configured to use the v3/'original' odata adapter:
breeze.config.initializeAdapterInstance('dataService', 'odata', true);
If I create a new entity
var manager = new breeze.EntityManager('odataEndPointHere');
manager.fetchMetadata().then(() => {
var newEvaluation = manager.createEntity('Evaluation', {Name:'Foo'});
});
then this newEvaluation will reference all primitive fields and the navigation properties (called Validation - a TPH type - and Replacements - a ~normal~ 1:1 entity relation). If I expand() that relation, I can query for existing Evaluations and will see the expected Validation value.
Grabbing an existing Validation instance and assigning it seems to work as well:
manager.fetchEntityByKey('Validation', existingIdHere).then(validation => {
newEvaluation.Validation = validation; // works, while assigning a non-entity throws
});
But if I call manager.saveChanges(); the server reports that there's no (mandatory) Validation link. Looking at the POST to the $batch endpoint I see that breeze really only posts a subset of the Evaluation type, only posts the primitive fields and none of the navigation properties. This happens for both existing (fetched and updated) and new (createEntity) objects.
Now, I understand that I've yet to create a small test case - given that this is a service that I cannot directly control I'm still trying to figure out how I'm going to provide a reduced recipe for reproduction.
That said:
breeze can query all my entities, just fine. Expanding the navigation properties works flawlessly
breeze completely ignores the very same properties during saveChanges() for me
(unrelated?) breeze offers no way for me to set the FK ID only (http://breeze.github.io/doc-js/navigation-properties.html, "Setting the Foreign Key directly") although it does list the navigation properties in manager.metadataStore.getEntityType("Evaluation").navigationProperties
Edit:
The $metadata result contain this for the entities in question:
<EntityType>
<!-- snip the rest --->
<NavigationProperty Name="Evaluations" Relationship="MyNamespace.Entities.FK_Evaluation_Validation" ToRole="Evaluation" FromRole="Validation" />
</EntityType>
and later:
<AssociationSet Name="FK_Evaluation_Validation" Association="MyNamespace.Entities.FK_Evaluation_Validation">
<End Role="Validation" EntitySet="Validations" />
<End Role="Evaluation" EntitySet="Evaluations" />
</AssociationSet>

Related

SAPUI5 - how to set value to input parameter in binding dynamically

In my XSOData service I have an entity based on calculation view with input parameters. I can to set these parameters as constants in my XML view, i.e.
<List items="{dicts>/AncParams(p_dict_name='GROUPS',p_rec_id=2)/Results}" >
<StandardListItem
title="{dicts>NAME}"
/>
</List>
and it will work fine.
But how I can set parameters p_dict_name and p_rec_id dynamically? I tried to use expression bindings to get values for parameters from another model (something like this: <List items="{= ${dicts>/AncParams(p_dict_name='GROUPS',p_rec_id=${DictUIProps>/parentId})/Results} }" >) but with no luck. As I understand, expression bindings won't work. Is there any other way?
As far as I'm aware you can't do the aggregation binding dynamically through XML. At least not in the versions I have used and I have to admit I haven't re-checked in a while. The string never gets interpreted for inner bindings before it's applied to the model.
The way I do this is through the controller:
<List id="myList" />
and in your controller (onBeforeRendering or onPatternMatched or wherever your model and view are known to the controller):
this.getView().byId('myList').bindItems({
model: 'dicts',
path: `{/AncParams(p_dict_name='${p_dict_name}',p_rec_id=${p_rec_id})/Results}`,
template: new sap.m.StandardListItem({
title: '{dicts>NAME}'
})
});
you can use the getModel('dicts').createKey function to generate the path name which is a little cleaner I suppose.
This is the way to apply dynamic filters as well, In case you ever build those.

Significance of using Linq Include when loading other table entry

I noticed that when using the read/write action view template in MVC creating a controller based on a model which holds relationships with other tables (or itself, doesn't matter), it automatically implements the Index Action using Include like so:
public ActionResult Index()
{
var table1 = db.Table1.Include(l => l.Parent).Include(l => l.Table2);
return View(table1.ToList());
}
I thought that this is used so that when the index loads, the view will include all the model fields (excluding ID of course) along with the the foreign fields such as the Parent or Table2 which seemed to make most sense.
However, I deleted the include parts like so:
public ActionResult Index()
{
var table1 = db.Table1;
return View(table1.ToList());
}
And the Index still loaded the foreign fields (Parent and Table2) as if the Include clause was not needed at all.
My question is, what is the point of using Include in this specific situation (when MVC loads the template) and also, overall?
If you are using Entity Framework, Include() tells EF that those relationships should be included in the query so the proper joins are generated. That means fields from Parent and Table2 will be included in the result with a single roundtrip to the server. (This is also known as eager-loading)
However if you remove the Include() statements, EF will only initially load fields from Table. It has however lazy-loading enabled by default, so fields from Parent and Table2 are retrieved from the database when you try to access them. This however will result in one additional roundtrip to the server per additional relationship.
You can find more information about the options available for loading related entities in this entry of the EF msdn site.
So, if your Index view uses the fields from the 3 tables, the Include() approach would require a single roundtrip (with a heavier query) while the lazy-loading approach would require 3 roundtrips.
As a basic rule of thumb, you could use Include() when you are certain you will need those fields. Use lazy-loading when only in some cases you need those fields. In any case make sure you check section 8 of this EF performance guide, it nicely explains both options and its implications so you can select the best one for your needs.
Hope it helps!

ASP.NET MVC - Database entities or ViewModels?

I am currently working on an ASP.NET MVC project.
Some developers on the team want to bind the auto-generated database entities directly to the Views.
Other developers want to create tailor-made ViewModel's and bind those to the Views.
Objectively, what are the pros and cons of both approaches?
(By "database entities" I am referring to the auto generated classes that an ORM framework generates, such as LINQ to SQL, Entity Framework or LLBLGen).
Definitely use view models in your views, and use something like AutoMapper to create view models from entities easily.
Cons:
Sometimes it feels like you are duplicating code, specifically, when the view model and the entity have the exact same properties
Pros:
You often need to represent an object in a simpler format (often called flattening), but you need full fidelity on the server side. This allows you to transition between the two without mucking up your domain model with presentation cruft.
Aggregate roots often have a lots of value objects and additional entities that are irrelevant to a specific view, and omitting them in a view model makes it easier to work with.
Your entities will have lots of two way references that are sensible in terms of an API, but create pure hell when serializing them for JSON, XML, etc. View models will eliminate these circular references.
You may often use the same entity but in different ways for different views. Trying to balance both needs on one type can create a huge mess.
The orthodoxy is that you should never use your raw database entities in your views. Like any rule, it is there to be broken if you know your entities well and you understand the consequences, but there are very good reasons not to break that rule, particularly when working in teams and with code that will be maintained in future by people who might not understand the rule or the entities as well as you do. The main reasons are:
ORM lazy loading. Imagine your Customer has a lazy loaded collection Orders. You pass Customer off to the View and it iterates over Orders. You get an N*1 select on the Orders table. But it also means that your database connection still needs to be open in the View. There is a pattern that people use 'Transaction per Action' which disposes of the database context in the Action_Executed event, which happens before your View is rendered. So you could be trying to access the database after it has been disposed. Even if you are not doing that now, someone in future might decide to implement that pattern because it is fashionable.
The concerns of the ViewModel are different to the db Model. For example, you typically decorate your ViewModel properties with validation attributes. These typically are different or only concern the UI not the db. If you bind to your database entities you will find all these UI concerns polluting you DB entities.
Related to 2 - the requirements of the ViewModel may demand computed or derived properties. For example, a Fullname constructed from First and Last names. These kind of things are best kept in the ViewModel.
You can unit-test your ViewModels in isolation from the database. ViewModels can end up containing quite a lot of logic which needs to be unit-tested. This is easier to test if it is not tied to your database (as with EF entities).
In general, creating and maintaining ViewModels (even without AutoMapper) is not an overhead and you will find it is a much better pattern of development overall. I would recommend it for everything but the simplest cases (lookup lists of static data, for example).
I believe using view models is the only way to go, so no pros for ORM entities:) View models not only provide data for view, but they also define how view should look (by defining templates) or how it should validate (by adding data annotations or implementing IDataErrorInfo).
Using view models:
Pros:
View models contain only properties required by view, nothing else.
View models may contain specific validation rules using data annotations or IDataErrorInfo.
View models can combine values from different database entities.
View models document themselves and are not tied to any framework.
View models protect you from forged POSTs, containing values, that were not provided in form, but were contained in ORM entities.
You can specify easily display templates for view models and reuse them in many places using DisplayFor or EditorFor helpers.
Using ORM entities:
Cons:
ORM entities already contain data annotations, that can mess up your validation. Example: Password field in user may be markes as Required, but it is not required when you change only basic user info.
ORM entities are strongly tied to Framework (Entity Framework) and may be not easy to implement rules in.
ORM entities can contain properties for more than one view, but it is hard to separate validation rules for different views.
Using ORM entities with lazy loading can lead you to executing SQL queries when views are rendered. It shouldn't happen.
Using ORM entities can lead to using huge SQL queries instead on small ones. When you want to display dropdown with first name and last name, you should only retrieve first name and last name from database, not whole entities.
Thanks for the answers so far - they have been a big help in understanding the pros/cons of both approaches. I have one thing to add that no one else has mentioned.
Over-posting attack
A worrying disadvantage with binding directly against DB entities is an "over-posting attack". This is where the attacker, using a tool no more advanced than FireBug, can insert form fields that are not intended to be editable by the user, but which do exist on the DB entity.
Consider an "Edit my profile" page. Your view might look like this:
#using(Html.BeginForm() {
<div>
#Html.LabelFor(x=> x.FirstName)
#Html.TextBoxFor(x=> x.FirstName)
</div>
<div>
#Html.LabelFor(x=> x.LastName)
#Html.TextBoxFor(x=> x.LastName)
</div>
<input type="Submit" value="Save" />
}
It would render the following HTML:
<form action="/profile/edit" method="post">
<div>
<label for="FirstName">FirstName</label>
<input type="text" name="FirstName" value="" />
</div>
<div>
<label for="LastName">LastName</label>
<input type="text" name="LastName" value="" />
</div>
<input type="Submit" value="Save" />
</form>
Using FireBug, an attacker merely needs to insert a chunk of HTML inside the form:
<input type="hidden" name="IsAdmin" value="true" />
...and suddenly users are able change data in very unexpected and harmful ways.
Here are some even scarier hidden form fields:
<input type="hidden" name="ShoppingCart.Items[0].Price" value="0.01" />
<input type="hidden" name="BankAccount.Balance" value="1000000" />
<input type="hidden" name="User.Administrator.Password" value="hackedPassword" />
Ouch!
Info taken from:
http://hendryluk.wordpress.com/tag/asp-net-mvc/
I once tried to develop an app which used NHibernate entities directly in ASP.NET views. I ran into many problems with Lazy loading and deferred SQL execution running directly from the views rather than in the business logic layer or even controllers. Moving to a viewmodels and using automapper seemed to solve all these problems and make the app easier to test, debug and maintain.
I also found that view models were helpful in holding all the associated data I needed on a page. Some developers like to use the dynamic ViewBag for this, but this is bad for testing and debugging.
In particular, view models made it easy when you wanted to pick associated entities from dropdown lists.
AutoMapper was a lifesaver on this project, as it saved having to write a ton of mapping code, all I had to do was create the view models and then the controllers automapped from entities to view models.
Do not expose backend-entities to the client.
Real world application have behaviour -not CRUD. It you databind your entities to the view it will just be a matter of time before you dig into muddy hack when behaviour is required on the clientside.
I was just about to add exactly the same sentiment as hackedbychinese. also i'd add, with fk's to lookup lists, you just HAVE to use viewmodels as the entity model merely will hold a pointer to a single id within that table. A viewmodel allows you to pass the required populated list into the view - voila.
Also, a viewmodel can contain discreet logic where required, this would definately NOT be the case with the entity model. Also, your validations may vary depending on the use of your view, therefore different validations can be applied per 'view' requirement.
The purpose of a ViewModel is mainly separation of concerns - decoupling the View from the implementation details of the Model.
Using DB entities in your views, especially your forms is a massive security issue. Take the following POCO object
public class User
{
public int Id { get; set; }
public string Username { get; set; }
public string Email { get; set; }
public bool IsAdmin { get; set; }
}
Now say you are presenting a view that allows a user to change their email. The MVC method for processing the form result when using Db Entities instead of view models would look like: (unless you don't use model binding, in which case you are making more work for yourself)
public class HomeController : Controller
{
[HttpPost]
public ActionResult ChangeEmail(User user)
{
//....
}
}
Model binding in Asp.net works by looking for GET or POST parameters matching the names of the properties in the model. Therefore, all the user has to do is add IsAdmin=true to the POSt parameters and viola, the model passed into the ChangeEmail function will have the IsAdmin property set to true, which could very easily be accidentally added into the database, giving users free access to change data they didn't have access to change.
This goes for user permissions, changing who owns an entity (make your question be associated with me instead of you), change original creation dates, etc...

ASPNET MVC: Why This Action Method Binding Convention?

Having just spent two amazingly frustrating hours formatting some hidden fields to bind properly to action method parameters -- the second time I've had this experience in the last week -- I'm now very curious as to why the MVC architects chose the particular binding convention that they did for lists (and dictionaries) of objects.
Here's my painfully gathered understanding of the format expected by the default binding engine. In my example I want to bind to a List, where the CustomClass type exposes a public property called PropertyName:
<input type="hidden" name="prefix[idx].PropertyName" value="PropertyName[idx] Value" />
prefix is the ViewDataDictionary.TemplateInfo.HtmlPrefix, if one has been defined.
I find it deeply counter-intuitive to start the reference to something with the indexing information (i.e., the [idx] piece). I also find it disturbing that nowhere in this construct do I make reference to the name of the action method parameter to which I'm binding. That seems to be in direct contrast to what happens with, say, a primitive model property:
<input type="hidden" name="Text" value="something" />
public ActionResult SomeActionMethod( string Text )...
I understand I can roll my own model binder in MVC. That doesn't seem like a profitable use of my time, although spending hours trying to puzzle out the correct format for hidden fields isn't profitable either :), so maybe I'll try that. I also know that I can let MVC do all the heavy lifting by creating a type template using #Html.HiddenFor(), and then outputting instances of CustomClass though a simple partial view that has CustomClass as a model and the single line #Html.DisplayForModel(). But that seems like going the long way around the barn, too. Besides, there are limitations to using the #Html.Hidden helpers (e.g., they "helpfully" raid the cache after postback to fill in values, so writing #Html.Hidden("fieldname", value) doesn't guarantee value will end up being output -- you may get the older value in the cache instead, which was another hour-long annoyance today).
But I'm mostly just curious why this format was chosen. Why not something more C/C++/C#/VB like:
<input name="prefix.ParameterName.PropertyName[idx]" />
Edit:
Good point on where I put the index parameter in my example. You're right, the property isn't indexed, the containing class is.
However, that doesn't change the basic situation. Why isn't the syntax something like:
<input name="prefix.ParameterName[0].PropertyName" />
The standard syntax ignores the parameter name with collections of custom types, and "guesses" the custom type from the property names. That's bizarre...so there must be a story or choice behind it :).
Actually, it makes perfect sense. The index is into the collection, not the property. You don't have a collection of PropertyName, you have a Collection of CollectionName[] that has a PropertyName.
To put this another way:
public class Foo { public string Bar { get; set; } }
var foos = List<Foo>();
for (var i = 0; i < foos.Length; i++)
{
var prop = foos[i].Bar; // This is the important bit
}
That's exactly what happens in the model binder.
When the model binder deserializes the post values, it has to know which collection to insert the values into, and it has to know what index each item is for. So it has to know to create a Collection of Foos, of x number of items, and which indexes each Bar is associated with.

ASP.Net MVC DefaultModelBinder not binding properties on POST

I'm facing a really strange problem that has me smoked.
I have a fairly simple scenario where I have a strongly typed view that is correctly populated from the controller on the GET, but then when it POSTS the form to the controller, the Reqeust is full of all the right values and right key names for the default model binder to correctly populate one of my model objects, and the DMB creates the correct opject, but it never populates any of the properties, they're all in their default state.
This was working before, the only changes I can think of were that I tried a custom modelbinder (then removed it; double checked to make sure I'm not still using that), and I refactored the model to have a base class with some of the props.
Any thoughts?
A very similar scenario - that the DefaultModelBinder is - essentially - not binding to your model, arrise if you would give your bound model object the same name as one of its properties:
Model
Public Property ArbitraryName1 As Integer
Public Property Answer As String
Public Property ArbitraryName2 As Boolean
View
<p/> ... #Model.ArbitraryName1
<p/> Answer: #Html.TextBoxFor(Function(model) model.Answer)
<p/> ... #Html.CheckBoxFor(Function(model) model.ArbitraryName2)
Controller
<HttpPost()>
Function Index(answer As Model) As ActionResult
' answer is Nothing
End Function
(Using ASP.NET MVC 3)
Got it. The model had been refactored in a way which naturally affected the ability of the mdoel binder to populate it.
The name of your input param do not have to be equal to some property name of the object. Remember that all data coming as an array of name -> value and the default binding use the names for make the relation work.
I had this behaviour arise by moving two properties from the top of the class to further down. I still can't work out why this stopped the binding of a third property from working (so this isn't a solution so much as a 'watch out for') but I repeated the change multiple times and each time the binding went from working to not working.
I also found that after making this change I sometimes had to 'Clean' the solution for the binding to start working again.

Resources