Update data in partial view

Posted on

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>
}

Result:
enter image description here

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.

Leave a Reply

Your email address will not be published. Required fields are marked *