【问题标题】:Why controller no works only in Html.PartialAsync?为什么控制器 no 仅在 Html.PartialAsync 中有效?
【发布时间】:2020-11-19 15:28:52
【问题描述】:

现在我有了一个控制器:

public async Task<IActionResult> Location()
        {
            Models.LocationModel Location = null;
            //some logic
            return View(Location);
        }

这是视图:

@model Vishdo.Models.LocationModel
<div>
    <h5>@Model.City</h5>
    <span>@Model.Name</span>
    <span>@Model.Phone</span>
</div>

当我通过 URL(https://localhost:44372/home/location) 直接访问视图时,一切正常。

现在我将它添加到 _Layout.cshtml 中,如下所示:

@Html.PartialAsync("/Views/Home/Location.cshtml")

运行后在ViewLocation.cshtml报错:

System.NullReferenceException
  HResult=0x80004003
  Message=Object reference not set to an instance of an object.
  Source=Sample.Views
  StackTrace:
   at AspNetCore.Views_Home_Location.<ExecuteAsync>d__0.MoveNext() in E:\Project\Sample\Views\Home\Location.cshtml:line 3

我在 Location 控制器中添加了一个断点,但发现它永远无法正常工作。所以Model总是为null,报这个错误。

另外,我将它添加到_Layout.cshtml 中,因为所有页面都需要此功能,而_Layout.cshml 没有控制器,所以我必须这样做。

我的代码有什么问题?我该如何解决?谢谢。

【问题讨论】:

    标签: asp.net-core .net-core


    【解决方案1】:

    由于@Html.PartialAsync() 不会触发控制器操作,因此您有多种选择来解决您的问题。

    1-您应该从任何服务中获取 Location 模型并将其传递给@Html.PartialAsync(),如下所示:

    @inject LocationService locationService
    @{
        var locationModel = locationService.GetLocation();
    }
    

    然后将此 locationModel 传递给@Html.PartialAsync()

    @Html.PartialAsync("/Views/Home/Location.cshtml", locationModel );
    

    2- 如上所述使用 ViewComponent。

    3- 通过将其实现为 HtmlHelper 扩展来使用 @Html.Action()。参考这个here

    【讨论】:

    • 我正在尝试第一种方式。模型成功转移到视图,最后渲染了一个奇怪的字符串“System.Threading.Tasks.Task`1[Microsoft.AspNetCore.Html.IHtmlContent]”。
    • 好吧,我应该在 PartialAsync 之后添加一个.Result。现在可以了。
    【解决方案2】:

    我在 Location 控制器中添加了一个断点,但发现它永远无法正常工作。所以Model总是为null,报这个错误。

    这是预期的行为,@Html.PartialAsync() 不会触发控制器动作,它直接搜索视图文件夹下的部分视图。

    另外,你可以通过ViewComponent来实现。我做了一个如下的演示:

    1.在你的项目中创建一个名为ViewComponents的文件夹,并创建一个名为LocationViewComponent的类

    public class LocationViewComponent : ViewComponent
    {
        public IViewComponentResult Invoke()
        {
            var Location = new LocationModel()
            {
                City = "AAA",
                Name = "BBB",
                Phone = "CCC"
            };
            return View(Location);
        }
    } 
    

    2.视图组件的默认视图名称为 Default.cshtml,将其添加到 Shared 文件夹中,如下所示:

    默认.cshtml

    @model LocationModel
    
    <div>
        <h5>@Model.City</h5>
        <span>@Model.Name</span>
        <span>@Model.Phone</span>
    </div>
    

    3.调用布局中的ViewComponent:

    <div class="container">
        <main role="main" class="pb-3">
            @RenderBody()
            @await Component.InvokeAsync("Location")
        </main>
    </div>
    

    结果:

    更多详情可以参考document

    【讨论】:

    • 顺便说一句,正如你所说,@Html.PartialAsync() 不会触发控制器动作。有没有其他方法可以在不使用 ViewComponent 的情况下实现这一点?
    • @Munesh Kumar 给出的选项也是可行的。
    猜你喜欢
    • 2012-09-16
    • 1970-01-01
    • 2014-05-23
    • 1970-01-01
    • 2019-09-21
    • 2022-10-24
    • 1970-01-01
    • 2018-07-11
    • 1970-01-01
    相关资源
    最近更新 更多