【问题标题】:Having error when displaying partial view in .NET Core在 .NET Core 中显示部分视图时出错
【发布时间】:2020-08-17 09:46:29
【问题描述】:

我正在尝试使用部分视图在不同页面上显示资产信息,但出现以下错误

“InvalidOperationException:名为“AssetInfo”的视图组件可能 找不到。视图组件必须是公共的非抽象类, 不包含任何通用参数,并且要么用 'ViewComponentAttribute' 或类名以 “视图组件”后缀。视图组件不能用 'NonViewComponentAttribute'。”

控制器

  public ActionResult AssetInfo(int? Id)
  {
        var model = _context.Asset.Where(x => x.Id == Id).ToList();
        return PartialView("_AssetInfo", model);
  }

局部视图

@model IEnumerable<InformationAssetRegister.Models.Asset>
<table border="1" cellpadding="4" cellspacing="4">
<tr>
    <th style="background-color: Yellow;color: blue">
        Asset Name
    </th>
    <th style="background-color: Yellow;color: blue">
       Asset type
    </th>
</tr>

@foreach (var item in Model)
{
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.AssetName)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.AssetType)
        </td>
    </tr>

}

我尝试使用 Html.RenderAction,但 Renderaction 不能在 .Net Core 中使用

  @{
    Html.RenderAction("AssetInfo", "Assets", new {Id= ViewBag.AssetId });
   }

我也试过下面的代码

   @await Component.InvokeAsync("AssetInfo", new { Id = ViewBag.AssetId })

任何人都可以帮助解决这个问题我是 .Net Core 的新手

【问题讨论】:

  • 你能展示一下你的Views文件夹的结构吗?
  • @Roar 刚接触 .net core 不知道我需要一个 ViewComponent 调用,请你帮忙
  • 我尝试使用 Html.RenderAction,但无法在线访问,但我想我遗漏了一些东西,但我不知道是什么

标签: c# model-view-controller asp.net-core-mvc


【解决方案1】:

据我所知,Html.RenderAction 已在 asp.net 核心中删除。 ASP.NET Core 使用名为 ViewComponents 的新功能来实现相同的目的。 Article。关于如何用 ViewComponents 替换 Renderaction 的更多细节,你可以参考这个answer

如果你还想在asp.net core中使用Html.RenderAction。

我建议你可以自己实现它,你可以创建一个类并将以下代码添加到你的项目中。

using System;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Html;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.AspNetCore.Routing;

namespace Microsoft.AspNetCore.Mvc.Rendering
{

    public static class HtmlHelperViewExtensions
    {
        public static IHtmlContent RenderAction(this IHtmlHelper helper, string action, object parameters = null)
        {
            var controller = (string)helper.ViewContext.RouteData.Values["controller"];
            return RenderAction(helper, action, controller, parameters);
        }

        public static IHtmlContent RenderAction(this IHtmlHelper helper, string action, string controller, object parameters = null)
        {
            var area = (string)helper.ViewContext.RouteData.Values["area"];
            return RenderAction(helper, action, controller, area, parameters);
        }

        public static IHtmlContent RenderAction(this IHtmlHelper helper, string action, string controller, string area, object parameters = null)
        {
            if (action == null)
                throw new ArgumentNullException(nameof(controller));
            if (controller == null)
                throw new ArgumentNullException(nameof(action));

            var task = RenderActionAsync(helper, action, controller, area, parameters);
            return task.Result;
        }

        private static async Task<IHtmlContent> RenderActionAsync(this IHtmlHelper helper, string action, string controller, string area, object parameters = null)
        {
            // fetching required services for invocation
            var currentHttpContext = helper.ViewContext.HttpContext;
            var httpContextFactory = GetServiceOrFail<IHttpContextFactory>(currentHttpContext);
            var actionInvokerFactory = GetServiceOrFail<IActionInvokerFactory>(currentHttpContext);
            var actionSelector = GetServiceOrFail<IActionDescriptorCollectionProvider>(currentHttpContext);

            // creating new action invocation context
            var routeData = new RouteData();
            var routeParams = new RouteValueDictionary(parameters ?? new { });
            var routeValues = new RouteValueDictionary(new { area, controller, action });
            var newHttpContext = httpContextFactory.Create(currentHttpContext.Features);

            newHttpContext.Response.Body = new MemoryStream();

            foreach (var router in helper.ViewContext.RouteData.Routers)
                routeData.PushState(router, null, null);

            routeData.PushState(null, routeValues, null);
            routeData.PushState(null, routeParams, null);

            var actionDescriptor = actionSelector.ActionDescriptors.Items.First(i => i.RouteValues["Controller"] == controller && i.RouteValues["Action"] == action);
            var actionContext = new ActionContext(newHttpContext, routeData, actionDescriptor);

            // invoke action and retrieve the response body
            var invoker = actionInvokerFactory.CreateInvoker(actionContext);
            string content = null;

            await invoker.InvokeAsync().ContinueWith(task =>
            {
                if (task.IsFaulted)
                {
                    content = task.Exception.Message;
                }
                else if (task.IsCompleted)
                {
                    newHttpContext.Response.Body.Position = 0;
                    using (var reader = new StreamReader(newHttpContext.Response.Body))
                        content = reader.ReadToEnd();
                }
            });

            return new HtmlString(content);
        }

        private static TService GetServiceOrFail<TService>(HttpContext httpContext)
        {
            if (httpContext == null)
                throw new ArgumentNullException(nameof(httpContext));

            var service = httpContext.RequestServices.GetService(typeof(TService));

            if (service == null)
                throw new InvalidOperationException($"Could not locate service: {nameof(TService)}");

            return (TService)service;
        }
    }
}

查看:

@Html.RenderAction("AssetInfo", "Home", new { Id = 2 });

家庭控制器:

    public ActionResult AssetInfo(int? Id)
    {
        //var model = _context.Asset.Where(x => x.Id == Id).ToList();
        var model = new List<Asset>() {
         new Asset(){ AssetName="te", AssetType="te2" }
        };

        return PartialView("_AssetInfo", model);
    }

结果:

【讨论】:

  • 感谢您的帮助,我按照您在回复中的建议创建了一个 Html.RenderAction
  • 当操作方法返回时,该方法无法正常工作,例如Content(""),有什么想法吗?
猜你喜欢
  • 1970-01-01
  • 2020-04-13
  • 1970-01-01
  • 2019-08-09
  • 2019-10-15
  • 2019-09-26
  • 1970-01-01
  • 1970-01-01
  • 2017-04-07
相关资源
最近更新 更多