选择复选框后变量包含空值

Variable contains a null value after selecting checkboxes

我有两个 运行 项目,一个 ASP.NET Core MVC 5.0 Web 项目和一个 ASP.NET Core Web API 5.0 项目。当 select 选择任何所需的复选框并在文本框中键入一个数字并在调试时点击下一步时,我注意到在我的 post 操作 SecIndex() 方法中,变量 phoneNumberInput 包含字段 PhoneNumberplansPhoneNumber 将保留我在文本框中输入的值,但 plansnull。我似乎无法理解为什么 plansnull 而它应该包含我 select 编辑的内容。 是否有什么原因导致它 return null 而不是我 select 编辑的值?

MVC 项目:

Controller 我打电话给 API:

public IActionResult SecIndex()
{
    // call planapi
    var result = _planServiceClient.RetrievePlans().Result;
    _logger.Log(LogLevel.Information, "Reached the Second Page View....");
    var x = new Plan.API.Models.ViewPhoneNumberInput { plans = result }; //So that you don't need to change the model in the view and the parameter type in the HttpPost Action.
    return View(x);
}

[HttpPost]
public IActionResult SecIndex(Plan.API.Models.ViewPhoneNumberInput phoneNumberInput)
{
    try
    {
        if (ModelState.IsValid)
        {
            _logger.Log(LogLevel.Information, "User successfully entered their phone number.");
            return RedirectToAction("FinalIndex", "Final");
        }
        else
        {
            _logger.Log(LogLevel.Error, "User missed to enter their phone number");
            throw new Exception("User did not enter a phone number in the textfield!");
        }     
    }
    catch(Exception ex)
    {
        _logger.LogError(ex, "Empty textfield!");
        return View(phoneNumberInput);
    }
}

RetrievePlans() 调用 SecIndex():

public async Task<List<Plan.API.Models.Plans>> RetrievePlans()
{
    var response = await _httpClient.GetAsync("api/plans/AvailablePlans");
    response.EnsureSuccessStatusCode();

    var result = await response.Content.ReadAsStringAsync();

    var json = JsonConvert.DeserializeObject<List<Plan.API.Models.Plans>>(result);
    return json;
}

在 MVC 中查看:

@model Plan.API.Models.ViewPhoneNumberInput

<h2>Second page</h2>
@using (Html.BeginForm())
{
    for (int i = 0; i < Model.plans.Count; i++)
    {
        <input type="checkbox" id="@Model.plans[i].PlanId" />
        <input hidden value="@Model.plans[i].PlanId" />
        <input hidden value="@Model.plans[i].PlanName" />

        <label for="Model.plans[i].PlanId"> @Model.plans[i].PlanName </label>
        <br />
    }

    @Html.TextBoxFor(r => r.PhoneNumber)
    <input id="Button" type="submit" value="Next" />

    <p>  @Html.ValidationMessageFor(r => r.PhoneNumber) </p>
}
<script>
    $('form').submit(function () {
        var count = 0;
        $('input[type=checkbox]').each(function () {
            if (this.checked) {
                this.nextElementSibling.name = "plans[" + count + "].PlanId";
                this.nextElementSibling.nextElementSibling.name = "plans[" + count + "].PlanName";
                count++;
            }
        });
    });
</script>

我试图在 <script> 中放置一个断点,但断点永远不会命中。即使我 select 一个值,这可能是 plansnull?

的原因吗

然后在API项目中:

ViewPhoneNumberInput 型号 class:

public class ViewPhoneNumberInput
{
    [Required(ErrorMessage = "You did not enter your phone number! Please enter your phone number!")]
    public String PhoneNumber { get; set; }
    public List<Plans> plans { get; set; }
}

Plans 型号 class:

public class Plans
{
    public int PlanId { get; set; }
    public string PlanName { get; set; }
}

Controller 对于 API:

[HttpGet]
[Route("AvailablePlans")]
public List<Plans> GetPlan()
{
    var _model = new ViewPhoneNumberInput();
    _model.plans = new List<Plans>();

    _model.plans.Add(new Plans { PlanId = 1, PlanName = "Internet" });
    _model.plans.Add(new Plans { PlanId = 2, PlanName = "TV & Streaming" });
    _model.plans.Add(new Plans { PlanId = 3, PlanName = "Mobile" });
    _model.plans.Add(new Plans { PlanId = 4, PlanName = "Home Security" });
    _model.plans.Add(new Plans { PlanId = 5, PlanName = "Home Phone" });

    var plansAvailable = JsonSerializer.Serialize(_model.plans);
    _logger.Log(LogLevel.Information, "Response-Body: {@Response-Body}", plansAvailable);    

    return _model.plans;
}

以下代码仅包含与 View-Controller 相关的部分。

Selected 属性 添加到 Plan 中:此更改使视图内容更加简单。实际上,进行这个简单的更改后,无需使用 JavaScript 来处理复选框状态。

数据模型:

public class Plan
{
    public int PlanId { get; set; }
    public string PlanName { get; set; }        
    public bool Selected { get; set; }
}

public class ViewPhoneNumberInput
{
    [Required(ErrorMessage = "You did not enter your phone number! Please enter your phone number!")]
    public String PhoneNumber { get; set; }

    public List<Plan> Plans { get; set; }
}

在控制器中:

public IActionResult SecIndex(ViewPhoneNumberInput model)
{            
    if ( model == null || model.Plans == null)
    {
        var result = _planServiceClient.RetrievePlans().Result;       
        model = new Plan.API.Models.ViewPhoneNumberInput { Plans = result };
                 
        ModelState.Clear(); 
    }
    return View(model);
}

[HttpPost]
public IActionResult Processing(ViewPhoneNumberInput data)
{
    if (ModelState.IsValid)
    {
        foreach (var plan in data.Plans)            
        {
            if (plan.Selected)
            {
                /* processing the selected plan */ 
            }                
        }
        return RedirectToAction("FinalIndex", "Final");            
    }
    else
    {
        return View("SecIndex", data);
    }
}

SecIndex.cshtml:

@model Models.ViewPhoneNumberInput

@{ ViewBag.Title = " "; }

<h2>Store List</h2>

@using (Html.BeginForm("Processing", "Home"))
{
    for (int i=0; i < Model.Plans.Count; i++)
    {
        <div class="form-group row">
            @Html.CheckBoxFor(r => Model.Plans[i].Selected)          
            <label>  @Model.Plans[i].PlanName</label><br />

            @Html.HiddenFor(h => @Model.Plans[i].PlanId)
            @Html.HiddenFor(h => @Model.Plans[i].PlanName)
        </div>
    }

    @Html.TextBoxFor(r => Model.PhoneNumber)
    <p>  @Html.ValidationMessageFor(r => Model.PhoneNumber) </p>

    <input id="Button" type="submit" value="Next" />    
}