Я новичок в ASP.NET Core MVC. Я предваряю этот вопрос, говоря, что я читал другие похожие вопросы, но это была не совсем та проблема, с которой я столкнулся.
Я пытаюсь реализовать динамическую левостороннюю навигацию, где каждая из кнопок загружается из моей базы данных.
Когда я вызываю @Html.Action("NavMenu", "Nav")
в своем "_Layout.cshtml", я получаю сообщение об ошибке
Error CS1929
'IHtmlHelper' does not contain a definition for 'Action' and the best extension method overload 'UrlHelperExtensions.Action(IUrlHelper, string, object)' requires a receiver of type 'IUrlHelper'
Один из других похожих вопросов привел меня к добавлению @using System.Web.Mvc.Html
в начало моего "_ViewImports", что привело к ошибке:
CS7069: Reference to type 'RouteValueDictionary' Claims it is defined in 'System.Web', but it could not be found
Также в ответе сказано, что @html.Action()
должен быть встроен в Core 2.0.
использование @await Html.PartialAsync("_SideNav")
работает только в моем представлении Index, поскольку в этом представлении есть @model IEnumerable<HSCWebApp.Models.HSCTable>
, но другим моим представлениям требуется @model HSCWebApp.Models.HSCTable
, что приводит к сбою "_SideNav"
Я на 100% открыт для других способов реализовать это.
В NuGet я установил:
Обновлено:
Я также получаю эти предупреждения во время сборки:
Warning NU1701 Package 'Microsoft.AspNet.Mvc 5.2.2' was restored using '.NETFramework,Version=v4.6.1' instead of the project target framework '.NETCoreApp,Version=v2.1'. This package may not be fully compatible with your project.
наряду с Entity Framework, AspNet.Razor AspNet.Webpages
Могут ли эти предупреждения как-то повлиять на мои ссылки?
Вот файлы:
Контроллер: ("NavController.cs")
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using HSCWebApp.Models;
using Microsoft.EntityFrameworkCore;
namespace HSCWebApp.Controllers
{
public class NavController : Controller
{
private readonly HSCWebAppContext _context;
public NavController(HSCWebAppContext context)
{
_context = context;
}
public ActionResult NavMenu()
{
NavViewModel nav = new NavViewModel();
List<NavViewModel> navList = new List<NavViewModel>();
var items = from n in _context.HSCTable select n;
List<HSCTable> tableList = items.ToList<HSCTable>();
for (int i = 0; i < tableList.Count(); i++)
{
nav.Id = tableList[i].ID;
nav.DepartmentName = tableList[i].DepartmentName;
nav.sel = tableList[i].sel;
navList.Add(nav);
}
//var movies = from m in _context.Movie select m;
//IEnumerable<NavViewModel> en = navList;
//IEnumerable<HSCTable> en = tableList;
return PartialView("_SideNav", tableList);
}
}
}
Модель: ("NavViewModel.cs")
using System.ComponentModel.DataAnnotations.Schema;
namespace HSCWebApp.Models
{
[Table("HSCTable")]
public class NavViewModel
{
public NavViewModel(){
int Id = this.Id;
string DepartmentName = this.DepartmentName;
string sel = this.sel;
}
public int Id { get; set; }
public string DepartmentName { get; set; }
public string sel { get; set; }
}
}
Просмотр: ("_SideNav.cshtml")
@model IEnumerable<HSCWebApp.Models.HSCTable>
@using System;
@using System.Collections;
@using System.Linq;
@{
List<List<string>> navButtons = new List<List<string>>();
int listIndex = 0;
int INITIAL = 0;
navButtons.Add(new List<string>());
navButtons[listIndex].Add("");
}
<body>
<div class = "sidenav">
@{
foreach (var item in Model)
{
if (navButtons[listIndex][INITIAL].Equals(null)
|| navButtons[listIndex][INITIAL].Equals(""))
{
// if the list of lists is empty, add the department name
//initialize the list with with the department name
navButtons[listIndex][INITIAL] = item.DepartmentName;
//add the current select
navButtons[listIndex].Add(item.sel);
}
else if (navButtons[listIndex][INITIAL].Equals(item.DepartmentName))
{
// if the current item's department name is the same
// is the current list's department name,
// add it's selectn
navButtons[listIndex].Add(item.sel);
}
else if (!item.DepartmentName.Equals(navButtons[listIndex][INITIAL]))
{
// if the current item's department name
// is not the same as the initial of this list,
// create new list
navButtons.Add(new List<string>());
listIndex++;
navButtons[listIndex].Add(item.DepartmentName);
navButtons[listIndex].Add(item.sel);
}
}
for (int i = 0; i < navButtons.Count; i++)
{
<button class = "accordion"
onclick = "openAccordion(this)">
@navButtons[i][INITIAL]
</button>
<div class = "tab">
@for (int j = 1; j < navButtons[i].Count; j++)
{
<a class = "tabLinks NoPrint"
onclick = "openTab(this)"
asp-action = "Details"
asp-route-id = "@navButtons[i][j]">
@navButtons[i][j].ToString()
</a>
}
</div>
}
// @Url.Action("Details", "HSCTables", new { id = 1 })
//onclick = "location.href='@Url.Action("Details","HSCTables", new { id = 1 })
}
</div>
</body>
Большое спасибо за уделенное время.
@Llazar Я этого не делаю, _SideNav - это представление, которое я хочу отобразить, и замена «NavMenu» на «_SideNav» по-прежнему дает ту же ошибку. Если я полностью не упускаю суть?
Частичные представления здесь не работают. Я думаю, что из вашего кода вы можете создать viewComponent в этом месте. Но если вы решите создать представление NavMenu
и из него вызовете частичное представление _SideNav
.
@Llazar Я тоже искал, чтобы просмотреть компоненты, но я следовал руководству, чтобы сделать это частичное представление, поэтому я предполагаю, что мой "_SideNav"
, являющийся параметром в возврате моего контроллера, вызывает проблему / нельзя использовать таким образом? Из того, что я читал, для меня подходят компоненты просмотра, но я определенно хотел бы знать, почему это не работает.
Проблемы с вашей Entity Framework не имеют ничего общего с этой проблемой. Вы должны удалить любое упоминание и тег. Задайте новый вопрос, если у вас возникли проблемы с устранением этого предупреждения.
Html.Action был удален из ASP.NET Core и заменен ViewComponent.
@mason Это была всего лишь первая ошибка, я заменю ее на MVC, так как я также получил "AspNet.Mvc 5.2.2 был восстановлен с использованием .NetFramework, Version = v4.61 ... Я подумал, что это может быть что-то, что было влияя на мои зависимости.
@ TiagoÁvila Думаю, это ответ на мой вопрос. Если вы отправите это как ответ, я отмечу это. Спасибо вам всем!
Почему вы ссылаетесь на ASP.NET MVC 5? Это для .NET Framework и старого MVC, работавшего на нем. Это не для .NET Core или ASP.NET Core.
@mason, хорошо, понятно. Я удалил это. Это было частью моих попыток решить мою проблему.
Как сказал @Tiago Avila, Html.Action
был удален из Asp.NET Core, поэтому я перестал пытаться делать это с @html.action
, а скорее с компонентами просмотра, как предложил @Llazar, и это сработало!
Компонент My View:
public class NavViewComponent : ViewComponent
{
private readonly HSCWebAppContext _context;
public NavViewComponent(HSCWebAppContext context)
{
_context = context;
}
public IViewComponentResult Invoke()
{
NavViewModel nav = new NavViewModel();
List<NavViewModel> navList = new List<NavViewModel>();
var items = from n in _context.HSCTable select n;
List<HSCTable> tableList = items.ToList<HSCTable>();
for (int i = 0; i < tableList.Count(); i++)
{
nav.Id = tableList[i].ID;
nav.DepartmentName = tableList[i].DepartmentName;
nav.sel = tableList[i].sel;
navList.Add(nav);
}
return View("_SideNav",tableList);
}
}
Мой вызов в _Layout:
@await Component.InvokeAsync("Nav")
Больше ничего менять не нужно. Спасибо за вашу помощь!
«Размещение как ответ».
Как я уже сказал, Html.Action был удален из ASP.NET Core и заменен на ViewComponents.
В Microsoft Docs есть хороший учебник, вы можете увидеть здесь. Объяснение преимуществ, места, где вы можете разместить View для своего ViewComponent, как использовать параметры и так далее.
Да, я прочитал этот документ, но я уже сделал всю «работу» для частичного просмотра. Будучи любителем, я просто подумал: «Зачем переделывать всю эту работу для компонентов представления, если я могу просто использовать частичные представления». Хотелось бы, чтобы они упомянули, что частичные представления были удалены.
@ZaeemQ на самом деле, частичное представление все еще есть в ASP.NET Core, вы можете вызвать частичное представление, используя '@await Html.PartialAsync ("Partial Name")'. Просто заменили Html.Action.
Ох, вот что я имел в виду. Я использовал partialAsync
, но он работал только с моей индексной страницей, а не с другими моими страницами. Частичный асинхронный режим унаследовал родительский блок просмотра, который работал для моего индексного представления, но не для других, из-за того, как был написан _SideNav
.
У вас есть мнение
NavMenu.cshtml
?