I have implemented a custom validation attribute to check column uniqueness. I want to check if the provided value already exists in the database or not. Here is my code:
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true, Inherited = true)]
public class UniqueAttribute : ValidationAttribute
{
public UniqueAttribute()
{
}
public override bool RequiresValidationContext => true;
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
return ValidationResult.Success;
}
}
the validationContext in IsValid method always returns null. How it can be fixed?
CodePudding user response:
Below is an example to check if the provided value already exists in the database or not, you can refer to it. UniqueAttribute:
public class UniqueAttribute : ValidationAttribute
{
protected override ValidationResult IsValid(object value,ValidationContext validationContext)
{
var context = (MvcMovieContext)validationContext.GetService(typeof(MvcMovieContext));//change the MvcMovieContext to your DbContext
if (!context.Movie.Any(a => a.Company == value.ToString()))
{
return ValidationResult.Success;
}
return new ValidationResult("Company exists");
}
}
Movie:
public class Movie
{
[Unique]
public string Company { get; set; }
}
Create view:
@model MvcMovie.Models.Movie
@{
ViewData["Title"] = "Create";
}
<h1>Create</h1>
<h4>Movie</h4>
<hr />
<div >
<div >
<form asp-action="Create">
<div asp-validation-summary="ModelOnly" ></div>
<div >
<label asp-for="Company" ></label>
<input asp-for="Company" />
<span asp-validation-for="Company" ></span>
</div>
<div >
<input type="submit" value="Create" />
</div>
</form>
</div>
</div>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
result:
CodePudding user response:
@Quin Guo Here is my Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddApiVersioning(o =>
{
o.ReportApiVersions = true;
o.AssumeDefaultVersionWhenUnspecified = true;
o.DefaultApiVersion = new ApiVersion(1, 0);
});
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDatabaseDeveloperPageExceptionFilter();
services.AddDefaultIdentity<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = false)
.AddRoles<IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>();
services.AddIdentityServer()
.AddApiAuthorization<ApplicationUser, ApplicationDbContext>();
services.AddAuthentication()
.AddIdentityServerJwt();
services.AddScoped<IClaimsTransformation, ClaimsTransformation>();
RegisterRepository(services);
RegisterServices(services);
RegisterAutoMapper(services);
services.AddControllersWithViews()
.AddJsonOptions(opts => opts.JsonSerializerOptions.PropertyNamingPolicy = null);
services.AddRazorPages();
// In production, the Angular files will be served from this directory
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/dist";
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseMigrationsEndPoint();
}
else
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
if (!env.IsDevelopment())
{
app.UseSpaStaticFiles();
}
app.UseRouting();
app.UseAuthentication();
app.UseIdentityServer();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller}/{action=Index}/{id?}");
endpoints.MapRazorPages();
});
app.UseSpa(spa =>
{
// To learn more about options for serving an Angular SPA from ASP.NET Core,
// see https://go.microsoft.com/fwlink/?linkid=864501
spa.Options.SourcePath = "ClientApp";
if (env.IsDevelopment())
{
spa.UseAngularCliServer(npmScript: "start");
}
});
}
Model class
public class Category
{
[Unique]
public string Name { get; set; }
public string Description { get; set; }
}