【问题标题】:ASP NET Core (MVC) problem with passing parameters from the view to the controller将参数从视图传递到控制器的 ASP NET Core (MVC) 问题
【发布时间】:2021-02-21 08:02:34
【问题描述】:

我在视图中有两个 DropDownList。当我尝试传递这些参数时,控制器中的方法被调用但参数等于 null。

当我签入浏览器(F12-network)时,我会查看参数 - 它们已发送但在方法中仍然为空

附: 我尝试更改 List 或 Location 以及 JobTitle 或 CommonEntity 上的参数类型,但它不起作用

控制器:

 public class HelloController: Controller
{
 
    [HttpGet]
    public IActionResult Index()
    {
          
        var locations = new List<Location>()
        {               
               new Location()
               {
                    Id = 0,
                Title = "Russia"
               
            },                
                new Location()
               {
                    Id = 1,
                Title = "Canada"
               }
        };                   
        
        ViewBag.Location = locations;

        var jobs = new List<JobTitle>()
        {
            new JobsTitle()
            {
                Id = 0,
                Title = "Manager"
            } ,
            new JobsTitle()
            {
                Id = 1,
                Title = "Programmer"
            }
        };

        ViewBag.JobTitle = new SelectList(jobs, "Title", "Title");


        return View();
    }

    [HttpPost]
    public string Find(string answer1, string answer2)
    {
        return "Fine";
    }

查看:

@using Stargate.Core.Models.CoreEntities
@model CommonEntity

@using (Html.BeginForm())
{


@Html.DropDownListFor(m => m.Location.Title, new SelectList(ViewBag.Location, "Title", "Title"))
@Html.DropDownListFor(m => m.JobTitle.Title, new SelectList(ViewBag.JobTitle, "Title", "Title"))

<button type="submit">Find</button>

}

型号:

public class CommonEntity
{
    public Location Location { get; set; }       
    public JobTitle JobTitle { get; set; }

}


public class JobTitle
{
    public long Id { get; set; }
    public string Title { get; set; }
}

 public class Location
 {
    public long Id { get; set; }
    public string Title { get; set; }
 }

【问题讨论】:

    标签: c# asp.net asp.net-mvc asp.net-core


    【解决方案1】:

    由于您接受的参数名称是answer1answer2,因此您的视图中应该有一个匹配的名称才能成功绑定。

    你可以修改你的前端代码如下(DropDownListFortoDropDownList):

    @model CommonEntity
    @using (Html.BeginForm("Find", "Hello"))
    {
    @Html.DropDownList("answer1", new SelectList(ViewBag.Location, "Title", "Title"))
    @Html.DropDownList("answer2", new SelectList(ViewBag.JobTitle, "Title", "Title"))
    <button type="submit">Find</button>
    }
    

    你的控制器:

    public class HelloController : Controller
    {
        [HttpGet]
        public IActionResult Index()
        {
    
            var locations = new List<Location>()
        {
               new Location()
               {
                    Id = 0,
                Title = "Russia"
    
            },
                new Location()
               {
                    Id = 1,
                Title = "Canada"
               }
        };
    
            ViewBag.Location = locations;
    
            var jobs = new List<JobTitle>()
        {
            new JobTitle()
            {
                Id = 0,
                Title = "Manager"
            } ,
            new JobTitle()
            {
                Id = 1,
                Title = "Programmer"
            }
        };
    
            ViewBag.JobTitle = jobs;
    
    
            return View();
        }
    
        [HttpPost]
        public string Find(string answer1,string answer2)
        {
            return "Fine";
        }
    }
    

    类:

     public class CommonEntity
    {
        public Location Location { get; set; }
        public JobTitle JobTitle { get; set; }
    
    }
    public class JobTitle
    {
        public long Id { get; set; }
        public string Title { get; set; }
    }
    public class Location
    {
        public long Id { get; set; }
        public string Title { get; set; }
    }
    

    结果:

    【讨论】:

      【解决方案2】:

      你做错事了,

      • 您应该更正您的 cshtml,以便在提交表单时,它将针对您的查找操作,
      @using (Html.BeginForm("Find", "Hello"))
      
      • 在您的查找操作中,您应该在 DefaultModelBinder 可解析的输入参数中提供,因为您没有 ViewModel 来拦截响应,我建议您收到 FormCollection 并且您可以从那里访问您的值。
      [HttpPost]
          public string Find(FormCollection form)
          {
              return "Fine";
          }
      

      【讨论】:

      • 点击按钮后出现错误页面不可用本地站点无法处理此请求
      • 您是否调试过代码以检查它是否命中 Find 操作?可能是您在回调中遇到错误
      • 你的探测是在发布之后,所以我认为你不应该从你的帖子中返回一个字符串,你应该返回一个视图。
      【解决方案3】:

      尝试如下更新参数。详情请参考Model Binding in ASP.NET Core

      [HttpPost]
      public string Find(Location Location, JobTitle JobTitle)
      {
          return "Fine";
      }
      

      或者您可以尝试使用CommonEntity 的参数,如下所示。

      [HttpPost]
      public string Find(CommonEntity commonEntity)
      {
          var locationTitle = commonEntity.Location.Title;
          var jobTitle = commonEntity.JobTitle.Title;
          
          return "Fine";
      }
      

      【讨论】:

      • 如果我首先执行您的解决方案,我收到如下错误: System.InvalidOperationException: "Action 'Controllers.HelloController.Find ' 有多个参数被指定或推断为从请求正文绑定。仅每个动作一个参数可以从body绑定。检查以下参数,并使用'FromQueryAttribute'指定从查询绑定,'FromRouteAttribute'指定从路由绑定,'FromBodyAttribute'用于从body绑定的参数:Location l JobTitle g"
      • 然后,我尝试将此添加到参数中: public string Find([FromQuery] Location l, [FromQuery] JobTitle g) { return "Fine"; } 然后错误消失了,但仍然为空
      • [FromQuery] 将不起作用,因为它会尝试从 query parameters 中查找值(即,来自 url localhost:\\URL?Location.Title=Russia&amp;JobTitle.Title=Programmer)? 之后的部分。但在您的情况下,表单会发布值,所以它可能是[FromBody] 或者不写任何注释,这样框架会尽力从 URL 或 Body 或 Query 中获取值。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-23
      • 2018-05-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多