问题描述
假设我在 ASP.NET RazorPages 中有这个页面:
@{
SocketGuild guild = (SocketGuild) ViewData["guild"]
}
<p>The guild has @(guild.Roles.Count) roles.</p>
public async Task OnGet()
{
ViewData["guild"] = GetGuild();
}
public async Task OnPost()
{
Console.WriteLine("Post Received");
}
当收到 GET 请求时,ViewData["guild"]
由 OnGet 处理程序设置,并且 .cshtml 呈现,允许返回页面。
当收到 POST 请求时,会呈现 .cshtml 文件,但由于 ViewData["guild"]
尚未定义,因此会引发空引用异常。我不需要在帖子中呈现我的 .cshtml 文件,因为我的请求是在后台发出的。
如果执行了 OnGet 方法,是否可以只渲染 .cshtml 文件?如有必要,我愿意切换到 MVC 风格的处理程序。
解决方法
我认为在您的情况下正确的方法是通过某种服务保留实际值,以便它也可以在 Post
请求中访问:
public interface ICacheService
{
Dictionary<string,object> Values { get; set; }
}
public class CacheService : ICacheService
{
public Dictionary<string,object> Values { get; set; } = new Dictionary<string,object>();
}
您还应该在您的 Startup.cs
文件中注册该服务:
public void ConfigureServices(IServiceCollection services)
{
...
services.AddSingleton<ICacheService,CacheService>(); // or Scoped depending on your needs
...
]
然后您可以轻松地使用您的代码使用此类服务:
public class SocketGuildModel : PageModel
{
public ICacheService Cache { get; set; }
public SocketGuildModel(ICacheService cache)
{
Cache = cache;
}
public async Task OnGet()
{
Cache.Values["guild"] = GetGuild();
await Task.CompletedTask;
}
public async Task OnPost()
{
Console.WriteLine("Post Received");
await Task.CompletedTask;
}
public static SocketGuild GetGuild() => new SocketGuild();
}
public class SocketGuild
{
public List<string> Roles { get; set; } = new List<string>();
}
@page
@using RazorPagesDemo.Services
@model RazorPagesDemo.Pages.SocketGuildModel
<form method="post" class="mt-3">
@{
var guild = (SocketGuild)Model.Cache.Values["guild"];
}
<p>The guild has @(guild.Roles.Count) roles.</p>
<button class="btn btn-primary" type="submit">Post</button>
</form>
话虽如此,根据您的具体需求,您还可以在 if ... else ...
文件中添加 .cshtml
逻辑并在条件后面添加门渲染(这可能是 bool
{{1} } 在 IsPost
和 OnGet
方法中设置的属性 OnPost
例如)。