asp.net core didn't binding value

Mike Feng 26 Reputation points
2023-04-03T02:15:15.83+00:00

The input control didn't show the binding values. Here is the reproduce steps:

  1. open vs2019, and choose "ASP.NET Core Web App(Model-View-Controller)" template.
  2. Leave the project name as default: WebApplication1.
  3. choose Target Framework: .NET 5.0, "None" Authentication Type.
  4. Use this code for Startup.cs
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;

namespace WebApplication1
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllersWithViews();
            services.AddSession(options => { options.IdleTimeout = TimeSpan.FromMinutes(5); });
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
            }
            app.UseSession();
            app.UseStaticFiles();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Error}/{id?}");
            });
        }
    }
}

  1. Add two models
using System;
using System.ComponentModel.DataAnnotations;

namespace WebApplication1.Models
{
    [Serializable]
    public class QueryInfoModel
    {
        [Display(Name = "Work Number")]
        public string WorkNum { get; set; }
    }
}

And this:

using System;
using System.ComponentModel.DataAnnotations;

namespace WebApplication1.Models
{
    [Serializable]
    public class StaffInfoModel
    {
        [Display(Name = "Work Number")]
        public string workNum { get; set; }
    }
}
  1. Modify the Index.cshtml
@model StaffInfoModel
@{
    ViewData["Title"] = "Home Page";
}
<div class="text-center">
    <form asp-controller="Home" asp-action="InputInfo" method="post" class="form-horizontal col-md-offset-4 col-md-8">
        @*工号*@
        <div class="form-group form-inline">
            <label asp-for="workNum" class="control-label col-sm-4"></label>
            <input type="text" asp-for="workNum" class="form-control col-sm-4" readonly="readonly" />
        </div>
    </form>
</div>
  1. Add Query.cshtml
@model QueryInfoModel
@{
    ViewData["Title"] = "Query Page";
}
<div class="text-center">
    <form asp-controller="Home" asp-action="Query" method="post" class="form-horizontal col-md-offset-4 col-md-8">
        <div class="form-group form-inline">
            <label asp-for="WorkNum" class="control-label col-sm-4"></label>
            <input type="text" asp-for="WorkNum" class="form-control col-sm-4" readonly="readonly" />
        </div>
        <span asp-validation-for="WorkNum" class="text-danger  col-sm-offset-3"></span>

        <div class="form-group form-inline">
            <label class="control-label col-sm-4"></label>
            <input type="submit" value="query" class="btn btn-primary col-sm-4" />
        </div>

    </form>
</div>
  1. And this is the HomeController.cs
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using WebApplication1.Models;

namespace WebApplication1.Controllers
{
    public class HomeController : Controller
    {
        private readonly ILogger<HomeController> _logger;

        public HomeController(ILogger<HomeController> logger)
        {
            _logger = logger;
        }

        public IActionResult Index()
        {
            return View();
        }
        public IActionResult Query()
        {
            return View();
        }

        [HttpPost]
        public IActionResult Query(QueryInfoModel model)
        {
            StaffInfoModel staff = new StaffInfoModel();
            staff.workNum = "1010101010";

            Debug.WriteLine(staff.workNum);

            return View("Index", staff);
        }
        public IActionResult Privacy()
        {
            StaffInfoModel staff = new StaffInfoModel();
            staff.workNum = "1010101010";

            return View("Index", staff);
        }

        [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
        public IActionResult Error()
        {
            return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
        }
    }
}
  1. At last, Modify the navbar in the _layout.cshtml

                <div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
                    <ul class="navbar-nav flex-grow-1">
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Query">Query</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
                        </li>
                    </ul>
                </div>

Now, run the application. When Press the Privacy, you can see there is a string in the textbox. But when click the query button in the Query page, there is no content in the textbox. And the confusion thing is when you input some text in the query textbox, and then click the query button, you will see the inputed text in the textbox. It seems the binding is failed. But I know the binding didn't failed, because when click the privacy menu, the text 1010101010 is showing. So why the value cannot be shown correctly when click the Query button in the query page?

ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,678 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Farid Uddin Kiron MSFT 456 Reputation points Microsoft Vendor
    2023-04-03T09:20:11.7533333+00:00

    So why the value cannot be shown correctly when click the Query button in the query page?

    As you may know model binding and model validation occur before the execution of a controller action and while you are sending request to Query Method which expecting QueryInfoModel as its mandatory thus, your model validation get failed and internally it throws error and new model binding skipped. As you can see as following:

    MdolSatass

    How to resolve:

    As you already noticed, when Model Validation got failed for QueryInfoModel which is null no longer it binds value to ModelState which is View("Index", staff). Therefore, you have to clear existing modelState by using ModelState.Clear() and then need to assign new value as following:

            [HttpPost]
            public IActionResult QueryGetParam(QueryInfoModel model)
            {
                ModelState.Clear();
                StaffInfoModel staff = new StaffInfoModel();
                staff.workNum = "1010101011";
                return View("Index", staff);
             
    
            }
    

    Above tweaking would resolve your issue.

    Output:

    ModelState

    Note: If you would like to know more details on Model validation you could check our official document here

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.