在Razor页面中有条件地调用ViewComponent

时间:2018-11-10 16:17:23

标签: c# asp.net-core

我是Razor Pages和View组件的新手,很显然我没能绕开这些概念:

我有一个Example page,此页面显示在_Layout内部,如下所示:

@page "{value1?}/{value2?}"
@model MyProject.Pages.ExampleModel
@{
    ViewData["Title"] = "Example";
}

现在,我需要根据value1value2有条件地调用ViewComponent:

public class ExampleModel : PageModel
{
    public async Task<IActionResult> OnGetAsync(string value1, string value2)
    {
        // this contains a lot of logic, db access etc, and passing objects to the component, but I'm abbreviating

        if (value1 == null && value2 == null)
        {
            return this.ViewComponent(nameof(SomeComponent));
        }
        else
        {
            return this.ViewComponent(nameof(SomeOtherComponent));
        }

        // return Page();
    }
}

这是我用来调用组件的扩展名:

public static class PageModelExtensions
{
    public static ViewComponentResult ViewComponent(this PageModel pageModel, string componentName, object arguments)
    {
        return new ViewComponentResult
        {
            ViewComponentName = componentName,
            Arguments = arguments,
            ViewData = pageModel.ViewData,
            TempData = pageModel.TempData
        };
    }
}

这是可行的,但是因为我没有调用return Page(),所以呈现组件时没有调用_Layout。我应该如何处理?

1 个答案:

答案 0 :(得分:1)

如果要从这样的Razor页面中渲染View组件,一种选择是在PageModel类中指定所述View组件的名称,然后在对应的文本中使用Component.InvokeAsync。 cshtml文件。可能是这样的:

Example.cshtml.cs

public class ExampleModel : PageModel
{
    public string ViewComponentName { get; set; }

    public async Task<IActionResult> OnGetAsync(string value1, string value2)
    {
        ...

        if (value1 == null && value2 == null)
            ViewComponentName = nameof(SomeComponent);
        else
            ViewComponentName = nameof(SomeOtherComponent);

        return Page();
    }
}

Example.cshtml

@page "{value1?}/{value2?}"
@model MyProject.Pages.ExampleModel

...

@await Component.InvokeAsync(Model.ViewComponentName)

在Example.cshtml.cs中,ViewComponentName是一个新属性,(毫无疑问)表示应作为页面一部分呈现的View Component的名称,在Example.cshtml中使用{{ 1}}。