从 ASP.NET Core 中的 ViewComponent 提交表单并执行控制器操作
Submit form and do controller action from ViewComponent in ASP.NET Core
我想在 ASP.NET 5、Mvc 核心应用程序的 ViewComponent 中从表单添加 ListItems。
组件视图(Views\Shared\Components\AddListItem\Default.cshtml):
@model ShoppingList.Models.ListItem
<form asp-action="Create">
<div class="form-horizontal">
<hr />
<div asp-validation-summary="ValidationSummary.ModelOnly" class="text-danger"></div>
<!-- some fields omitted for brevity -->
<div class="form-group">
<label asp-for="Description" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="Description" class="form-control" />
<span asp-validation-for="Description" class="text-danger" />
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
</form>
ViewComponent 控制器(ViewComponents\AddListItem.cs):
namespace ShoppingList.ViewComponents
{
public class AddListItem : ViewComponent
{
private readonly ApplicationDbContext _context;
public AddListItem(ApplicationDbContext context)
{
_context = context;
}
public IViewComponentResult Invoke(string listId)
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IViewComponentResult> Create (ListItem listItem)
{
_context.ListItem.Add(listItem);
await _context.SaveChangesAsync();
return View(listItem);
}
}
}
组件在 home.cshtml 中调用:
@{
ViewData["Title"] = "Home Page";
}
@Component.Invoke("AddListItem", @ViewBag.DefaultListId)
但是,我无法让它工作。什么都没有添加。
将 AddListItem
重命名为 AddListItemViewComponent
。这是 ASP.NET 用于查找组件的约定 - 即 ViewComponents 需要以 ViewComponent
后缀结尾。如果你不想这样做,你可以用 [ViewComponent]
属性修饰 class 并将名称 属性 设置为你需要的任何名称。
此外,Create
方法永远不会被调用,ViewComponents 也永远不会响应 HttPost
,因为它的唯一目的是显示视图,而不是执行代码以响应回发。 View 只会调用 Invoke
或其异步版本 InvokeAsync
,不会调用其他任何东西。
起初有点令人困惑,但从某种意义上说,您可以在 组件 中做更多的事情,从某种意义上说,它就像一个强大的 Partial
一样简单。 class,DI 友好,也更容易测试。
ASP.NET 团队有一个页面解释了 ViewComponents here
感谢您的帮助,@Dealdiane。
如果有人感兴趣,这里是工作代码:
Views\Shared\Components\AddListItem\Default.cshtml
<form asp-controller="ListItems" asp-action="QuickCreate">
<div class="form-horizontal">
<hr />
<div asp-validation-summary="ValidationSummary.ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="No" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="No" class="form-control" />
<span asp-validation-for="No" class="text-danger" />
</div>
</div>
...
Controllers\ListItemsController.cs
// POST: ListItems/QuickCreate
// Create item without showing view, return to home
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> QuickCreate(ListItem listItem)
{
_context.ListItem.Add(listItem);
await _context.SaveChangesAsync();
return Redirect("/");
}
我想在 ASP.NET 5、Mvc 核心应用程序的 ViewComponent 中从表单添加 ListItems。
组件视图(Views\Shared\Components\AddListItem\Default.cshtml):
@model ShoppingList.Models.ListItem
<form asp-action="Create">
<div class="form-horizontal">
<hr />
<div asp-validation-summary="ValidationSummary.ModelOnly" class="text-danger"></div>
<!-- some fields omitted for brevity -->
<div class="form-group">
<label asp-for="Description" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="Description" class="form-control" />
<span asp-validation-for="Description" class="text-danger" />
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
</form>
ViewComponent 控制器(ViewComponents\AddListItem.cs):
namespace ShoppingList.ViewComponents
{
public class AddListItem : ViewComponent
{
private readonly ApplicationDbContext _context;
public AddListItem(ApplicationDbContext context)
{
_context = context;
}
public IViewComponentResult Invoke(string listId)
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IViewComponentResult> Create (ListItem listItem)
{
_context.ListItem.Add(listItem);
await _context.SaveChangesAsync();
return View(listItem);
}
}
}
组件在 home.cshtml 中调用:
@{
ViewData["Title"] = "Home Page";
}
@Component.Invoke("AddListItem", @ViewBag.DefaultListId)
但是,我无法让它工作。什么都没有添加。
将 AddListItem
重命名为 AddListItemViewComponent
。这是 ASP.NET 用于查找组件的约定 - 即 ViewComponents 需要以 ViewComponent
后缀结尾。如果你不想这样做,你可以用 [ViewComponent]
属性修饰 class 并将名称 属性 设置为你需要的任何名称。
此外,Create
方法永远不会被调用,ViewComponents 也永远不会响应 HttPost
,因为它的唯一目的是显示视图,而不是执行代码以响应回发。 View 只会调用 Invoke
或其异步版本 InvokeAsync
,不会调用其他任何东西。
起初有点令人困惑,但从某种意义上说,您可以在 组件 中做更多的事情,从某种意义上说,它就像一个强大的 Partial
一样简单。 class,DI 友好,也更容易测试。
ASP.NET 团队有一个页面解释了 ViewComponents here
感谢您的帮助,@Dealdiane。
如果有人感兴趣,这里是工作代码:
Views\Shared\Components\AddListItem\Default.cshtml
<form asp-controller="ListItems" asp-action="QuickCreate">
<div class="form-horizontal">
<hr />
<div asp-validation-summary="ValidationSummary.ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="No" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="No" class="form-control" />
<span asp-validation-for="No" class="text-danger" />
</div>
</div>
...
Controllers\ListItemsController.cs
// POST: ListItems/QuickCreate
// Create item without showing view, return to home
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> QuickCreate(ListItem listItem)
{
_context.ListItem.Add(listItem);
await _context.SaveChangesAsync();
return Redirect("/");
}