Home > Back-end >  Why does my asp.net model binding not work?
Why does my asp.net model binding not work?

Time:09-21

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

CodePudding user response:

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");
}

CodePudding user response:

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)

CodePudding user response:

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.

  • Related