我们在.NET Core 3.1.5上,这是Blazor Server应用程序。
我们具有ValidationAttribute,并且需要访问外部服务来验证对象。
ValidationAttribute具有IsValid方法:
受保护的重写ValidationResult IsValid(对象值,ValidationContextvalidationContext)ValidationContext具有一个GetService方法,该方法委派给ServiceProvider的实例。不幸的是,服务提供者字段从未初始化,因此我们无法检索任何服务。
这是通过Mvc:aspnet / Mvc#6346提出(并修复)的,但是我们的Validator是通过以下两种方法之一调用的:
https://github.com/dotnet/aspnetcore/blob/master/src/Components/Forms/src/EditContextDataAnnotationsExtensions.cs#L47 https://github.com/dotnet/aspnetcore/blob/master/src/Components/Forms /src/EditContextDataAnnotationsExtensions.cs#L75后来再也不设置服务提供者了。我犹豫要打开一个错误(但可以这样做),但这对我来说似乎是错误的(或至少应该记录在案)。
任何Google搜索最终都会在此Blog帖子中结束,但是正如我刚才提到的那样,这是行不通的。
所以我们的问题是:将服务注入ValidationAttribute或更正确的方法是什么?验证需要调用外部服务的模型字段的正确方法是什么?
在statup.cs
:
services.AddTransient<IMarktTypDaten, MarktTypDaten>();
我们尝试在其中注入服务并应用验证的类。
public class MarktTypNameValidation : ValidationAttribute {
protected override ValidationResult IsValid(object value, ValidationContext validationContext) {
var service = (IMarktTypDaten) validationContext.GetRequiredService(typeof(IMarktTypDaten));
...some code...
return ValidationResult.Success;
}
}
调用时的ExceptionMessage GetRequiredService
:'No service for type 'DataAccessLibrary.Interfaces.IMarktTypDaten' has been registered.
它也发布在Github上:https : //github.com/dotnet/aspnetcore/discussions/23305
另外:我在15年左右的时间里第一次使用C#/。NET,请保持谦虚;-)
正如史蒂文(Steven)在评论部分中所建议的那样,您不应该那样做。相反,您可以按照以下代码片段中的说明进行操作,其中一部分只是用于指出您需要执行的操作的伪代码...不能按原样工作。
您可以为此重写EditContext的FieldChanged方法。
假设您有此表单,其中包含电子邮件地址的输入字段,并且您想检查此电子邮件是否已被其他用户使用...要检查输入电子邮件地址的可用性,必须对数据存储执行呼叫并验证这一点。请注意,FieldChanged方法中描述的某些操作可以移到单独的验证服务中。
<EditForm EditContext="@EditContext"
OnValidSubmit="HandleValidSubmit">
<DataAnnotationsValidator />
<div class="form-group">
<label for="name">Name: </label>
<InputText Id="name" Class="form-control" @bind-
Value="@Model.Name"></InputText>
<ValidationMessage For="@(() => Model.Name)" />
</div>
<div class="form-group">
<label for="body">Text: </label>
<InputText Id="body" Class="form-control" @bind-Value="@Model.Text"></InputText>
<ValidationMessage For="@(() => Model.Text)" />
</div>
<div class="form-group">
<label for="body">Email: </label>
<InputText Id="body" Class="form-control" @bind-Value="@Model.EmailAddress"></InputText>
<ValidationMessage For="@(() => Model.EmailAddress)" />
</div>
<p>
<button type="submit">Save</button>
</p>
</EditForm>
@code
{
private EditContext EditContext;
private Comment Model = new Comment();
ValidationMessageStore messages;
protected override void OnInitialized()
{
EditContext = new EditContext(Model);
EditContext.OnFieldChanged += EditContext_OnFieldChanged;
messages = new ValidationMessageStore(EditContext);
base.OnInitialized();
}
// Note: The OnFieldChanged event is raised for each field in the
// model. Here you should validate the email address
private void EditContext_OnFieldChanged(object sender,
FieldChangedEventArgs e)
{
// Call your database to check if the email address is
// available
// Retrieve the value of the input field for email
// Pseudocode...
var email = "[email protected]";
var exists = VerifyEmail(email);
messages.Clear();
// If exists is true, form a message about this, and add it
// to the messages object so that it is displayed in the
// ValidationMessage component for email
}
}
希望这可以帮助...
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句