我正在尝试将值从Razor Page
的OnGetAsync
中的另一个Model
赋值,以进行一些数据验证,然后将它们赋值回OnPostAsync
上的实际Model
以保存数据。
我在Input.TestName = TestData.TestName;
这一行得到NullReferenceException
错误
public class TestData
{
[Key]
public int TestID { get; set; }
public string TestName { get; set; }
}
页面模型
private readonly Test.Models.TestContext _context;
public EditModel(Test.Models.TestContext context)
{
_context = context;
}
[BindProperty]
public TestData TestData { get; set; }
[BindProperty]
public InputModel Input { get; set; }
public class InputModel
{
[Required, MaxLength(50), MinLength(3)]
public string TestName { get; set; }
}
public async Task<IActionResult> OnGetAsync(int? id)
{
TestData = await _context.TestData.FirstOrDefaultAsync(m => m.TestID == id);
Input.TestName = TestData.TestName; //Error Occurs here. TestData.TestName has value while debug.
return Page();
}
public async Task<IActionResult> OnPostAsync()
{
TestData.TestName = Input.TestName;
_context.Attach(TestData).State = EntityState.Modified;
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
我在InputModel class
之外尝试了TestName
,它工作得很好,但我有很多属性可以像这样使用。所以我想把它们放在一个class
下
请建议我在这里遗漏了什么。
发布于 2018-08-11 19:28:09
正如您在问题中确认在调试器中查看时TestData.TestName
具有值一样,您应该将注意力转向Input.TestName
。更具体地说,这可能意味着Input
属性本身为null
,这将导致您的NullReferenceException
。
这也是有道理的。当OnPostAsync
被调用时,ASP.NET核心试图使用请求中的数据绑定到您的Input
属性,这导致它为您创建一个InputModel
实例。这是通过使用Input
属性本身上已有的[BindProperty]
属性启用的。
但是,当调用OnGetAsync
时,不会发生相同的过程。默认情况下,[BindProperty]
将只触发非GET请求来执行此绑定,这意味着OnGetAsync
调用中的Input
将为null
(这是引用类型属性的默认设置)。
要解决此问题,请在尝试设置其TestName
值之前,更新您的OnGetAsync
实现以创建其自己的Input
实例。以下是实现这一点的一种方法:
public async Task<IActionResult> OnGetAsync(int? id)
{
TestData = await _context.TestData.FirstOrDefaultAsync(m => m.TestID == id);
Input = new InputModel { TestName = TestData.TestName };
return Page();
}
同样值得记住的是,如果id不匹配,您对FirstOrDefaultAsync
的调用将把TestData
设置为null
,这将给您一个不同的NullReferenceException
。
https://stackoverflow.com/questions/51802241
复制相似问题