Razor Pages .NetCore OnPost 处理程序

Posted

技术标签:

【中文标题】Razor Pages .NetCore OnPost 处理程序【英文标题】:Razor Pages .NetCore OnPost Handler 【发布时间】:2021-07-27 23:05:54 【问题描述】:

我正在使用 .NetCore Razor 页面使用 C# 开发一个项目,并且我有这个页面,用户可以通过填写一些字段来进行预约。

我有一个日历字段,用户可以从中选择一个日期。根据该日期,我想在下拉列表中填充可用于约会的时间列表。

我尝试使用像 OnPost() 这样的处理程序,但这需要一个提交按钮,但我只有日历输入。

这是我在 Razor 页面中用于日历的代码


<div class="form-group col-md-4">
    <label asp-for="StartDate"></label>
    <input asp-for="StartDate" class="form-control" />
    <span class="text-danger" asp-validation-for="StartDate"></span>
</div>

在我的模型页面中,我应该有类似的东西

 public IActionResult OnPostStartDate()
 
    \\code that brings from the database the available hours 
 

我是否可以使用任何其他功能,以便当用户从日历中选择日期时,下拉菜单中将填充可用时间?

编辑 在我的 Razor 页面中

@section Scripts 
    <script>
          $("#StartDate").on("change", function () 
              var time = $(this).val();
              $("#select").empty();
              $("#select").append("<option value=''>select </option>");
              $.getJSON(`?handler=Time&time=$time`, (data) => 
                $.each(data, function (i, item) 
                $("#select").append("<option value='"  + "'>" + item.hour + "</option>");
                );
            );      
        );
    </script>






<form class="form-style" method="post" id="createBTForm">
    <div asp-validation-summary="ModelOnly" class="text-danger"></div>
        <div class="form-group">
            <label asp-for="StartDate" class="control-label"></label>
            <input asp-for="StartDate" class="form-control" />
            <span asp-validation-for="StartDate" class="text-danger"></span>
        </div>

   <select id="select" asp-for="Time" class="form-control"></select>

   <div class="form-group button-position col-md4">
          <input type="submit" id="placeRequest" name="placeRequest" value="Place Request" class="btn btn-primary" />
   </div>
</form>

在我的模型页面中

[Required(ErrorMessage = "Field cannot be empty!")]
[BindProperty]
[DataType(DataType.Date)]
[Display(Name = "Start Date:")]
public DateTime StartDate  get; set; 

//this is null after selecting an option from the dropdown
[BindProperty]
public string Time  get;set; 

//this is the method that should work when I press the Place Request submit button
public async Task<IActionResult> OnPost()

    if (!ModelState.IsValid)
    
        return Page();
    

    //here I send the data to the database     
           
    return Redirect(Url.Page(indexPage));



//this is the method that puts the values on the dropdown (this works)
public async Task<IActionResult> OnGetTime(DateTime time)

    //Here I set my model based on database data
      var finalHours = leaveFromLocations.Where(f => !unavailable.Contains(f));

      foreach (var h in finalHours)
      
             model.Add(new Hours
             
                  Hour = h
              );
      

      return new JsonResult(model);


问题是,在我将 json 模型发送到下拉列表并且值出现在下拉列表中后,我无法选择已选择的选项(在选择选项后的调试中 Time 属性显示为 null)

【问题讨论】:

asp-for绑定下拉列表的值,你的值为null,所以时间为null。你应该改变你的代码如下。$("#select").append("&lt;option value='" + item.hour + "'&gt;" + "'&gt;" + item.hour + "&lt;/option&gt;"); 我发现这种方法存在一个问题:如果我尝试选择当前日期,它将不起作用。我尝试将功能从 on change 更改为 onclick,但我根本不允许选择数据 可以看我的test,测试显示如果不点击日历,其时间不会进入输入框。我认为这是datetime控件的默认设置。OnChange事件只有在当前控件发生变化时才会触发。 【参考方案1】:

你可以写一个onchange函数,然后使用ajax发送数据到后端。下面是一个简单的demo。

 <form method="post">
        <div asp-validation-summary="ModelOnly" class="text-danger"></div>
        <div class="form-group">
            <label asp-for="Time.StartDate" class="control-label"></label>
            <input asp-for="Time.StartDate" class="form-control" />
            <span asp-validation-for="Time.StartDate" class="text-danger"></span>
        </div>
        <select id="select" asp-for="Time.Hour" class="form-control"></select>
        <div class="form-group">
            <input type="submit" value="Create" class="btn btn-primary" />
        </div>
</form>
@section Scripts 
    @await html.RenderPartialAsync("_ValidationScriptsPartial");
<script>
    $("#Time_StartDate").on("change", function () 
        var time = $(this).val();
        $("#select").empty();
        $("#select").append("<option value=''>select </option>");
        $.getJSON(`?handler=Time&time=$time`, (data) => 
            $.each(data, function (i, item) 
                //"id" and "hours" is in your JsonResult(model),and remember The first letter of the attribute must be lowercase
                $("#select").append("<option value='" + item.id + "'>" + item.hours + "</option>");
            );
        );
    );
</script>

后端:

  public IActionResult OnGetTime(DateTime time)
    
        //this is a fake data,you can query your data here.
        var model = new List<Hour>
        
            new Hour
            
                Id=1,
                Hours=1
            ,
            new Hour
            
                Id=2,
                Hours=2
            ,
        ;
        return new JsonResult(model);
    

测试结果:

【讨论】:

您的解决方案很棒,但我有一个问题:在模型页面(后端)中,您是如何声明小时的?是 SelectList 类型的绑定属性吗?因为在我的下拉菜单中按照您的步骤操作,选项 1 和 2 显示为未定义 你只需要返回任何一个模型作为一个jsonresult,然后在javascripts中像我的demo一样通过拼接显示下拉列表。记住你的模型中属性的第一个字母必须是小写的像 item.Id 到 item.id 的 javascripts。 如果不起作用,您可以提供您的代码。 到目前为止,我用我的代码编辑了我的帖子,下拉列表获取了我从后端发送的值,但是当我选择一个选项(我从下拉列表中选择一些内容)时,我的 Time 属性为空(在调试模式下)

以上是关于Razor Pages .NetCore OnPost 处理程序的主要内容,如果未能解决你的问题,请参考以下文章

我无法在 asp.net core 2.0 razor pages 中执行下载操作

ASP .NET Core 5 Razor Pages:如何正确使用局部视图并验证其模型状态?

为啥 Razor Pages 是在 Asp.net Core 中创建 Web UI 的推荐方法?

如何使用 .NET Core 2 中的 Razor Pages 更改起始页?

带有 id 的 asp.net core 2 razor pages 路由

.net core 2.0 Razor pages VS 2017表格数据下载