2009-12-19 53 views
0

这是我在ASP.NET MVC真正模型的简化,我认为这将有助于集中在问题:麻烦路过视图和控制器之间的复杂数据在ASP.NET MVC

比方说,我有这两个域对象:

public class ObjectA 
{ 
    public ObjectB ObjectB; 
} 

public class ObjectB 
{ 
} 

我也有一种观点认为,可以让我创建一个新的对象A和包括从可能ObjectBs列表中选择一个对象B。

我已经创建了一个新的类来装饰ObjectA与这个可能性列表,这是我真正的我的视图模型。现在

public class ObjectAViewModel 
{ 
    public ObjectA ObjectA { get; private set; } 
    public SelectList PossibleSelectionsForObjectB { get; private set; } 

    public ObjectAViewModel(ObjectA objectA, IEnumerable<Location> possibleObjectBs) 
    { 
     ObjectA = objectA; 
     PossibleSelectionsForObjectB = new SelectList(possibleObjectBs, ObjectA.ObjectB); 
    } 
} 

,什么是构建我的视图和控制器,以允许用户在视图中选择一个对象B,然后让控制器保存对象A与对象B的选择(对象B已经存在,并保存的最佳途径)?

我试着创建一个类型为ObjectAViewModel的强类型视图,并将Html.DropDownList绑定到Model.PossibleSelectionsForObjectB。这很好,我可以很好地选择对象。但是让它回到控制器是我挣扎的地方。

尝试性解决方案1:

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Create(ObjectAViewModel objectAViewModel) 

这里这个问题是objectAViewModel.ObjectA.ObjectB属性为null。我正在考虑绑定到这个属性的DropDownList,当用户在视图中选择这个时会更新模型,但这不是由于某种原因。

尝试性解决方案2:

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Create(ObjectA objectA) 

这里这个问题是ObjectA.ObjectB属性为null。再次,我想也许DropDownList选择会更新这个。

我也尝试在上述每个解决方案中使用UpdateModel方法,但没有运气。有没有人有任何想法?我猜我缺少一个绑定或某处的某个地方...

谢谢!

回答

0

经过一番研究后,它看起来不像是ASP.NET MVC会为我照顾的情况。也许有一个我可以使用的数据服务绑定模型(因此MVC会根据在下拉列表中选择的内容自动获取适当的对象),但现在,我可以通过在控制器中处理它来解决此问题:

  1. 使用Controller.ModelState
  2. 刷新从下拉获取所选择的项目的是对象B从基础数据服务
  3. 分配该对象B到对象A。对象B
  4. 保存对象A

所以我的控制器方法现在看起来是这样的:

编辑基于从LukLed

[AcceptVerbs(HttpVerbs.Post)] 
    public ActionResult Create(ObjectA objectA, string objectBStr) 
    { 
     ObjectB objectB = _objBService.Get(objectBStr); 
     objectA.ObjectB = objectB; 
     _objAService.Save(objectA); 
     return RedirectToAction("Details", new { id = objectA.Id }); 
    } 
+1

你可以改变公众的ActionResult创建(对象A对象A) 公众的ActionResult创建(对象A对象A,字符串对象B)。您不必从ModelState获取值。 – LukLed 2009-12-20 10:18:31

+0

谢谢!我会去做。 – manu08 2009-12-21 23:01:19

1

我使用的代码如下评论:

[HttpPost] 
    public ActionResult Create([Bind(Exclude = "Id")]ObjectA objectAToCreate) 
    { 
     try 
     { 
      Repository.AddObjectA(objectAToCreate); 
      return RedirectToAction("Details", new { id = objectAToCreate.Id }); 
     } 
     catch 
     { 
      return View(); 
     } 
    } 

Wit在库(实体框架特定)H下面的代码:

public void AddObjectA(ObjectA objectAToAdd) 
    { 
     objectAToAdd.ObjectB = GetObjectB(objectAToAdd.ObjectB.Id); 
     _entities.AddToObjectAs(objectAToAdd); 
     _entities.SaveChanges(); 
    } 

    public void GetObjectB(int id) 
    { 
     return _entities.ObjectBs.FirstOrDefault(m => m.id == id); 
    } 

根据您的commments,它基本上是重装从底层数据服务的对象,但是我没有找到需要使用的ModelState到访问尝试的值。

这是基于沿着这些线路编码一个观点:

 <p> 
      <%= Html.LabelFor(f => f.ObjectB.Id) %> 
      <%= Html.DropDownList("ObjectB.Id", new SelectList((IEnumerable)ViewData["ObjectBList"], "Id", "Descriptor"),"") %> 
      <%= Html.ValidationFor(f => f.ObjectB, "*") %> 
     </p> 

注意,这可以改善使用强类型的视图模型(我相信你已经这样做了),也创建一个自定义编辑模板对于对象B使得呼叫可以使用进行:

<%= Html.EditorFor(f => f.ObjectB) %> 
相关问题