'How can I use Html.EditorFor() inside a razor component?
I have as ASP.NET Core/.net 5 based project. I want to create some sort of reusable view/component for creating a datetime range selector. So anytime I want to create datetime range can just call the view/component and it'll render the view accordingly.
My initial thought want to create an Editor Template for the following model
public class DateTimeRange
{
public DateTime? From { get; set; }
public DateTime? To { get; set; }
}
Then any time I want to render a datetime range, I would then do something like this
public class MainViewModel
{
public DateTimeRange Range { get; set; }
}
and in the Main.cshtml view I would do something like this
@model MainViewModel
@Html.EditorFor(x => x.Range)
But in the above use case, there is no way to tell the editor if the range should be required or not.
So I thought about using razor components since components allow me to pass parameters to the view
The DateTime.razor component would look something like this
@if (IsRequired)
{
<div class="col p-1">
<label class="sr-only" asp-for=""></label>
<input type="text" class="form-control" asp-for="" required>
</div>
<div class="col p-1">
<label class="sr-only" asp-for=""></label>
<input type="text" class="form-control" asp-for="" required>
</div>
}
else
{
<div class="col p-1">
<label class="sr-only" asp-for=""></label>
<input type="text" class="form-control" asp-for="">
</div>
<div class="col p-1">
<label class="sr-only" asp-for=""></label>
<input type="text" class="form-control" asp-for="">
</div>
}
@code {
public bool IsRequired { get; set; }
}
Then in my main view I would do something like this
@model MainViewModel
<component type="typeof(DateTime)" param-IsRequired="true" param-Model="Model.Range" />
But, how would I use asp-for helper or any other to render the input for the From and To Properties from inside the component while not losing the integrity of the HTML-prefix?
Solution 1:[1]
I Write a simply demo to show how to use asp-for in View Component:
Models/DateTimeRange
public class DateTimeRange
{
//Add validation
[Required]
public DateTime? From { get; set; }
[Required]
public DateTime? To { get; set; }
}
Models/DateTimeRange
public class MainViewModel
{
public DateTimeRange Range { get; set; }
}
Components/RangeViewConponent.cs
public class RangeViewComponent : ViewComponent
{
public async Task<IViewComponentResult> InvokeAsync()
{
return View();
}
}
Views/shared/Components/Range/default.cshtml
@model ComponentTest.Models.MainViewModel
<form method="post" asp-controller="Home" asp-action="privacy">
<div class="col p-1">
<label class="sr-only" asp-for="@Model.Range.From"></label>
<input type="date" class="form-control" asp-for="@Model.Range.From" >
<span asp-validation-for="@Model.Range.From" class="text-danger"></span>
</div>
<div class="col p-1">
<label class="sr-only" asp-for="@Model.Range.To"></label>
<input type="date" class="form-control" asp-for="@Model.Range.To" >
<span asp-validation-for="@Model.Range.To" class="text-danger"></span>
</div>
<button type="submit">submit</button>
</form>
I use View Component in HomeController/Privacy
@{
ViewData["Title"] = "Privacy Policy";
}
<h1>@ViewData["Title"]</h1>
<p>Use this page to detail your site's privacy policy.</p>
//use View Component
@await Component.InvokeAsync("Range")
//Add validation javascript
@section Scripts{
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>
}
You can see if I don't select any date and click submit button, the error message will show and I can't submit any data
Then I select the date and click the submit button , the View Component can submit the MainViewModel successfully
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Xinran Shen |


