开发者

Need help designing to ASP.NET MVC action methods

I'm just starting out learning ASP.NET MVC 3. I've been going through the Music store sample on the ASP.NET website, as well as starting to develop my own site, but I'm having some trouble understanding how I should setup my controller action methods.

On my site each user that is logged in will be able to perform standard CRUD operations on their Pr开发者_开发问答ojects. I've set this up similar to the Music Store sample with the following action methods on a ProjectController. So far this makes sense to me.

ActionMethod                                          View
ProjectController.Index()                            Lists the active users's projects
ProjectController.Details(int id)                    Shows details for project 123
ProjectController.Create()                           Shows a form to edit a new project
ProjectController.Create(FormCollection col)         Adds a new project with the form contents
ProjectController.Edit()                             Shows a form to edit a new project
ProjectController.Edit(int id, FormCollection col)   Adds a new project with the form contents
ProjectController.Deiete(int id)                     Shows a delete confirmation form
ProjectController.Delete(int id, FormCollection col) Deletes a project with the provided id.

In addition, users will be able to add Items to each project. Items can not exist on their own and must be associated to a project when being created. What I'm having trouble understanding is how to pass along the reference to the project an Item should be created in. For example in my item controller I have a pair of Create() action methods similar to the controller above.

ItemController.Create()                               Shows a form to create a new item
ItemController.Create(FormCollection col)             Creates a new item with the details from the form.

Yet I don't understand how the first Create() method passes a reference to the project which the new Item should be created in since the View() helper method can only accept one object parameter. Should I just add a reference to a project to a property of the ViewBag? I'm new to dynamic types as well and the ViewBag just seems magic to me at the point. So I'm a little hesitant to use it. I've also always thought strongly typed design is better. So should I create a separate "NewItemData" model object that contains a reference to a new Item as well as the project it is being added to?

Once the form knows which project it is adding an item to how should it pass this information back when submitted? Should there be a hidden "ProjectID" field in the form? Or should the form POST back to a URL with the project id in the query string?

www.mysite.com/Item/Create?ProjectID=1234 

Finally, I also want to be able to list the items that are added to each project. Should this be part of the ItemController or the ProjectController. For simplicities sake I'm sticking with the default Controller\Action[ID] URL routing. A few of my ideas are listed below. I'm leaning towards the last option, but would really like to hear what others with more experience with this stuff think.

Action Method                          URL
ItemController.Index(int ProjectID)    \Item?ProjectID=1234    
ItemController.List(int id)            \Item\List\1234         
ProjectController.Items(int id)       \Project\Items\1234


To answer your last question, it depends. Do Items in your model exist independently of a project? If the answer is no, then I would tend to do

ProjectController.AddItem(int id)
ProjectController.Items(int id)

where id represents the projectID.

The name of the parameters you use in the action signature directly correspond to values from the routedata and request values. {controller}/{action}/{id} is a pattern that uses the braced names as keys in the route dictionary. If you wanted you could change the routes to be {controller}/{action}/{projectid} for that action and your method signature could be the (int projectid) signature.

I don't recommend you do this just to get awesome signatures. Use comments instead if you think people will get confused.

Without changing the route pattern, if you would prefer your urls to be /project/items?projectid=3 than /project/items/3 then the action would be this:

ProjectController.Items(int projectId)

I like the prettier urls, so i'd be more apt to use the id version. That being said, if Items do not exist independently of the Project object, I would be be more likely to do this. However, if you are going to have a TON of different actions that can be performed on an Item, it would make sense to separate them into ItemController and ProjectController.

It comes down, to a large extent, about what makes sense for your application and how many actions you think a controller should have on it.


In this case you'd create a hidden field with the name=projectId and then in your Create controller have an action method.

[HttpPost]
public ActionResult Create( int projectId, FormCollection postData )

Usually you'd also use a strongly typed viewmodel so instead the FormCollection parameter use:

[HttpPost]
public ActionResult Create( int projectId, Item or ItemViewModel postData )

And as long as the name attributes match the properties in Item or ItemViewModel MVC's ModelBinder will take care of hydrating those values.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜