MVC, C# Passing parent.id to child Index or Create Action?
The closest I found to my question was this but I don't understand how it would be used.
<% object parentModel = ViewContext.ParentActionViewContext.ViewData.Model; %>
I have a gateway table and a sensor table. Gateways can have multiple sensors. The tables have an association of 1 to many (gateway to sensor) and the sensor table has a gatewayid field upon which the sensor is related to a gateway.
I am using the entity framework I have a gateway repository class I have a gateway controller class I have a gateway partial buddy class to handle Data Annotations I have an index view that lists the gateways and provides the classic crud pages
On the gateway list I have added an action link to list the sensors associated with a given gateway.
All good so far (I hope).
I assume that now I should create the same setup for my sensors table; repository, controller, buddy class, etc.
Q1: What is the MVC approach to listing all sensors (child records) for a given gateway (parent record)?
On each gateway line item I have generated a link that looks like this:
localhost/sensor/list/5
This would indicate that the list should only display the sensors for the current gateway.
I don't think this is the right way to go. I think I should be passing a gateway m开发者_Go百科odel in the background so that anytime I issue a link like this:
localhost/sensor/
it would simply understand the context of the current gateway.
Q2: The subsequent problem is how to do the same for the sensor create action. I can set up the create controller and throw up a view form but how do I indicate which gateway the sensor is supposed to be associated with?
At the top of the SensorController class:
SensorRepository repository = new SensorRepository();
GatewayRepository Grepository = new GatewayRepository();
My sensor List ActionResult method looks like this:
public ActionResult List(int id)
{
Gateway gateway = Grepository.GetGateway(id);
var sensors = repository.FindGatewaySensors(id);
return View(sensors);
}
My sensor Create ActionResult method looks like this (note that I'm setting the gatewayid value before passing it to the view; it is not editable in the view form):
// GET: /Sensor/Create
public ActionResult Create(int id)
{
Sensor sensor = new Sensor();
sensor.gatewayid = id;
return View(sensor);
}
Here is the Create ActionResult post method:
[HttpPost]
public ActionResult Create(FormCollection collection)
{
Sensor sensor = new Sensor();
if (TryUpdateModel(sensor))
{
repository.Add(sensor);
repository.Save();
return RedirectToAction("List", new { id = sensor.gatewayid });
}
return View(sensor);
}
But this just doesn't seem right. I'll bet there's a simple approach that I'm missing. Please enlighten me.
I don't know if this is relevant anymore (old question), but here are some opinions on this (and nothing more than opinions).
For Q1, I prefer to use what I imagine being "logical" URLs with MVC - i.e. from a user perspective, the URL should let them know what resource they are likely to fetch. Since you can do some semi-fancy routing, perhaps a route such as this would be clever:
/gateways/5/sensorlist
Or some variation on that theme. Of course there are a number of ways you could set the "current" gateway, as a session variable or a session cookie for instance, but what then of someone copying the URL, mailing it to his friend saying "Check out the sensors on THIS bad boy gateway!" - it wouldn't work without a reference to the gateway (doesn't have to be the ID, some people think exposing database IDs is a bad thing).
As for Q2, my common solution to this is basically to include a hidden field in the form of the create view, indicating the ID of the gateway you want to create a sensor for. It's clean and it works, and that is usually enough for me.
If you're still waiting for an answer half a year later, I hope some of this helps! :)
精彩评论