Reputation: 883
I have a form in a razor page with a field that has remote validation..
. . .
<div class="form-group">
<label class="control-label" asp-for="ReportViewModel.ExecSql"></label>
<textarea class="form-control" asp-for="ReportViewModel.ExecSql" ></textarea>
<span asp-validation-for="ReportViewModel.ExecSql" class="text-danger"></span>
</div>
. . .
The field in the ReportViewModel is defined as:
. . .
[Remote(action: "VerifySql", controller: "ReportService", HttpMethod = "POST")]
public string ExecSql { get; set; }
To call the action below:
[AcceptVerbs("Post")]
public IActionResult VerifySql(string ExecSql)
{
if (!Repository.VerifySql(ExecSql))
return Json("Sql is not valid (Select statements only are allowed)");
return Json(data: true);
}
The razor page cs file:
public class AddReportModel : PageModel
{
private readonly IIntegrityReportRepository _repository;
private readonly IMapper _mapper;
public AddReportModel(IIntegrityReportRepository repository, IMapper mapper)
{
_repository = repository;
_mapper = mapper;
}
[TempData]
public string ConfirmationMessage { get; set; }
[BindProperty]
public IntegrityReportViewModel ReportViewModel { get; set; }
. . .
This calls the action but ExecSql is always null. This is because when I look at the request, the form is posting.. ReportViewModel.ExecSql. Which I cannot pick up from my VerifySql action method.
I have tried adding a name to the cshtml field:
<textarea class="form-control" asp-for="ReportViewModel.ExecSql" name="ExecSql" ></textarea>
This then does bind the field and pass the value, however the client side validation does not work when it is passed back.
I can get it working by defining ANOTHER field in the cs razor page file e.g.
[Remote(action: "VerifySql", controller: "ReportService", HttpMethod = "POST")]
[BindProperty]
public string ExecSqlField { get; set; }
And then changing the cshtml to:
<div class="form-group">
<label class="control-label" asp-for="ExecSqlField"></label>
<textarea class="form-control" asp-for="ExecSqlField"></textarea>
<span asp-validation-for="ExecSqlField" class="text-danger"></span>
</div>
However this feels wrong and I am then duplicating the viewmodel which I need to share across another pages. Is there anyway to pick up the field in the original viewmodel in my action method by somehow getting the Verify action method to access ReportViewModel.ExecSql?
Many thanks for any help
Upvotes: 3
Views: 1430
Reputation: 232
Just wanted to add that @Baseless and @Breno did have the correct answer.
My property was as such:
[Display(Name = "Access Code")]
[Remote("CheckForGroup", "Users", "Admin", HttpMethod = "Post")]
public string AccessCode { get; set; }
and it only worked when I added this to my controller:
public IActionResult CheckForGroup([Bind(Prefix = "Input.AccessCode")] string accessCode)
Thank you guys!
Upvotes: 4
Reputation: 148
Afte banging heads a lot, I found a workaround. Not the most elegant but it is doing the job right now.
Just add [Bind(Prefix = "ReportViewModel.ExecSql")] to your validation method parameter.
You can revert the changes and resume using the "Model.Field" form pattern.
Upvotes: 3