When you pass a model property, rather than the model, to a partial then the binding name in the partial will not match the model for postback. You can use a different model for postback that matches the new binding names. You can also make a custom viewdata dictionary where you set the prefix
Chekbox from partial view isn't mapped
Hi,
1st sorry for my bad english :-/
In my Razor pages app, I built a form using partial views since this options are shared with many pages like this :
<form method="post">
<div asp-validation-summary="All" class="text-danger"></div>
<div class="row">
<div class="col-12 col-sm-4 col-lg-3 col-xl-3 col-xxl-2 mb-sm-2 text-primary">
@Html.DisplayNameFor(model => model.Chapter.Title)
</div>
<div class="col-12 col-sm-8 col-lg-7 col-xl-6 col-xxl-4 my-2 mt-sm-0 mb-sm-2 ps-4 ps-sm-0">
<input asp-for="Chapter.Title" class="form-control border-primary rounded-xl" placeholder="@Html.DisplayNameFor(model => model.Chapter.Title)" />
</div>
<div class="col-12 col-sm-4 col-lg-3 col-xl-3 col-xxl-2 mb-sm-2 text-primary">
@Html.DisplayNameFor(model => model.Chapter.Order)
</div>
<div class="col-12 col-sm-8 col-lg-7 col-xl-6 col-xxl-4 my-2 mt-sm-0 mb-sm-2 ps-4 ps-sm-0">
<input asp-for="Chapter.Order" class="form-control border-primary rounded-xl" placeholder="@Html.DisplayNameFor(model => model.Chapter.Order)" />
</div>
</div>
@await Html.PartialAsync("_PropertyPartial", Model.Chapter)
@Html.HiddenFor(model=>model.Chapter.CreatedBy)
@Html.HiddenFor(model=>model.Chapter.ModifiedBy)
@Html.HiddenFor(model=>model.Chapter.CreationDate)
@Html.HiddenFor(model=>model.Chapter.ModificationDate)
@Html.HiddenFor(model=>model.Chapter.ParentId)
@await Html.PartialAsync("Status/_StatusPartial", Model.Chapter)
// this part work if I use it instead of the partial above.
@*<div class="row">
<div class="col-12 col-sm-4 col-lg-3 col-xl-3 col-xxl-2 mb-sm-2 text-primary">
@azzedinehtmlsql .DisplayName("Etat")
</div>
<div class="col-12 col-sm-8 col-lg-9 col-xxl-10 text-primary fa-xl ps-4 ps-sm-0">
<div class="row">
<div class="col-6 col-xl-3 mb-2">
<label class="form-check-label select-none">
<small>
@Html.CheckBoxFor(model => model.Chapter.IsPrivate)
<i class="fa-duotone fa-user-secret text-primary" title="@Html.DisplayNameFor(model =>model.Chapter.IsPrivate)"></i>
<i class="far fa-toggle-on text-success unchecked" title="Cliquez pour mettre au statut @Html.DisplayNameFor(model => model.Chapter.IsPrivate).ToLower()"></i>
<i class="far fa-toggle-off text-muted checked" title="Cliquez pour mettre au statut @Html.DisplayNameFor(model => model.Chapter.IsPrivate).ToLower()"></i>
<i class="fa-duotone fa-user text-primary" title="@Html.DisplayNameFor(model => model.Chapter.IsPrivate)"></i>
</small>
</label>
</div>
</div>
</div>
</div>*@
<hr class="bg-primary" />
<div class="row">
</div>
<div class="form-group mt-5 text-center">
<button type="submit" class="btn btn-primary text-white-50 rounded-pill">
<i class="fa-solid fa-save pr-1"></i>
Sauvegarder
</button>
</div>
</form>
the partial called is
@model WikiGuidIdBase
<div class="row">
<div class="col-12 col-sm-4 col-lg-3 col-xl-3 col-xxl-2 mb-sm-2 text-primary">
@Html.DisplayName("Etat")
</div>
<div class="col-12 col-sm-8 col-lg-9 col-xxl-10 text-primary fa-xl ps-4 ps-sm-0">
<div class="row">
@if (Model is TopicBase)
{
@await Html.PartialAsync("./Status/_PrivateStatusPartial", Model)
@await Html.PartialAsync("./Status/_DeletedStatusPartial", Model)
}
@if (Model is IDraft)
{
@await Html.PartialAsync("./Status/_WritingProgressStatusPartial", Model)
}
@if (Model is Topic)
{
@await Html.PartialAsync("./Status/_OnlineStatusPartial", Model)
}
</div>
</div>
</div>
and the last partial, which is not mapped when I submit the form is
@{
var type = Model.GetType().Name;
var name = string.Empty;
var id = string.Empty;
if (!string.IsNullOrWhiteSpace(type))
{
name = string.Concat(type, "_IsPrivate");
id = string.Concat(type, ".IsPrivate");
}
}
@{
@if ((bool)ViewData["WritingMode"])
{
<div class="col-6 col-xl-3 mb-2">
<label class="form-check-label select-none">
<small>
@*@Html.CheckBoxFor(model => (model as TopicBase).IsPrivate, htmlAttributes:new {@name = name, @id = id})*@
@Html.CheckBox(name,(Model as TopicBase).IsPrivate, htmlAttributes:new{@id=id})
<i class="fa-duotone fa-user-secret text-primary" title="@Html.DisplayNameFor(model => (model as TopicBase).IsPrivate)"></i>
<i class="far fa-toggle-on text-success unchecked" title="Cliquez pour mettre au statut @Html.DisplayNameFor(model => (model as TopicBase).IsPrivate).ToLower()"></i>
<i class="far fa-toggle-off text-muted checked" title="Cliquez pour mettre au statut @Html.DisplayNameFor(model => (model as TopicBase).IsPublic).ToLower()"></i>
<i class="fa-duotone fa-user text-primary" title="@Html.DisplayNameFor(model => (model as TopicBase).IsPublic)"></i>
</small>
</label>
</div>
}
else
{
<div class="col-6 col-xl-3 mb-2">
<small>
<i class="fa-duotone fa-user-secret text-primary" title="@Html.DisplayNameFor(model => (model as TopicBase).IsPrivate)"></i>
@if (!(Model as TopicBase).IsPrivate)
{
<i class="far fa-toggle-on text-success"></i>
}
else
{
<i class="far fa-toggle-off text-muted"></i>
}
<i class="fa-duotone fa-user text-primary" title="@Html.DisplayNameFor(model => (model as TopicBase).IsPublic)"></i>
</small>
</div>
}
}
model heritage is correct,
3 additional answers
Sort by: Newest
-
Laurent Guigon 276 Reputation points
2022-11-24T09:11:40.943+00:00 Sorry, I don't have a GitHub account... Git is too cryptic too me.
-
Laurent Guigon 276 Reputation points
2022-11-11T13:07:52.147+00:00 Ok, Since I need this function I wrote the code like this
<form method="post"> <div asp-validation-summary="All" class="text-danger"></div> <div class="row"> <div class="col-12 col-sm-4 col-lg-3 col-xl-3 col-xxl-2 mb-sm-2 text-primary"> @Html.DisplayNameFor(model => model.Chapter.Title) </div> <div class="col-12 col-sm-8 col-lg-7 col-xl-6 col-xxl-4 my-2 mt-sm-0 mb-sm-2 ps-4 ps-sm-0"> <input asp-for="Chapter.Title" class="form-control border-primary rounded-xl" placeholder="@Html.DisplayNameFor(model => model.Chapter.Title)" /> </div> <div class="col-12 col-sm-4 col-lg-3 col-xl-3 col-xxl-2 mb-sm-2 text-primary"> @Html.DisplayNameFor(model => model.Chapter.Order) </div> <div class="col-12 col-sm-8 col-lg-7 col-xl-6 col-xxl-4 my-2 mt-sm-0 mb-sm-2 ps-4 ps-sm-0"> <input asp-for="Chapter.Order" class="form-control border-primary rounded-xl" placeholder="@Html.DisplayNameFor(model => model.Chapter.Order)" /> </div> </div> @await Html.PartialAsync("_PropertyPartial", Model.Chapter) @Html.HiddenFor(model=>model.Chapter.CreatedBy) @Html.HiddenFor(model=>model.Chapter.ModifiedBy) @Html.HiddenFor(model=>model.Chapter.CreationDate) @Html.HiddenFor(model=>model.Chapter.ModificationDate) @Html.HiddenFor(model=>model.Chapter.ParentId) @* @await Html.PartialAsync("Status/_StatusPartial", Model.Chapter)*@ <div class="row"> <div class="col-12 col-sm-4 col-lg-3 col-xl-3 col-xxl-2 mb-sm-2 text-primary"> @Html.DisplayName("Etat") </div> <div class="col-12 col-sm-8 col-lg-9 col-xxl-10 text-primary fa-xl ps-4 ps-sm-0"> <div class="row"> <div class="col-6 col-xl-3 mb-2"> <label class="form-check-label select-none"> <small> @Html.CheckBoxFor(model => model.Chapter.IsPrivate) <i class="fa-duotone fa-user-secret text-primary" title="@Html.DisplayNameFor(model =>model.Chapter.IsPrivate)"></i> <i class="far fa-toggle-on text-success unchecked" title="Cliquez pour mettre au statut @Html.DisplayNameFor(model => model.Chapter.IsPrivate).ToLower()"></i> <i class="far fa-toggle-off text-muted checked" title="Cliquez pour mettre au statut @Html.DisplayNameFor(model => model.Chapter.IsPrivate).ToLower()"></i> <i class="fa-duotone fa-user text-primary" title="@Html.DisplayNameFor(model => model.Chapter.IsPrivate)"></i> </small> </label> </div> <div class="col-6 col-xl-3 mb-2"> <label class="form-check-label select-none"> <small> @Html.CheckBoxFor(model => model.Chapter.IsDeleted) <i class="fa-duotone fa-trash-alt text-primary" title="@Html.DisplayNameFor(model => model.Chapter.IsDeleted)"></i> <i class="far fa-toggle-on text-success unchecked" title="Cliquez pour mettre au statut @Html.DisplayNameFor(model => model.Chapter.IsDeleted).ToLower()"></i> <i class="far fa-toggle-off text-muted checked" title="Cliquez pour mettre au statut @Html.DisplayNameFor(model => model.Chapter.IsNotDeleted).ToLower()"></i> <i class="fa-duotone fa-book-open text-primary" title="@Html.DisplayNameFor(model => model.Chapter.IsNotDeleted)"></i> </small> </label> </div> <div class="col-6 col-xl-3 mb-2"> <label class="form-check-label select-none"> <small> @Html.CheckBoxFor(model => model.Chapter.IsDraft) <i class="fa-duotone fa-person-digging text-primary" title="@Html.DisplayNameFor(model => model.Chapter.IsDraft)"></i> <i class="far fa-toggle-on text-success unchecked" title="Cliquez pour mettre au statut @Html.DisplayNameFor(model => model.Chapter.IsDraft).ToLower()"></i> <i class="far fa-toggle-off text-muted checked" title="Cliquez pour mettre au statut @Html.DisplayNameFor(model => model.Chapter.IsDrafted).ToLower()"></i> <i class="fa-duotone fa-book-open text-primary" title="@Html.DisplayNameFor(model => model.Chapter.IsDrafted)"></i> </small> </label> </div> </div> </div> </div> <div class="form-group mt-5 text-center"> <button type="submit" class="btn btn-primary text-white-50 rounded-pill"> <i class="fa-solid fa-save pr-1"></i> Sauvegarder </button> </div> </form>
But it'not DRY... If some has an idea, you're welcome
-
Laurent Guigon 276 Reputation points
2022-11-11T10:05:41.69+00:00 Hi
Thx for your answers.I should pass the model instead of the property, ok.
But My Partial is a generic which accept many class from an heritage hierarchy.
Topic, Chapter, Section, Sub-section, Paragraph, Alinea : all this classes implements one or many common Interfaces, and are derivated like this :all of the final classes have the IsPrivate property, so I tried to built à single reusable partial and pass the good class as a property of my CreateModel page (inherits from PageModel)
In ths CreateModel bind item is an instance of Chapter, in another use it will be Topic, Paragraph, etc.@ AgaveJoe in this use case of the partial, ((bool)ViewData["WritingMode"]) == true becaus it's a create form. The partial is also used in read page.
@Bruce (SqlWork.com) : I don't know how to fix the problem... :`(