Is it possible to pass classes between controllers in ASP.NET MVC?
Is it possible to do something like this in an ASP.NET MVC controller?
public ActionResult Index(CustomADT adt)
{
...
}
And you will pass in a class from another controller when you click on a link. Or is it only possible to pass around strings?
Edit:
A bit more elaboration. Let's say I have the following class hierarchy:
public class Area
{
public string Name { get; set; }
public ICollection<Building> Buildings { get; set; }
}
public class Building
{
public string Name { get; set; }
}
So Area
contains a list of Buildings
. Now, I have two controllers, AreasController
and BuildingsController
. Both have an Index()
method. What I'd like to do is when this URL is navigated to:
http://localhost/Areas/
It'll list all the areas. Then, when you go to this URL:
http://localhost/Areas/1/Buildings/
It'll list all the buildings for area with ID 1. In BuildingsController
, I receive the ID as an int and then use it to find the correct Area, like so:
public ActionResult Index(int areaId)
{
var area = areaRepository.GetById(areaId);
return View(area.Buildings);
}
Now, this seems pretty clunky to me. The areaId has to be received as an int, then I have to hit up the repository again to get the actual Area
object. Is there any way that I can do this instead:
public ActionResult Index(Area area)
{
return View(area.Buildings);
}
And not hit up the repository again and re-retrieve an object that's already been instantiated开发者_开发知识库? I'm leaning towards no because of how HTTP works (you can't place an object in the URL), but maybe someone has a neat trick up their sleeve.
Yes, it is possible. More so, it is built right into MVC itself with what is called "ModelBinders". Model binders use reflection to match up the querystring/form key/value pairs with your CustomADT class object. What you have will work perfectly, as long as your form submits the same property names.
Your form...
<% using (Html.BeginForm()) { %>
<%= Html.TextBox("Title", Model.Title) %>
<%= Html.TextBox("Description", Model.Description) %>
<% } %>
Your class...
public class CustomADT
{
public String Title {get; set;}
public String Description {get; set;}
}
Notice how your class' properties match the form key/values? ASP.NET MVC has it built-in that it will map those together, with your sample Index(CustomADT adt) above.
If you have special requirements for binding, you can create your own custom IModelBinder class and register it within your global.asax for custom mappings between your form key/value pairs and your model (class). (bing it)
Also, I highly recommend reading up on the "ViewModel" pattern with ASP.NET MVC (bing it).
I also blogged about how to use strongly-typed action methods, which allows you to pass around classes from your view to a controller (and in the controller to, with the extensions within the Microsoft.Web.Mvc assembly I mention).
http://eduncan911.com/archive/tags/Asp.Net+Mvc/default.aspx
Finally, there is no direct conversion from a model to a querystring to call another action method on a controller. But, you can use the default Model binding to reflect your model and create them for you:
return RedirectToAction("Index", "Home", myCustomADT);
I think should work as the last parameter is a collection that will be appended as querystring. If that does not (I have doubts), you will need to pass each property as part of an anonymous collection (, new { Title = myCustomADT.Title, Description = myCustomADT.Description);).
A better question is, why would you want to? You really want to redirect and pass view models around instead.
I found a possible answer here:
http://msdn.microsoft.com/en-us/library/dd394711%28VS.100%29.aspx
Under the section entitled, Passing State Between Action Methods. Basically, you store the object in the TempData
dictionary and then reference it as a string. This is an ugly solution though because it's not strongly-typed.
精彩评论