简体   繁体   English

Razor 页面:值不会从 OnGet() 停留在 OnPost()

[英]Razor Pages: Values not staying from OnGet() to OnPost()

I'm working on a ASP.NET Core webpage using Razor Pages.我正在使用 Razor 页面开发 ASP.NET 核心网页。 On one page, a customer is added or selected and the customer_id is passed through correctly in the OnGet function (seen through debugging).在一个页面上,添加或选择了一个客户,并且在 OnGet function 中正确传递了 customer_id(通过调试看到)。 When I then have the user fill out the form, I try to make a call to a SQL server database using Entity Framework.当我让用户填写表格时,我尝试使用实体框架调用 SQL 服务器数据库。 Everything should be working correctly, however, in OnPostAsync(), when I try to import the customer_id value I had set in OnGet(), I get an error because the value somehow gets set to 0 instead of what I had it previously set as.一切都应该正常工作,但是,在 OnPostAsync() 中,当我尝试导入在 OnGet() 中设置的 customer_id 值时,出现错误,因为该值以某种方式设置为 0 而不是我之前设置的值. I don't know why this is happening as I'm generally new to Razor Pages and Entity Framework, but I've posted the code below.我不知道为什么会发生这种情况,因为我通常是 Razor 页面和实体框架的新手,但我已经发布了下面的代码。 Any suggestions would be great!任何建议都会很棒!

AddAssessment.cshtml.cs:添加评估.cshtml.cs:

namespace CustomerPageTest.Pages.Assessment
{
public class AddAssessmentModel : PageModel
{
    private readonly CustomerPageTest.Data.CustomerPageTestContext _context;

    public AddAssessmentModel(CustomerPageTest.Data.CustomerPageTestContext context)
    {
        _context = context;
    }

    public static List<SelectListItem> InDatabaseUserData()
    {
        List<SelectListItem> Users = new List<SelectListItem>();

            string connString = "Data Source = DESKTOP-5A23I9M; Initial Catalog = DataWarehouse; User ID = sa; pwd = 2128Swan";
            string commandString = "SELECT user_id, name FROM KelderUser";

            SqlConnection conn = new SqlConnection(connString);
            SqlDataAdapter adapter = new SqlDataAdapter(commandString, conn);
            DataTable dtCustomers = new DataTable();
            adapter.Fill(dtCustomers);

            foreach (DataRow dataRow in dtCustomers.Rows)
            {
                SelectListItem temp = new SelectListItem()
                {
                    Value = dataRow[0].ToString(),
                    Text = dataRow[1].ToString()
                };
                Users.Add(temp);
            }
        return Users;
    }

    [BindProperty]
    public CustomerPageTest.Assessment Assessment { get; set; } = new CustomerPageTest.Assessment();
    public List<SelectListItem> SelectUser { get; set; } = new List<SelectListItem>();

    public void OnGet(int customerId)
    {
        SelectUser = InDatabaseUserData();
        Assessment.customer_id = customerId;
        if(Assessment == null)
        {
            return RedirectToPage("/Customer/List");
        }
        return Page();
    }

    // To protect from overposting attacks, enable the specific properties you want to bind to, for
    // more details, see https://aka.ms/RazorPagesCRUD.
    public async Task<IActionResult> OnPostAsync()
    {
        if (!ModelState.IsValid)
        {
            return Page();
        }

        foreach(var item in SelectUser)
        {
            if (item.Selected)
            {
                try { Assessment.user_id = Convert.ToInt32(item.Value); } catch (Exception) { }
            }
        }

        try { Assessment.imported_data_datetime = Convert.ToDateTime(Assessment.imported_data_datetime); } catch(Exception) { }
        _context.Assessment.Add(Assessment);
        await _context.SaveChangesAsync();

        return RedirectToPage("/Customer/List");
    }
}

} }

Then AddCustomer.cshtml:然后 AddCustomer.cshtml:

@page
@model CustomerPageTest.Pages.Assessment.AddAssessmentModel

@{
    ViewData["Title"] = "AddAssessment";
}

<h1>AddAssessment</h1>

<h4>Assessment</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form method="post">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="Assessment.vcenter" class="control-label"></label>
                <input asp-for="Assessment.vcenter" class="form-control" />
                <span asp-validation-for="Assessment.vcenter" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Assessment.imported_data_datetime" class="control-label"></label>
                <input asp-for="Assessment.imported_data_datetime" class="form-control" />
                <span asp-validation-for="Assessment.imported_data_datetime" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Assessment.notes" class="control-label"></label>
                <input asp-for="Assessment.notes" class="form-control" />
                <span asp-validation-for="Assessment.notes" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Assessment.user_id"></label>
                <select class="form-control" asp-for="Assessment.user_id" asp-items="Model.SelectUser">
                    <option value="">Select a User</option>
                </select>
            </div>
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-page="/Customer/List">Back to List</a>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

Also, If you have any questions about what is going on in my code, let me know as there are other classes and pages before this.另外,如果您对我的代码中发生的事情有任何疑问,请告诉我,因为在此之前还有其他类和页面。 The main idea is that I have an Assessment class with an integer: customer_id, that needs to be set and it's not getting set.主要思想是我有一个评估 class 和一个 integer:customer_id,需要设置,但没有设置。

The reason this happens is because HTTP is stateless.发生这种情况的原因是因为 HTTP 是无状态的。 Any state (data) that you created in one request is destroyed once that request has been processed unless you take steps to persist it.一旦处理该请求,您在一个请求中创建的任何 state(数据)都会被销毁,除非您采取措施将其持久化。

There are multiple ways to manage state in Razor Pages ( https://www.learnrazorpages.com/razor-pages/state-management ), but in your case, you should use a hidden form field, posting the selected customer ID to the OnPost handler有多种方法可以管理 Razor 页面中的 state ( https://www.learnrazorpages.com/razor-pages/state-management ,但在选择的案例中,您应该使用隐藏表单来发布您的客户 ID/state-management) OnPost 处理程序

I write a demo,and i find you didn't bind the customer_id in the cshtml,so when you post the date to cshtml.cs,you didn't post the customer_id.You can add <input hidden asp-for="Assessment.customer_id" class="form-control" /> in the cshtml to bind customer_id.我写了一个demo,我发现你没有在cshtml中绑定customer_id,所以当你将日期发布到cshtml.cs时,你没有发布customer_id。你可以添加<input hidden asp-for="Assessment.customer_id" class="form-control" />绑定customer_id。

Here is a demo worked:这是一个演示:

cshtml: .cshtml:

<div class="row">
    <div class="col-md-4">
        <form method="post">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="Assessment.vcenter" class="control-label"></label>
                <input asp-for="Assessment.vcenter" class="form-control" />
                <span asp-validation-for="Assessment.vcenter" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Assessment.imported_data_datetime" class="control-label"></label>
                <input asp-for="Assessment.imported_data_datetime" class="form-control" />
                <span asp-validation-for="Assessment.imported_data_datetime" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Assessment.notes" class="control-label"></label>
                <input asp-for="Assessment.notes" class="form-control" />
                <span asp-validation-for="Assessment.notes" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Assessment.user_id"></label>
                <select class="form-control" asp-for="Assessment.user_id" asp-items="Model.SelectUser">
                    <option value="">Select a User</option>
                </select>
            </div>
            <input hidden asp-for="Assessment.customer_id" class="form-control" />
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

cshtml.cs: cshtml.cs:

public class AddCustomerModel : PageModel
    {
        [BindProperty]
        public Assessment Assessment { get; set; } = new Assessment();
        public List<SelectListItem> SelectUser { get; set; } = new List<SelectListItem>();
        public IActionResult OnGet()
        {
            for (int i = 1; i < 6; i++) {
                SelectListItem temp = new SelectListItem()
                {
                    Value = i+"",
                    Text = "user"+i
                };
                SelectUser.Add(temp);
            }
            Assessment.customer_id = 2;
            Assessment.vcenter = "vcenter";
            return Page();


        }
        public IActionResult OnPost() {
            if (!ModelState.IsValid)
            {
                return Page();
            }
            return Page();
        }
    }

Result:结果: 在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM