I have an AccountModel and a page where the user can upload a file. What I would like to have happen is when the user uploads the file. The PageController does something like the following. this is a quick attempt just written in the question to illustrate my question.

public class PageController : Controller {
private Service service;
public ActionResult Upload(HttpPostedFileBase f){
service.savefile(f,_AccountModel_whatever.currentlyloggedinuser.taxid) }
}
public class Service
{
// abunch of validation and error checking to make sure the file is good to store
}

Wouldn't this approach be in bad practice? Since I'm making my controller dependent on the existence of th AccountModel? This will become a HUGE program over the next few years, and I really want to maximize the quality of the framework now.

4 Answers
4

Couple of angles here. First, you could probably pass the account model into your service as a constructor dependency if it is in fact used everywhere there. Using any IoC framework you can pretty easily fob off these dependencies on the framework presuming it knows how to hydrate them.

Second, I would typically avoid rolling my own account model -- or at least writing code to it. In most cases, IPrincipal and IIdentity do the job for you and make your account model very flexible.

It's bad practice if there is a case where someone could move to file upload without being logged in. In that case, there'd be an exception. But wouldn't you want there to be one? I'm assuming you're tracking the files based on the account, so you'd have problems otherwise.

As long as you make sure to kick people with expired sessions back to the log in screen, I don't see any problem beyond those inherent in non-stateful web apps.

In your opinion are you suggesting this could/should be done somehow as a web stateful app? or was that just an aside?
–
MVCylonMay 24 '11 at 17:19

@doug: No no, that would be a nightmare. Just, with web pages, you always have to acknowledge that someone could try to break in to a process in the middle, by tweaking the link, or by accidentally bookmarking a dynamically generated page or something.
–
SatanicpuppyMay 24 '11 at 17:32

So, you are saying it is perfectly acceptable for one controller to reference other models? in Microsoft examples, they always seem to have 1 to 1 to 1 for model controller view, which is so over simplified it makes me want to vomit in terror.
–
MVCylonMay 24 '11 at 17:44

@doug: Yea, I hate their documentation. Their examples are never what I need. As far as I know it should work. You'll have to give it a shot.
–
SatanicpuppyMay 24 '11 at 17:54

You could abstract out the Account model by having an interface that it shares with the controller, if you are worried about changes in AccountModel. But IMO, models "usually" don't change over time (They may incrementally get bigger) because of the usual dependence on the storage below - migrating data in a production system is a pain. So you might be worrying pre-maturely in this case.

You don't want a system with an interface for every interaction with the model, Try and identify the fluid pieces and abstract them alone. A good long term product vision should help you arrive at the right building blocks in the first place.

Is your AccountModel a principal of some kind? If so, I'd really make sure to make it implement IPrincipal and follow the normal patterns. You can then pull the principal in and cast it to get the data you need.

If its not, you can have an AccountModelId in a hidden form field. Make your action method take an AccountModel. A custom model binder can look for this id and retreive your model for you, if it must be read out of a database or something.

Either way, you're in a good spot to be able to unit test your controller as the AccountModel mock is easily given to the controller.