【问题标题】:ASP.NET Core MVC with Razor Pages (can't return object from a different model)带有 Razor 页面的 ASP.NET Core MVC(不能从不同的模型返回对象)
【发布时间】:2019-02-27 12:08:28
【问题描述】:

我在作为 Razor 页面模型 (cs) 文件的一部分创建的方法中调用 Azure 表。结果的类型为TenantEntityModel。我想简单地在我的视图中显示这些结果。

是否可以这样做,如果可以,我的 Razor 页面模型中需要包含什么?

我的 Razor 模型中的方法有以下调用:

TenantEntityModel Result = await azureTableConnection.TenantLookupAsync(azureTableConnection, domainName, id);

我以为我可以在视图中使用@Model.Result.DomainName,但是没有引用此对象,因为我的 Razor 模型中不存在Result。所以我尝试将它添加到我的 Razor 模型中:

public TenantEntityModel Result { get; }

这使我可以在我的 Razor 视图中访问 Result 的属性。如果我在return Page() 语句之前放置一个断点,我可以看到Result 对象具有我所追求的属性。然而,当视图被渲染时,Model 对象的Result 属性为空,我得到:

NullReferenceException:对象引用未设置为对象的实例。

我也试过添加BindProperty如下:

[BindProperty]
public TenantEntityModel Result { get; }

...但这也没有用。因此,我不知道如何获取查询结果,使用来自不同类的模型填充对象,然后使用该对象的结果呈现页面。

查看代码:

@page
@model ApiKeyModel
@if (@Model.Result.ApiKey == null)
            {
                //show the button
                <button name="CreateApiKey" type="submit" class="btn btn-primary">Create new API Key</button>
            }

控制器代码:

public class ApiKeyModel : PageModel
{
    private readonly UserManager<UserRegistrationExtension> _userManager;
    private readonly ILogger<PersonalDataModel> _logger;

    [BindProperty]
    public TenantEntityModel Result { get; set; }

    public ApiKeyModel(
        UserManager<UserRegistrationExtension> userManager,
        ILogger<PersonalDataModel> logger)
    {
        _userManager = userManager;
        _logger = logger;
    }

    public async Task<IActionResult> OnGet()
    {
        // need to validate if account exists first
        var user = await _userManager.GetUserAsync(User);
        if (user == null)
        {
            return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
        }

        var domainName = user.Office365DomainName;
        var id = user.Id;
        AzureTableConnection azureTableConnection = new AzureTableConnection();
        TenantEntityModel Result = await azureTableConnection.TenantLookupAsync(azureTableConnection, domainName, id);

        return Page();
    }

【问题讨论】:

  • 你的控制器和查看代码在哪里?
  • 已编辑。只是好奇...... Razor 页面中的“控制器代码”是否包含视图页面的“代码背后”?如果是这样,“模型”在哪里?可能是一个愚蠢的问题,但我认为 Razor 页面将所有内容都填充在 .cs 文件(控制器和模型)中。
  • 对不起,你是对的,我忘了这是 ASP.NET Core 中的 Razor Pages

标签: c# razor asp.net-core-mvc razor-pages


【解决方案1】:

将您的 PageModel 代码更改为此。您正在创建一个局部变量 TenantEntityModel Result,而不是为您的属性赋值。

public class ApiKeyModel : PageModel
{
    private readonly UserManager<UserRegistrationExtension> _userManager;
    private readonly ILogger<PersonalDataModel> _logger;

    [BindProperty]
    public TenantEntityModel Result { get; set; }

    public ApiKeyModel(
        UserManager<UserRegistrationExtension> userManager,
        ILogger<PersonalDataModel> logger)
    {
        _userManager = userManager;
        _logger = logger;
    }

    public async Task<IActionResult> OnGet()
    {
        // need to validate if account exists first
        var user = await _userManager.GetUserAsync(User);
        if (user == null)
        {
            return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
        }

        var domainName = user.Office365DomainName;
        var id = user.Id;
        AzureTableConnection azureTableConnection = new AzureTableConnection();
        Result = await azureTableConnection.TenantLookupAsync(azureTableConnection, domainName, id);

        return Page();
    }
}

【讨论】:

  • 成功了!谢谢约翰!!这就说得通了。所以没有必要把类名(模型)放在我想的变量前面。这是因为我的班级之前通过public TenantEntityModel Result {get; set;} 片段定义了它的类型吗?
  • 是的,这是您的视图代码可以访问的属性!
  • “您正在创建一个局部变量 TenantEntityModel Result ” - 啊!刚才这让我绊倒了几个小时。嗬! :)
【解决方案2】:

对于在Razor Page 中在ViewPageModel 之间传递模型,您需要为定义的模型public TenantEntityModel Result { get; set; } 设置值,而不是定义一个新对象TenantEntityModel Result

尝试将OnGet()改为:

public async Task<IActionResult> OnGet()
{
    // need to validate if account exists first
    var user = await _userManager.GetUserAsync(User);
    if (user == null)
    {
        return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
    }

    var domainName = user.Office365DomainName;
    var id = user.Id;
    AzureTableConnection azureTableConnection = new AzureTableConnection();
    Result = await azureTableConnection.TenantLookupAsync(azureTableConnection, domainName, id);

    return Page();
}

【讨论】:

    猜你喜欢
    • 2019-03-12
    • 2020-10-01
    • 2020-02-09
    • 2018-01-07
    • 2020-04-01
    • 2020-08-22
    • 1970-01-01
    • 2021-01-27
    • 2018-11-26
    相关资源
    最近更新 更多