Reputation: 3481
So I have complex object that should be displayed on the page. Some properties of this object should be disabled (or readonly) for users in certain access roles. However, I noticed that if I edit this <input disabled .../>
in devtools and remove disabled
property and add arbitrary text, then model binder will happily take this value and put it in form model when submitted via OnPost
action.
Here is example code:
<form method="post">
<div class="form-group col-sm-6">
<label asp-for="FormModel.FirstName" class="control-label">First Name</label>
<input asp-for="FormModel.FirstName"
disabled="disabled"
class="form-control"
/>
</div>
<div class="form-group col-sm-6">
<label asp-for="FormModel.LastName" class="control-label">Last Name</label>
<input asp-for="FormModel.LastName"
class="form-control"
/>
</div>
<input type="submit" value="Save" class="btn btn-primary" />
</form>
And the page model:
public class IndexModel : PageModel
{
private readonly MyDbMock _myDb;
[BindProperty]
public FormModel FormModel { get; set; }
public IndexModel(MyDbMock myDb)
{
_myDb = myDb;
}
public void OnGet()
{
FormModel = new FormModel
{
FirstName = _myDb.FormModel.FirstName,
LastName = _myDb.FormModel.LastName
};
}
public IActionResult OnPost()
{
_myDb.FormModel = FormModel;
return RedirectToAction(nameof(OnGet));
}
}
public class FormModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class MyDbMock
{
public FormModel FormModel { get; set; } = new FormModel
{
FirstName = "John",
LastName = "Smith"
};
}
When I open this page for the first time I get John
in the disabled input with First name
label. This is fine. Then when I click Save
my OnPost
method will get FormModel
object where FirstName
is null. This is reflected in the updated page. Can this be prevented and tell model binder just to not touch this property? Ie. leave it as John
when form is submitted and not set it to null
because of it being disabled?
The other issue I have is that an advanced user can remove disabled
attribute from the First Name
input and just submit arbitrary value. Can this also be prevented by telling model binder same thing as above? Eg. leave First Name
field as-is when it was sent in GET
request, no updates.
Here is the demo of all this:
I know I can handle this in backend code by preventing updating of the disabled fields. However I am looking some more elegant and declarative way if it exists. In my main project the form model is much complex and has objects within objects so ideally I'd like to skip adding additional logic to action handler for this.
Upvotes: 1
Views: 1524
Reputation: 18239
Try to add a hidden input to bind FormModel.FirstName
,and change the name of the disabled input,so that the value of disabled input will not be binded to FormModel.FirstName
.
<form method="post" >
<div class="form-group col-sm-6">
<label asp-for="FormModel.FirstName" class="control-label">First Name</label>
<input asp-for="FormModel.FirstName" name="FirstName"
disabled="disabled"
class="form-control" />
<input asp-for="FormModel.FirstName" hidden/>
</div>
<div class="form-group col-sm-6">
<label asp-for="FormModel.LastName" class="control-label">Last Name</label>
<input asp-for="FormModel.LastName"
class="form-control" />
</div>
<input type="submit" value="Save" class="btn btn-primary" />
</form>
Upvotes: 1