我是从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; }
}
}
然后我创建了一些测试特许经营集和特许经营权。
以下是主要观点:
该项目要求所有与集合相关的特许经营权在相应的集合中可见。此外,我需要能够在Set的详细信息中添加特许经营权。
我创建了一个屏幕截图,以说明在我点击主视图上的“详细信息”后它的样子:
使用如下所示的ActionLink创建新特许经营按钮:
@Html.ActionLink("New Franchise", "Create", "Franchise", null, new { @class = "btn btn-large btn-primary" })
这将我带到特许经营创建页面,如下所示:
正如您所看到的,问题是应该包含相关Set Model的下拉列表未预先填充 - 而是我必须单击下拉列表并重新选择我已经在的Set。
下拉 正在填充 - 但是由所有现有的集合 - 而不是我所在的集合。
点击它时,下面是下拉列表:
在特许经营权创建视图内部,这就是该下拉列表及其标签的样子:
<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就是这样的:
我认为如果设置和特许经营权之间的关联正确,并且当我在集合中添加特许经营权时,该网址将如下所示:
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);
}
如果有更多代码可以提供帮助,请告诉我。
答案 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
重命名为(FranchiseSet
或FranchiseGroup
等),以避免命名冲突吗?英语中的Set
is one of the most ambiguous and common words。