Problem
I have partial view which update data on server.
Partial view contains list of configurations (can be check box or text box depends on type).
This code is working, and I would like to know how to implement this better.
Main question is related to “@Html.HiddenFor”.
Is this correct way to implement update?
Without “@Html.HiddenFor” my model data is not ok.
Action:
public async Task<IActionResult> UpdateConfiguration(List<ConfigurationModel> configurations)
{
logger.LogInformation("Update configurations");
using (var client = new HttpClient())
{
SetToken(client, this.HttpContext);
var configUrl = Helper.GetUrlManagerApi(env, "Configuration");
var response = await client.PutAsync(configUrl, configurations.ToJson());
HandleResponseError(response, logger);
return RedirectToAction("Index", "Home");
}
}
Partial view:
@using Microsoft.EntityFrameworkCore.Metadata.Internal
@using Bluebox.Common.Models
@using Bluebox.Common.Helper
@using Microsoft.AspNetCore.Mvc.Localization
@using SettingsApp.Models;
@inject IViewLocalizer Localizer
@model List<ConfigurationModel>
@using (Html.BeginForm("UpdateConfiguration", "ManagerSettings"))
{
<table class="table table-hover table-striped">
<thead class="h2-table">
<tr>
<th>@Localizer["Property"]</th>
<th>
@Localizer["Edit"]
</th>
</tr>
</thead>
@for (var i = 0; i < Model.Count(); i++)
{
<tr>
<td>
@Localizer[Model[i].LocalizeId.ToString()]
@Html.HiddenFor(model => model[i].Id, @Model[i].Id)
@Html.HiddenFor(model => model[i].LocalizeId, @Model[i].LocalizeId)
@Html.HiddenFor(model => model[i].Key, @Model[i].Key)
@Html.HiddenFor(model => model[i].Type, @Model[i].Type)
</td>
<td>
@if (Model[i].Type == PropertyType.Boolean)
{
@Html.CheckBoxFor(model => model[i].ValueBool, Model[i].Value == "true")
}
else if (Model[i].Type == PropertyType.Number)
{
@Html.TextBoxFor(model => model[i].ValueNum, new { style = "width:50px;", @type = "number" })
}
else if (Model[i].Type == PropertyType.Text)
{
@Html.TextBoxFor(model => model[i].Value, new { style = "width:250px;" })
}
</td>
</tr>
}
</table>
<div>
<input type="submit" class="button" value='@Localizer["Update"]' />
</div>
}
Solution
The most problem in "@Html.HiddenFor"
is that users may change this value by means of a browser developer window or CSRF, for avoiding last one you can use
@Html.AntiForgeryToken()
You can protect your application from adverse changes if you will reread all hidden properties such as LocalizeId
, Key
and Type
from your data source before applying user’s changes.