I'm working on an asp.net core application. There is a settings page that is initially empty. The user can then update the settings by selecting a json file. These settings are then confirmed and sent to the controller. The controller should return the same page but displaying the updated settings.
The file is being read and sent to the controller, it is then correctly being deserialized into a settings object and stored in the session.
I have tried using a GET for updating the settings but the query string is too long.
This is the form the user submits, it's part of a dialog that is shared between multiple different functions so is very generic.
<form method="post">
<button type="submit" class="btn btn-primary" id="modalSubmitButton">Okay</button>
</form>
After the user chooses a file the content of it is retrieved and an event handler is set for the above button.
function OpenFile(event) {
const input = event.target
if ('files' in input && input.files.length > 0) {
var file = (event.target.files)[0];
var fileReader = new FileReader();
fileReader.onload = (function (file) {
return function (e) {
var contents = e.target.result;
document.getElementById("modalHeading").innerHTML = "Please confirm overwrite";
document.getElementById("modalSubmitButton").addEventListener("click", function (e) {
LoadSettings(contents);
});
$("#dialog").modal('show');
};
})(file);
fileReader.readAsText(file);
}
}
Adding this to the click event makes the controller only called once (but with null for the model)
e.preventDefault();
e.stopPropagation();
e.stopImmediatePropagation();
return false;
The ajax call to call the controller when the button is clicked.
function LoadSettings(settings) {
data = JSON.stringify(settings);
$.ajax({
type: "POST",
data: data,
url: "https://localhost:44365/Site/LoadSettings",
contentType: "application/json; charset=utf-8"
})
}
This is the function that is called, there are two different settings pages depending on the json.
[HttpPost]
public void LoadSettings([FromBody]SiteSettings config)
{
HttpContext.Session.SetObject("config", config);
if (config.Config.Count < 2)
{
return Settings();
}
return MultiSettings();
}
Which calls this (the controller function responsible for this page).
[HttpGet]
public IActionResult Settings()
{
var config = HttpContext.Session.GetObject<SiteSettings>("config");
Model = new SettingsViewModel();
if (config != null)
{
Model.Config = config;
}
return View(Model);
}
That constructor takes the settings json and deserializes it.
public SiteSettings Config { get; set; }
public SettingsViewModel(string settingsConfig)
{
try
{
Config = JsonConvert.DeserializeObject<SiteSettings>(settingsConfig);
}
catch (Exception ex)
{
Config = new SiteSettings();
}
}
I am getting a 415 error when calling this using Ajax. I am able to make a POST and send the settings via Postman and receive the page with the updated settings. Looking at it in Fiddler the function is called twice, the first with the json and the second without.
In Fiddler the first request has the 'Session was aborted by the client, Fiddler or the server' icon.