我正在使用.Net Core进行项目,而我正在使用ASP Razor Pages。在我的模型中,我有一个OnGet,它在我的视图中加载了我需要的所有数据。
public IList<Projet> Projets { get; set; }
public ActionResult OnGet()
{
Projets = _serviceSelect.getProjets();
return Page();
}
然后,在我提交表单时激活的OnPost中。
<form method="post">
<div asp-validation-summary="All" class="text-danger"></div>
<input type="radio" value="1" asp-for="LoginData.TypeCompte" />choice<br />
Username: <input asp-for="LoginData.Username" /><br />
Password: <input asp-for="LoginData.Password" /><br />
Remember me: <input asp-for="LoginData.RememberMe" type="checkbox" /><br />
<input asp-page-handler="connexion" type="submit" value="Login" />
@Html.AntiForgeryToken()
</form>
我想在我的视图中使用我的ModelState显示错误。
public ActionResult OnPostConnexion()
{
if (ModelState.IsValid)
{
// Do stuff
}
else
{
ModelState.AddModelError("", "username or password is blank");
return Page();
}
}
但是,当我返回Page()时,就像模型重新加载一样,当我尝试访问我的数据时,我的对象为空。
Object reference not set to an instance of an object.
@foreach (var item in Model.Projets)
如何在不丢失模型中包含的数据的情况下更新视图?
当你调用“Page()”时,这就是要求一个新的Page对象,当你返回该对象时它将是空白的。页面和视图是不同的,一般用ASP你会使用视图,在MSDN上有一些关于差异和原因的好文章但是现在只要你将Page()更改为View()它应该解决问题。
您获得对象引用错误的原因是因为返回视图时未填充Model.Projects,因此无法在foreach循环中进行迭代。
根据现有代码,您可以在返回页面之前再次填充模型。
public ActionResult OnPostConnexion()
{
if (ModelState.IsValid)
{
// Do stuff
}
else
{
Projets = _serviceSelect.getProjets();
ModelState.AddModelError("", "username or password is blank");
return Page();
}
}
更好的解决方案是:
public ActionResult OnPostConnexion(viewModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
else
{
//do stuff
}
}
您需要在代码中修复两件事:
首先,您需要使用[BindProperty]标记您的Projets属性,如下所示:
[BindProperty]
public IList<Projet> Projets { get; set; }
然后你需要重新编码你的页面,以便Projects的字段在qazxsw poi标签内,这样它们就会被发回到页面,然后你需要重写它们的输出方式:
form
备注您需要在列表中呈现字段,使其获得唯一ID,以便ModelBinder可以在Post上检索它们。在我的例子中,我命名了一个字段FieldOne,这就是它的呈现方式:
<form method="post">
<div asp-validation-summary="All" class="text-danger"></div>
<input type="radio" value="1" asp-for="LoginData.TypeCompte" />choice<br />
Username: <input asp-for="LoginData.Username" /><br />
Password: <input asp-for="LoginData.Password" /><br />
Remember me: <input asp-for="LoginData.RememberMe" type="checkbox" /><br />
<input asp-page-handler="connexion" type="submit" value="Login" />
@Html.AntiForgeryToken()
<!-- SEE REMARK BELOW! -->
@{
for (int i = 0; i < Model.Projets.Count; i++)
{
<input asp-for="@Model.Projets[i].FieldOne" />
<br />
<input asp-for="@Model.Projets[i].FieldTwo" />
}
}
</form>
我遇到了同样的问题,建议的解决方案没有人工作。我通过简单的使用帮助类为我保留模型来解决它。解决方案不优雅但有效:)
<input type="text" id="Projets_0__FieldTwo" name="Projets[0].FieldTwo" value="one">
在我的get方法中,我将一个项添加到字典中:
public interface ISessionHelper
{
void AddRenewItem(string key, object item);
object GetItem(string key);
}
public class SessionHelper : ISessionHelper
{
private readonly Dictionary<string, object> _sessionBag;
public SessionHelper()
{
_sessionBag = new Dictionary<string, object>();
}
public void AddRenewItem(string key, object item)
{
if (_sessionBag.Keys.Contains(key)) _sessionBag.Remove(key);
_sessionBag.Add(key, item);
}
public object GetItem(string key)
{
if (_sessionBag.Keys.Contains(key))
{
return _sessionBag[key];
}
return null;
}
}
在我的post方法中,我从字典中取回模型并为当前模型分配所需的属性:
public async Task<IActionResult> OnGetAsync(int? id)
{
...
_sessionHelper.AddRenewItem(this.ToString(), this);
...
}
不要忘记将服务添加为Singleton:
public async Task<IActionResult> OnPostApplyGuess(int itemId)
{
GameModel model = (GameModel) _sessionHelper.GetItem(this.ToString());
MyProp1= model.MyProp1;
MyProp2 = model.MyProp2 ;
MyProp3= model.MyProp3;
if (!ModelState.IsValid)
{
return Page();
}
return Page();
}
我希望它对某人有帮助:)
我用services.AddSingleton<ISessionHelper, SessionHelper>();
中的return Page();
替换return this.OnGet();
解决了这个问题
这样,OnGet中填充PageModel属性的任何逻辑都会被重用。
所以我的完整示例如下:
public ActionResult OnPostConnexion()