skip to Main Content

My Controller does not receive data from a Form in my View.
I’ve used basically the exact same code before with other models and there it works pefectly fine.
Can someone explain why this doesn’t work?

Controller:

[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult ChangeWiFiNetwork(Models.Settings.NetworkSettings model)
{
    Logger.LogInformation("SSID:", model.SSID);
    Logger.LogInformation("PASS:", model.Password);
    return RedirectToAction("Index");
}

View:

@model Webserver.Models.Settings.Settings

<h1>Settings</h1>

<div class="row">
    <div class="col-6">
        <form asp-action="ChangeWiFiNetwork">
            <div class="form-group">
                <label asp-for="Network.SSID" class="control-label"></label>
                <input asp-for="Network.SSID" class="form-control" />
                <span asp-validation-for="Network.SSID" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Network.Password" class="control-label"></label>
                <input asp-for="Network.Password" class="form-control" />
                <span asp-validation-for="Network.Password" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Save" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

Models:

namespace Webserver.Models.Settings
{
    public class Settings
    {
        public NetworkSettings Network { get; set; }
    }
}

namespace Webserver.Models.Settings
{
    public class NetworkSettings
    {
        public string SSID { get; set; }
        public string Password { get; set; }
    }
}

Output

SSID: 
PASS: 

Both show as null in Debug-Mode.

Firefox Network-Analysis shows Network.SSID and Network.Password are being sent in Form-Data.

I’m using .Net 5

Thanks

3

Answers


  1. Chosen as BEST ANSWER

    For now I'll just extract the Values from Request.Form manually.

    This is really awful code, but I just can't figure out why the model binding doesn't work.

    [HttpPost]
    [ValidateAntiForgeryToken]
    public IActionResult ChangeWiFiNetwork(Models.Settings.NetworkSettings throwaway)
    {
        if (!(Request.Form.ContainsKey("NetworkSettings.SSID") && Request.Form.ContainsKey("NetworkSettings.Password")))
        {
            throw new Exception("SSID or Password missing!");
        }
    
        Models.Settings.NetworkSettings settings = new()
        {
            SSID = Request.Form["NetworkSettings.SSID"],
            Password = Request.Form["NetworkSettings.Password"]
        };
    
        Logger.LogInformation("SSID: " + settings.SSID);
        Logger.LogInformation("PASS: " + settings.Password);
    
        return RedirectToAction("Index");
    }
    

  2. fix the view, since you use AntiForgeryToken add it to form

     <form asp-action="ChangeWiFiNetwork">
     @Html.AntiForgeryToken()
    

    and action input parameter should be the same as model

    public IActionResult ChangeWiFiNetwork(Models.Settings.Settings model)
    
    Login or Signup to reply.
  3. You set the model as @model Webserver.Models.Settings.Settings but in your action, you set the input parameter as Models.Settings.NetworkSettings model,

    So you should change your action like this:

    public IActionResult ChangeWiFiNetwork(Models.Settings.Settings model)
    

    Or changing the binding model in the view:

    @model Webserver.Models.Settings.NetworkSettings
    

    Anyway you need to keep the model the same both in view and controller action.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search