2016-02-14 5 views
7

Chcę dodać ListItems z formularza w ViewComponent w aplikacji podstawowej ASP.NET 5, Mvc.Prześlij formularz i wykonaj czynności kontrolera od ViewComponent w ASP.NET Core

widoku komponentu (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> 

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

    } 
} 

Komponent jest wywoływany w home.cshtml:

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

@Component.Invoke("AddListItem", @ViewBag.DefaultListId) 

Jednak nie mogę tego uruchomić. Nic nie jest dodawane.

+0

Ho w nazywasz ten ViewComponent? – Dealdiane

+0

@ { ViewData ["Title"] = "Strona główna"; } @ Component.Invoke ("AddListItem", @ ViewBag.DefaultListId) –

Odpowiedz

3

Zmień nazwę AddListItem na AddListItemViewComponent. Jest to konwencja używana przez ASP.NET do znajdowania komponentu - to jest ViewComponents musi kończyć się przyrostkiem ViewComponent. Jeśli nie chcesz tego robić w ten sposób, możesz udekorować klasę za pomocą atrybutu [ViewComponent] i ustawić właściwość name na dowolną nazwę.

Metoda Create nigdy nie zostanie wywołana, a ViewComponents nigdy nie zareaguje na HttPost, ponieważ jest tylko celem wyświetlania widoku, a nie wykonywania kodu w odpowiedzi na odświeżenie. Widok wywoła tylko Invoke lub jego asynchroniczną wersję InvokeAsync i nic więcej.

To trochę mylące, ale w pierwszym łatwym sposobem, aby myśleć o to jak potężny Partial w tym sensie, że można zrobić więcej rzeczy w komponent klasie DI dziećmi, i jest łatwiejsze do sprawdzenia, jak również.

drużyny ASP.NET ma stronę, która wyjaśnia ViewComponents here

+0

Myślę, że link się zmienił lub ta sekcja nie jest już dostępna ... https://docs.microsoft.com/en-us/aspnet/ core/mvc/views/view-components – JMG

+0

Masz na myśli, że nie mogę wywołać metody HttpPost w viewcomponent? –

+0

@ Programator, zgadza się. ViewComponents zostały zaprojektowane do renderowania treści, a nie do przetwarzania żądań. – Dealdiane

2

Dzięki za pomoc, @Dealdiane.

na wypadek gdyby ktoś intested, tutaj jest kod roboczych:

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> 
... 

Kontrolery \ 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("/"); 
    } 

kompletny kod źródłowy projektu w pracy można znaleźć tutaj: GitHub ShoppingList

Powiązane problemy