从ASP.NET Core中的ViewComponent提交表单并执行控制器操作

Ole*_*vik 8 c# asp.net-core asp.net-core-viewcomponent

我想从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>
Run Code Online (Sandbox Code Playgroud)

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);
        }

    }
}
Run Code Online (Sandbox Code Playgroud)

在home.cshtml中调用Component:

@{
        ViewData["Title"] = "Home Page";
}

@Component.Invoke("AddListItem", @ViewBag.DefaultListId)
Run Code Online (Sandbox Code Playgroud)

但是,我不能让这个工作.什么都没有添加.

Ole*_*vik 9

感谢您的帮助,@Dealdiane。

如果有人感兴趣,这里是工作代码:

视图\共享\组件\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>
 ...
Run Code Online (Sandbox Code Playgroud)

控制器\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("/"); 
    }
Run Code Online (Sandbox Code Playgroud)


Dea*_*ane 6

重命名AddListItemAddListItemViewComponent。这是ASP.NET用于查找组件的约定-ViewComponents需要以ViewComponent后缀结尾。如果您不想这样做,则可以使用[ViewComponent]属性装饰类,并将name属性设置为所需的任何名称。

另外,该Create方法将永远不会被调用,并且ViewComponents永远不会响应,HttPost因为它的唯一目的是显示视图而不执行代码以响应回发。View将仅调用Invoke其异步版本,InvokeAsync而不会调用其他任何版本。

首先,这有点令人困惑,但是Partial从某种意义上来说,一种简单的思考方式就像是一种强大的功能,因为您可以在组件类中做更多的事情,DI友好,并且也更易于测试。

ASP.NET团队的页面在此处解释了ViewComponents

  • 你的意思是我不能在viewcomponent中调用HttpPost方法? (2认同)
  • 但是,如果 ViewComponent 具有特定于 ViewComponent 的功能,那么您如何处理它......就像具有搜索功能的控件一样......您将搜索操作放在哪里...... (2认同)