Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/29.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
ASP.NET MVC中在视图和控制器之间传递复杂数据时出现问题_Asp.net_Asp.net Mvc_Binding_Model - Fatal编程技术网

ASP.NET MVC中在视图和控制器之间传递复杂数据时出现问题

ASP.NET MVC中在视图和控制器之间传递复杂数据时出现问题,asp.net,asp.net-mvc,binding,model,Asp.net,Asp.net Mvc,Binding,Model,下面是我在ASP.NET MVC中实际模型的简化,我认为这将有助于集中精力解决问题: 假设我有两个域对象: public class ObjectA { public ObjectB ObjectB; } public class ObjectB { } 我还有一个视图,允许我创建一个新的ObjectA,其中包括从可能的ObjectB列表中选择一个ObjectB 我创建了一个新类,用这个可能性列表装饰ObjectA,我想这确实是我的视图模型 public class ObjectAV

下面是我在ASP.NET MVC中实际模型的简化,我认为这将有助于集中精力解决问题:

假设我有两个域对象:

public class ObjectA
{
    public ObjectB ObjectB;
}

public class ObjectB
{
}
我还有一个视图,允许我创建一个新的ObjectA,其中包括从可能的ObjectB列表中选择一个ObjectB

我创建了一个新类,用这个可能性列表装饰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);
    }
}
这里的问题是objectAViewModel.ObjectA.ObjectB属性为空。我在想,当用户在视图中选择此属性时,绑定到此属性的DropDownList会更新模型,但这不是出于某种原因

尝试的解决方案2:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(ObjectAViewModel objectAViewModel)
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(ObjectA objectA)
这里的问题是ObjectA.ObjectB属性为null。再一次,我想DropDownList选择可能会更新这个

我还尝试在上面的每个解决方案中使用UpdateModel方法,但没有成功。有人有什么想法吗?我猜我找不到装订之类的东西了


谢谢

经过进一步的研究,ASP.NET MVC似乎不会为我解决这个问题。也许我可以使用一个数据服务绑定模型(因此MVC会根据下拉列表中选择的内容自动从内存中抓取适当的对象),但现在,我可以通过在控制器中处理它来解决这个问题:

  • 使用Controller.ModelState从下拉列表中获取所选项目
  • 从基础数据服务重新加载该ObjectB
  • 将该ObjectB分配给ObjectA.ObjectB
  • 保存对象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 });
        }
    
    我使用的代码如下:

        [HttpPost]
        public ActionResult Create([Bind(Exclude = "Id")]ObjectA objectAToCreate)
        {
            try
            {
                Repository.AddObjectA(objectAToCreate);
                return RedirectToAction("Details", new { id = objectAToCreate.Id });
            }
            catch
            {
                return View();
            }
        }
    
    在存储库中使用以下代码(特定于实体框架):

    根据您的说明,它实际上是从底层数据服务重新加载对象,但是我发现不需要使用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>
    
    
    f、 ObjectB.Id)%>
    f、 ObjectB,“*””>
    

    请注意,这可以改进为使用强类型ViewModel(我相信您已经这样做了),还可以为ObjectB创建自定义编辑器模板,以便可以使用以下方法进行调用:

    <%= Html.EditorFor( f => f.ObjectB ) %>
    
    f.ObjectB)%%>
    
    您可以将public ActionResult创建(ObjectA ObjectA)更改为public ActionResult创建(ObjectA ObjectA,string ObjectB)。您不必从ModelState获取值。
    <%= Html.EditorFor( f => f.ObjectB ) %>