ASP.NET MVC 4 - 嵌套模型 - 如何设置正确的关联?

时间:2012-06-21 17:54:05

标签: asp.net-mvc asp.net-mvc-3

我是从Rails的背景来到asp.net MVC 4的,我在弄清楚如何处理嵌套模型时遇到了一些麻烦。

我正在使用Entity Framework 4.3和CodeFirst方法。

该应用程序非常简单,并且具有 Set 模型 - 其中包含许多特许经营。它有一个特许经营模式 - 属于集合。

POCO类是与适当的导航属性一起创建的,然后我用视图搭建了控制器,然后生成了数据库。

以下是课程:

设置

 namespace FranchiseManagerTest.Models
    {
        public class Set
        {        
            [Key]
            public int SetID { get; set; }
            public string SetName { get; set; }
            public string MainAddress { get; set; }
            public string TimeZone { get; set; }       
            public virtual ICollection<Franchise> Franchises { get; set; }
        }
    }

特许

namespace FranchiseManagerTest.Models
{
    public class Franchise
    {
        [Key]
        public int FranchiseID { get; set; }        
        public int SetID { get; set; }
        public string FranchiseName { get; set; }
        public string FranchiseNumber { get; set; }     

        public virtual Set Set { get; set; }

    }
}

然后我创建了一些测试特许经营集和特许经营权。

以下是主要观点:

enter image description here

该项目要求所有与集合相关的特许经营权在相应的集合中可见。此外,我需要能够在Set的详细信息中添加特许经营权。

我创建了一个屏幕截图,以说明在我点击主视图上的“详细信息”后它的样子:

enter image description here

使用如下所示的ActionLink创建新特许经营按钮:

@Html.ActionLink("New Franchise", "Create", "Franchise", null,  new { @class = "btn btn-large btn-primary" })

这将我带到特许经营创建页面,如下所示:

enter image description here

正如您所看到的,问题是应该包含相关Set Model的下拉列表未预先填充 - 而是我必须单击下拉列表并重新选择我已经在的Set。

下拉 正在填充 - 但是由所有现有的集合 - 而不是我所在的集合。

点击它时,下面是下拉列表:

enter image description here

特许经营权创建视图内部,这就是该下拉列表及其标签的样子:

       <div class="editor-label">
            @Html.LabelFor(model => model.SetID, "Set")
        </div>
        <div class="editor-field">
            @Html.DropDownList("SetID", String.Empty)
            @Html.ValidationMessageFor(model => model.SetID)
        </div>

以下是我的尝试:


我尝试使用ActionLink将 SetID 值传递给View:

@Html.ActionLink("New Franchise", "Create", "Franchise", Model.SetID,  new { @class = "btn btn-large btn-primary" })

然后我尝试将Create View的String.Empty属性更改为:

 <div class="editor-label">
        @Html.LabelFor(model => model.SetID, "Set")
    </div>
    <div class="editor-field">
        @Html.DropDownList("SetID", Model.SetID)
        @Html.ValidationMessageFor(model => model.SetID)
    </div>

但是,这不起作用并生成无效参数错误。

以下是可能的线索(或其他问题?)

当我从我所关联的Set访问Create Franchise View时,URL就是这样的:

enter image description here

我认为如果设置特许经营权之间的关联正确,并且当我在集合中添加特许经营权时,该网址将如下所示:

localhost:52987/Set/1/Franchise/Create

这是一个错误的假设吗 - 这可以在.NET MVC中做吗?

非常感谢此处的任何建议!


EDITS


以下是我的Global.asax文件中的路由,如果这有用的话:

public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );

            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Set", action = "Index", id = UrlParameter.Optional }
            );
        }

As Requested - 这里是特许经营控制器的GET和POST Create方法:

 //
    // GET: /Franchise/Create

    public ActionResult Create()
    {
        ViewBag.SetID = new SelectList(db.Sets, "SetID", "SetName");
        return View();
    }

    //
    // POST: /Franchise/Create

    [HttpPost]
    public ActionResult Create(Franchise franchise)
    {
        if (ModelState.IsValid)
        {
            db.Franchises.Add(franchise);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        ViewBag.SetID = new SelectList(db.Sets, "SetID", "SetName", franchise.SetID);
        return View(franchise);
    }

如果有更多代码可以提供帮助,请告诉我。

2 个答案:

答案 0 :(得分:3)

我对你要做的事情感到有点困惑,但我建议你做一些改变:

我会改变这个:

<div class="editor-label">
    @Html.LabelFor(model => model.SetID, "Set")
</div>
<div class="editor-field">
    @Html.DropDownList("SetID", Model.SetID)
    @Html.ValidationMessageFor(model => model.SetID)
</div>

到此:

<div class="editor-label">
    @Html.LabelFor(model => model.SetID, "Set")
</div>
<div class="editor-field">
    @Html.DropDownListFor(model => model.SetID, (SelectList)ViewBag.FranchiseSets)
    @Html.ValidationMessageFor(model => model.SetID)
</div>

如果您将 SetID 值传递给创建 ActionMethod并指定它,则应将其传递给视图。看起来您没有填充DropDownList,因此选择列表中没有选项可供选择。

public ActionResult Create(int SetID)
{
    ViewBag.FranchiseSets = new SelectList(...);
    var franchise = new Franchise { SetID = SetID };
    return View(franchise);
}

答案 1 :(得分:1)

目前尚不清楚您的行为和路线是如何设置的,但您可能想尝试一下:

@Html.ActionLink("New Franchise", "Create", "Franchise", new{Model.SetID},  new { @class = "btn btn-large btn-primary" })

通过创建一个具有SetID属性的对象,MVC将知道该参数应该被命名为“SetID”。

PS - 我可以建议将Set重命名为(FranchiseSetFranchiseGroup等),以避免命名冲突吗?英语中的Set is one of the most ambiguous and common words

相关问题