如何在OnPost之后将我的模型保存在我的视图中?

问题描述 投票:1回答:6

我正在使用.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)

如何在不丢失模型中包含的数据的情况下更新视图?

c# asp.net-core razor-pages
6个回答
0
投票

当你调用“Page()”时,这就是要求一个新的Page对象,当你返回该对象时它将是空白的。页面和视图是不同的,一般用ASP你会使用视图,在MSDN上有一些关于差异和原因的好文章但是现在只要你将Page()更改为View()它应该解决问题。


0
投票

您获得对象引用错误的原因是因为返回视图时未填充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
    }
}

0
投票

尝试使用TempData。 enter image description here

更多信息:http://www.tutorialsteacher.com/mvc/tempdata-in-asp.net-mvc


0
投票

您需要在代码中修复两件事:

首先,您需要使用[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>

0
投票

我遇到了同样的问题,建议的解决方案没有人工作。我通过简单的使用帮助类为我保留模型来解决它。解决方案不优雅但有效:)

<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();
    }

我希望它对某人有帮助:)


0
投票

我用services.AddSingleton<ISessionHelper, SessionHelper>(); 中的return Page();替换return this.OnGet();解决了这个问题

这样,OnGet中填充PageModel属性的任何逻辑都会被重用。

所以我的完整示例如下:

public ActionResult OnPostConnexion()
© www.soinside.com 2019 - 2024. All rights reserved.