If I understand your question correctly, I would say it is because you generally don't have explicit control over the parameters passed to an action.
Remember that the model binding will, by default, take them from a number of different places, including ones that are outside your control, like querystring.
It sounds like you're thinking that you should be able to have something like this:
/article/list/sport
Which calls ArticleController.List(string category);
And also:
/article/list/sport/20110901
Which calls ArticleController.List(string category, DateTime date);
But what happens when someone types the URL /article/list/sport?date=20110902
?
It just sounds like a recipe for unpredictable behaviour, and in return, what real benefit would you get from this sort of action overloading?
I see two distinct subjects in your question:
- How to manage circular references when serializing to JSON?
- How safe is it to use EF entities as model entities in you views?
Concerning circular references I'm sorry to say that there is no simple solution. First because JSON cannot be used to represent circular references, the following code:
var aParent = {Children : []}, aChild = {Parent : aParent};
aParent.Children.push(aChild);
JSON.stringify(aParent);
Results in: TypeError: Converting circular structure to JSON
The only choice you have is to keep only the composite --> component part of the composition and discard the "back navigation" component --> composite, thus in you example:
class parent
{
public List<child> Children{get;set;}
public int Id{get;set;}
}
class child
{
public int ParentId{get;set;}
[ForeignKey("ParentId"), ScriptIgnore]
public parent MyParent{get;set;}
public string name{get;set;}
}
Nothing prevents you from recomposing this navigation property on your client side, here using jQuery:
$.each(parent.Children, function(i, child) {
child.Parent = parent;
})
But then you will need to discard it again before sending it back to the server, for JSON.stringify won't be able to serialize the circular reference:
$.each(parent.Children, function(i, child) {
delete child.Parent;
})
Now there is the issue of using EF entities as your view model entities.
First EF is likely to using Dynamic Proxies of your class to implement behaviors such as change detection or lazy loading, you have to disable those if you want to serialize the EF entities.
Moreover using EF entities in the UI can be at risk since all the default binder will mapping every field from the request to entities fields including those you did not want the user to set.
Thus, if you want you MVC app to be properly designed I would recommended to use a dedicated view model to prevent the "guts" of your internal business model from being exposed to the client, thus I would recommend you a specific view model.
Best Answer
Do you have to create the view from the
POST
? A nicer pattern might be to use Post/Redirect/Get; this way the data isPOSTed
to the action which simply returns a302
redirect to theGET
action with the appropriate parameters in the query string. The responsibility for rendering then remains with theGET
whilst altering state on the server is kept within the 'POST'.The additional benefit of doing this is that you solve the problem of user's making duplicate requests when refreshing the page.
In terms of Best Practice when working with the web, it might be worthwhile learning more about REST and trying to apply
RESTful
principles to your MVC application.