在 2 个控制器 ASP.NET Core 3.1 MVC 之间传递 ID
Posted
技术标签:
【中文标题】在 2 个控制器 ASP.NET Core 3.1 MVC 之间传递 ID【英文标题】:Pass ID between 2 controllers ASP.NET Core 3.1 MVC 【发布时间】:2021-10-04 21:37:24 【问题描述】:我是编程新手,需要您的帮助。我正在尝试创建一个简单的测试应用程序(ASP.NET Core 3.1 MVC + EF)。我创建了 2 个模型(事件、注册)。目标是通过单击Events/Index
页面中的“注册”按钮打开带有选定EventId
的注册创建表单页面。我应该如何将EventId
传递给EnrollmentsController
?我尝试使用带有隐藏输入的表单在Events/Index
页面中传递EventId
,但我仍然不知道如何在EnrollmentsController
中正确处理EventId
。
注意:我不想在Enrollment
的Create
方法和视图中使用SelectList
。
如果有任何帮助,我将不胜感激。谢谢!
更新:感谢@PanagiotisKanavos,我终于在 URL 中获得了 EventId,但它仍然没有输入到表单输入中。有“0”。有什么问题?
型号
public class Event
public int EventId get; set;
public string Name get; set;
[DataType(DataType.Date)]
public DateTime Date get; set;
public class Enrollment
public int EnrollmentId get; set;
public int EventId get; set;
public Event Event get; set;
[Display(Name ="First name")]
public string FirstName get; set;
[Display(Name = "Last name")]
public string LastName get; set;
[Display(Name ="Enrollment date")]
[DataType(DataType.DateTime)]
public DateTime EnrollmentDate get; set;
Events/Index
查看
@model IEnumerable<FormTest.Models.Event>
@
ViewData["Title"] = "Index";
<h1>Index</h1>
<p>
<a asp-action="Create">Create New</a>
</p>
<table class="table">
<thead>
<tr>
<th>
@html.DisplayNameFor(model => model.Name)
</th>
<th>
@Html.DisplayNameFor(model => model.Date)
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
<tr>
<td>
@Html.DisplayFor(modelItem => item.Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.Date)
</td>
<td>
<a asp-action="Create" asp-controller="Enrollments" asp-route-id="@item.EventId" class="btn btn-primary">Enroll</a>
</td>
</tr>
</tbody>
</table>
Enrollments/Create
查看
@model FormTest.Models.Enrollment
@
ViewData["Title"] = "Create";
<h1>Create</h1>
<h4>Enrollment</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Create">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="EventId" class="control-label"></label>
<input class="form-control" asp-for="EventId" name="EventId" />
</div>
<div class="form-group">
<label asp-for="FirstName" class="control-label"></label>
<input asp-for="FirstName" class="form-control" />
<span asp-validation-for="FirstName" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="LastName" class="control-label"></label>
<input asp-for="LastName" class="form-control" />
<span asp-validation-for="LastName" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="EnrollmentDate" class="control-label"></label>
<input asp-for="EnrollmentDate" class="form-control" />
<span asp-validation-for="EnrollmentDate" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
EnrollmentsController
创建方法
// GET: Enrollments/Create
public IActionResult Create(int eventId)
var newEnrollment = new Enrollment
EventId = eventId,
FirstName = "John",
LastName = "Doe",
EnrollmentDate = DateTime.UtcNow
;
return View(newEnrollment);
这是屏幕:
【问题讨论】:
控制器代码在哪里?您是否有特定问题,或者您是否在询问控制器的一般工作方式?你试过ASP.NET Core MVC tutorial吗?Controllers and Views
部分准确显示您的要求。 <a asp-action="Edit" asp-route-id="@item.ID">Edit</a>
生成一个以 ID 作为参数调用 Edit
的链接。您可以使用样式使链接看起来像一个按钮。你可以在asp-action
中传递不同的动作名称
您的意思是要将隐藏输入的值传递给操作?
如果你真的需要POST
,你可以在链接按钮的onclick
处理程序中使用fetch
。如果你真的想要一个表格,你可以使用Form tag helpers。例如,asp-route-id="1234"
会将1234
传递给id
参数
您的隐藏输入缺少name
属性:<input type="hidden" value="@Html.DisplayFor(modelItem => item.EventId)" />
。浏览器会忽略没有名字的输入
嗨,@CyberAnt,尝试检查我更新的答案,您在asp-route-value
中的值名称与操作Create
的参数名称不一致。
【参考方案1】:
最简单的选择是不使用表单,而是使用 Enrollments 控制器的链接。毕竟,目标是打开Enrollments
页面,而不是提交注册:
<td>
<a asp-controller="Enrollments"
asp-action="Create"
asp-route-id="@item.EventID">Enroll</a>
</td>
可以使链接看起来像一个具有正确引导样式的按钮:
<a asp-controller="Enrollments"
asp-action="Create"
asp-route-id="@item.EventID"
class="btn btn-primary" role="button" >
Enroll
</a>
Controller 动作需要接受id
作为参数:
public IActionResult Create(int eventId)
var newEnrollment=new Enrollment
EventId=eventId,
...
;
return View(newEnrollment);
可以使用相同的路由标签助手in a form:
<td>
<form asp-controller="Enrollments"
asp-action="Create"
asp-route-id="@item.EventID" method="post">
<button type="submit" value="Enroll"></button>
</form>
</td>
不过,使用这样的表格有点奇怪。这需要添加一个响应POST
的Index(id)
操作以及响应GET
的Index(id)
。
ASP.NET Core MVC Tutorial 展示了如何创建一个列出 Todo 项目的应用程序,允许编辑、删除和从列表重定向到编辑页面。
Tag Helpers in Forms 页面解释了如何使用标签助手(如 asp-controller
、asp-action
和 asp-route-*
)在表单中指定控制器、操作和参数。
【讨论】:
问题中提到控制器动作被称为Create
。因此,可能需要asp-action="Create"
路由到它。
@AmalK 谢谢,我没注意到。我添加了动作
@PanagiotisKanavos 非常感谢,这很有帮助。我从来没有想过我可以像这样将 ID 传递给另一个控制器。现在我将 EventId 获取到 URL -/enrollments/create/1,这是正确的,但我仍然无法将值输入到注册/创建视图中的表单输入中。有什么建议吗?
@CyberAnt Create
视图是什么样的?新的注册对象将是表单的Model
。您可以使用<input asp-for="FirstName" class="form-control" />
显示和编辑FirstName
属性的内容。<input type="hidden" asp-for="Id" />
为ID。检查 ASP.NET 教程。你可以找到代码here
@PanagiotisKanavos,我更新了这个问题。请检查一下。我真的不明白怎么了...谢谢【参考方案2】:
如果你想使用asp-route-value,你需要确保值名称与动作中的参数名称一致。例如,你使用
public IActionResult Create(int eventId)
这样你就需要使用
asp-route-eventId="@item.EventId"
【讨论】:
以上是关于在 2 个控制器 ASP.NET Core 3.1 MVC 之间传递 ID的主要内容,如果未能解决你的问题,请参考以下文章
Wcf 服务在 .NET Core 3.1 控制台应用程序中工作,但在 ASP.NET Core 3.1 Web API 中无法工作
Asp.net Core 3.1-如何从控制器返回到 Razor 页面?
ASP.Net Core 3.1 - 从控制器向部分视图模态传递值?