{"id":1322,"date":"2026-03-28T09:00:38","date_gmt":"2026-03-28T12:00:38","guid":{"rendered":"https:\/\/maurobernal.com.ar\/blog\/validacion-de-datos-en-net-10-con-data-annotations-guia-completa\/"},"modified":"2026-03-28T09:00:38","modified_gmt":"2026-03-28T12:00:38","slug":"validacion-de-datos-en-net-10-con-data-annotations-guia-completa","status":"publish","type":"post","link":"https:\/\/maurobernal.com.ar\/blog\/validacion-de-datos-en-net-10-con-data-annotations-guia-completa\/","title":{"rendered":"Validacion de Datos en .NET 10 con Data Annotations: Guia Completa"},"content":{"rendered":"<p>Validar los datos de entrada es una de las primeras l\u00edneas de defensa de cualquier API. En .NET, la forma m\u00e1s directa de hacerlo es con <strong>Data Annotations<\/strong>: atributos que se aplican sobre las propiedades del modelo y que ASP.NET Core eval\u00faa autom\u00e1ticamente antes de que el request llegue a tu l\u00f3gica de negocio.<\/p>\n<p>En esta primera parte repasamos en profundidad c\u00f3mo funciona Data Annotations en .NET 10, sus capacidades y sus l\u00edmites. En la <a href=\"#\">segunda parte<\/a> comparamos esta estrategia contra <strong>FluentValidation<\/strong>.<\/p>\n<h2>\u00bfQu\u00e9 son los Data Annotations?<\/h2>\n<p>Los Data Annotations son atributos del namespace <code>System.ComponentModel.DataAnnotations<\/code> que se aplican directamente sobre las propiedades de un modelo para declarar reglas de validaci\u00f3n. ASP.NET Core los eval\u00faa durante el <em>model binding<\/em> y popula autom\u00e1ticamente <code>ModelState<\/code> con los errores encontrados.<\/p>\n<pre><code class=\"language-csharp\">using System.ComponentModel.DataAnnotations;\n\npublic class CreateUserRequest\n{\n    [Required(ErrorMessage = \"El email es obligatorio.\")]\n    [EmailAddress(ErrorMessage = \"El formato del email no es v\u00e1lido.\")]\n    [MaxLength(150)]\n    public string Email { get; set; } = string.Empty;\n\n    [Required(ErrorMessage = \"El nombre es obligatorio.\")]\n    [StringLength(80, MinimumLength = 2, ErrorMessage = \"El nombre debe tener entre 2 y 80 caracteres.\")]\n    public string Name { get; set; } = string.Empty;\n\n    [Range(13, 120, ErrorMessage = \"La edad debe estar entre 13 y 120.\")]\n    public int Age { get; set; }\n}<\/code><\/pre>\n<p>Con este modelo, ASP.NET Core valida autom\u00e1ticamente cada request antes de ejecutar el action method.<\/p>\n<h2>Integraci\u00f3n autom\u00e1tica en ASP.NET Core (Controllers)<\/h2>\n<p>En una aplicaci\u00f3n MVC o Web API con controllers, la validaci\u00f3n es completamente autom\u00e1tica. Solo ten\u00e9s que verificar <code>ModelState.IsValid<\/code>:<\/p>\n<pre><code class=\"language-csharp\">[ApiController]\n[Route(\"api\/[controller]\")]\npublic class UsersController : ControllerBase\n{\n    [HttpPost]\n    public async Task&lt;IActionResult&gt; Create([FromBody] CreateUserRequest request)\n    {\n        \/\/ Si los atributos fallan, ASP.NET Core devuelve 400 autom\u00e1ticamente\n        \/\/ (gracias al atributo [ApiController])\n\n        \/\/ ... l\u00f3gica de negocio\n        return Created($\"\/api\/users\/{Guid.NewGuid()}\", request);\n    }\n}<\/code><\/pre>\n<p>El atributo <code>[ApiController]<\/code> activa la validaci\u00f3n autom\u00e1tica del <code>ModelState<\/code>: si alguna regla falla, el framework devuelve un <code>400 Bad Request<\/code> con el detalle de los errores sin que tengas que escribir c\u00f3digo adicional.<\/p>\n<h2>Integraci\u00f3n en Minimal APIs (.NET 10)<\/h2>\n<p>En Minimal APIs, la validaci\u00f3n no es autom\u00e1tica. En .NET 10 se puede activar de forma expl\u00edcita con el nuevo filtro integrado:<\/p>\n<pre><code class=\"language-csharp\">var builder = WebApplication.CreateBuilder(args);\nvar app = builder.Build();\n\napp.MapPost(\"\/users\", async (CreateUserRequest request) =>\n{\n    \/\/ La validaci\u00f3n de anotaciones se puede activar con un endpoint filter\n    return Results.Created($\"\/users\/{Guid.NewGuid()}\", request);\n})\n.AddEndpointFilter&lt;ValidationFilter&lt;CreateUserRequest&gt;&gt;();<\/code><\/pre>\n<p>O implementando un filtro gen\u00e9rico reutilizable:<\/p>\n<pre><code class=\"language-csharp\">public class ValidationFilter&lt;T&gt; : IEndpointFilter\n{\n    public async ValueTask&lt;object?&gt; InvokeAsync(EndpointFilterInvocationContext ctx, EndpointFilterDelegate next)\n    {\n        var model = ctx.Arguments.OfType&lt;T&gt;().FirstOrDefault();\n        if (model is null) return Results.BadRequest(\"Payload requerido.\");\n\n        var context = new ValidationContext(model);\n        var results = new List&lt;ValidationResult&gt;();\n\n        if (!Validator.TryValidateObject(model, context, results, validateAllProperties: true))\n        {\n            var errors = results\n                .GroupBy(r => r.MemberNames.FirstOrDefault() ?? \"General\")\n                .ToDictionary(\n                    g => g.Key,\n                    g => g.Select(r => r.ErrorMessage!).ToArray()\n                );\n\n            return Results.ValidationProblem(errors);\n        }\n\n        return await next(ctx);\n    }\n}<\/code><\/pre>\n<h2>Atributos m\u00e1s usados<\/h2>\n<table>\n<thead>\n<tr>\n<th>Atributo<\/th>\n<th>Descripci\u00f3n<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>[Required]<\/code><\/td>\n<td>El campo no puede ser null ni vac\u00edo<\/td>\n<\/tr>\n<tr>\n<td><code>[StringLength(max, MinimumLength = min)]<\/code><\/td>\n<td>Longitud de string entre m\u00edn y m\u00e1x<\/td>\n<\/tr>\n<tr>\n<td><code>[MaxLength(n)]<\/code> \/ <code>[MinLength(n)]<\/code><\/td>\n<td>Longitud m\u00e1xima o m\u00ednima<\/td>\n<\/tr>\n<tr>\n<td><code>[Range(min, max)]<\/code><\/td>\n<td>Valor num\u00e9rico dentro de un rango<\/td>\n<\/tr>\n<tr>\n<td><code>[EmailAddress]<\/code><\/td>\n<td>Formato de email v\u00e1lido<\/td>\n<\/tr>\n<tr>\n<td><code>[Url]<\/code><\/td>\n<td>Formato de URL v\u00e1lida<\/td>\n<\/tr>\n<tr>\n<td><code>[Phone]<\/code><\/td>\n<td>Formato de n\u00famero telef\u00f3nico<\/td>\n<\/tr>\n<tr>\n<td><code>[RegularExpression(pattern)]<\/code><\/td>\n<td>Validaci\u00f3n con expresi\u00f3n regular<\/td>\n<\/tr>\n<tr>\n<td><code>[Compare(\"OtherProp\")]<\/code><\/td>\n<td>Compara el valor con otra propiedad<\/td>\n<\/tr>\n<tr>\n<td><code>[CreditCard]<\/code><\/td>\n<td>N\u00famero de tarjeta de cr\u00e9dito v\u00e1lido<\/td>\n<\/tr>\n<tr>\n<td><code>[AllowedValues(...)]<\/code><\/td>\n<td>Valor dentro de un conjunto permitido (.NET 8+)<\/td>\n<\/tr>\n<tr>\n<td><code>[DeniedValues(...)]<\/code><\/td>\n<td>Valor fuera de un conjunto denegado (.NET 8+)<\/td>\n<\/tr>\n<tr>\n<td><code>[Length(min, max)]<\/code><\/td>\n<td>Longitud de colecciones o strings (.NET 8+)<\/td>\n<\/tr>\n<tr>\n<td><code>[Base64String]<\/code><\/td>\n<td>String Base64 v\u00e1lido (.NET 8+)<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2>Validaciones personalizadas<\/h2>\n<h3>Opci\u00f3n 1: IValidatableObject<\/h3>\n<p>Para l\u00f3gica que involucra m\u00faltiples propiedades del mismo modelo:<\/p>\n<pre><code class=\"language-csharp\">public class CreateUserRequest : IValidatableObject\n{\n    public string? Email { get; set; }\n    public int Age { get; set; }\n\n    public IEnumerable&lt;ValidationResult&gt; Validate(ValidationContext validationContext)\n    {\n        if (Age &lt; 18 && Email?.EndsWith(\".work\") == true)\n            yield return new ValidationResult(\n                \"Los menores no pueden registrarse con un email de trabajo.\",\n                new[] { nameof(Email) }\n            );\n    }\n}<\/code><\/pre>\n<h3>Opci\u00f3n 2: Atributo personalizado<\/h3>\n<p>Para reglas reutilizables en m\u00faltiples modelos:<\/p>\n<pre><code class=\"language-csharp\">public class NoDisposableEmailAttribute : ValidationAttribute\n{\n    private static readonly string[] _blocked = { \"test@test.com\", \"lorem@ipsum.com\" };\n\n    protected override ValidationResult? IsValid(object? value, ValidationContext context)\n    {\n        if (value is string email && _blocked.Contains(email.ToLower()))\n            return new ValidationResult(\"Us\u00e1 un email real, no uno descartable.\");\n\n        return ValidationResult.Success;\n    }\n}\n\n\/\/ Uso\n[NoDisposableEmail]\npublic string Email { get; set; } = string.Empty;<\/code><\/pre>\n<h2>Respuesta de error: ProblemDetails<\/h2>\n<p>Con <code>[ApiController]<\/code>, los errores de validaci\u00f3n se devuelven autom\u00e1ticamente como <code>ValidationProblemDetails<\/code> (RFC 7807):<\/p>\n<pre><code class=\"language-json\">{\n  \"type\": \"https:\/\/tools.ietf.org\/html\/rfc9110#section-15.5.1\",\n  \"title\": \"One or more validation errors occurred.\",\n  \"status\": 400,\n  \"errors\": {\n    \"Email\": [\"El formato del email no es v\u00e1lido.\"],\n    \"Name\": [\"El nombre es obligatorio.\"]\n  }\n}<\/code><\/pre>\n<h2>Limitaciones de Data Annotations<\/h2>\n<ul>\n<li><strong>No admiten async:<\/strong> no pod\u00e9s consultar la base de datos para verificar si un email ya existe dentro de un atributo.<\/li>\n<li><strong>La l\u00f3gica se mezcla con el modelo:<\/strong> el DTO carga con responsabilidades de validaci\u00f3n.<\/li>\n<li><strong>Dif\u00edcil de testear de forma aislada:<\/strong> los atributos no son clases independientes f\u00e1cilmente instanciables.<\/li>\n<li><strong>Reglas cruzadas son engorrosas:<\/strong> <code>IValidatableObject<\/code> funciona pero no escala bien con l\u00f3gica compleja.<\/li>\n<li><strong>Mensajes no localizables f\u00e1cilmente:<\/strong> los <code>ErrorMessage<\/code> son strings literales (aunque se pueden usar resource files).<\/li>\n<li><strong>No hay soporte para RuleSets:<\/strong> no pod\u00e9s tener distintas reglas para \u00abcrear\u00bb vs \u00abactualizar\u00bb el mismo modelo.<\/li>\n<\/ul>\n<h2>\u00bfCu\u00e1ndo usar Data Annotations?<\/h2>\n<ul>\n<li>Proyectos peque\u00f1os o medianos con reglas simples.<\/li>\n<li>Equipos que prefieren cero dependencias externas.<\/li>\n<li>Modelos con validaciones est\u00e1ticas y directas (no async, no cruzadas).<\/li>\n<li>Cuando la validaci\u00f3n vive c\u00f3modamente junto al modelo (DTOs simples).<\/li>\n<\/ul>\n<h2>Conclusi\u00f3n<\/h2>\n<p>Data Annotations es el sistema de validaci\u00f3n nativo de .NET: sin dependencias, integraci\u00f3n autom\u00e1tica con el pipeline de ASP.NET Core, y atributos suficientes para cubrir la mayor\u00eda de los casos comunes. En .NET 10, el conjunto de atributos disponibles creci\u00f3 significativamente con adiciones como <code>[AllowedValues]<\/code>, <code>[DeniedValues]<\/code>, <code>[Length]<\/code> y <code>[Base64String]<\/code>.<\/p>\n<p>Sus limitaciones aparecen cuando las reglas de validaci\u00f3n se vuelven complejas: l\u00f3gica async, m\u00faltiples propiedades correlacionadas, o la necesidad de distintas reglas para distintos contextos. Para esos escenarios, la respuesta es <strong>FluentValidation<\/strong>. Lo vemos en la <a href=\"#\">segunda parte de esta serie<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Aprende a validar datos en .NET 10 usando Data Annotations: atributos nativos, validaciones personalizadas, integracion con Minimal APIs y controllers, y cuando usar esta estrategia.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[1],"tags":[38,348,425,359,412,426,39,424,423,422],"class_list":["post-1322","post","type-post","status-publish","format-standard","hentry","category-blog","tag-net","tag-net-10","tag-api-rest","tag-asp-net-core","tag-backend","tag-buenas-practicas","tag-c","tag-dataannotations","tag-fluentvalidation","tag-validacion"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Validacion de Datos en .NET 10 con Data Annotations: Guia Completa &#183; devops Mauro Bernal<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/maurobernal.com.ar\/blog\/validacion-de-datos-en-net-10-con-data-annotations-guia-completa\/\" \/>\n<meta property=\"og:locale\" content=\"es_ES\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Validacion de Datos en .NET 10 con Data Annotations: Guia Completa &#183; devops Mauro Bernal\" \/>\n<meta property=\"og:description\" content=\"Aprende a validar datos en .NET 10 usando Data Annotations: atributos nativos, validaciones personalizadas, integracion con Minimal APIs y controllers, y cuando usar esta estrategia.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/maurobernal.com.ar\/blog\/validacion-de-datos-en-net-10-con-data-annotations-guia-completa\/\" \/>\n<meta property=\"og:site_name\" content=\"devops Mauro Bernal\" \/>\n<meta property=\"article:published_time\" content=\"2026-03-28T12:00:38+00:00\" \/>\n<meta name=\"author\" content=\"Mauro Bernal\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@_maurobernal\" \/>\n<meta name=\"twitter:site\" content=\"@_maurobernal\" \/>\n<meta name=\"twitter:label1\" content=\"Escrito por\" \/>\n\t<meta name=\"twitter:data1\" content=\"Mauro Bernal\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tiempo de lectura\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/validacion-de-datos-en-net-10-con-data-annotations-guia-completa\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/validacion-de-datos-en-net-10-con-data-annotations-guia-completa\\\/\"},\"author\":{\"name\":\"Mauro Bernal\",\"@id\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/#\\\/schema\\\/person\\\/09c4dbdfb59b20e015c703fd19713283\"},\"headline\":\"Validacion de Datos en .NET 10 con Data Annotations: Guia Completa\",\"datePublished\":\"2026-03-28T12:00:38+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/validacion-de-datos-en-net-10-con-data-annotations-guia-completa\\\/\"},\"wordCount\":645,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/#\\\/schema\\\/person\\\/09c4dbdfb59b20e015c703fd19713283\"},\"keywords\":[\".NET\",\".NET 10\",\"API REST\",\"ASP.NET Core\",\"Backend\",\"Buenas Practicas\",\"c#\",\"DataAnnotations\",\"FluentValidation\",\"Validacion\"],\"articleSection\":[\"Blog\"],\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/validacion-de-datos-en-net-10-con-data-annotations-guia-completa\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/validacion-de-datos-en-net-10-con-data-annotations-guia-completa\\\/\",\"url\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/validacion-de-datos-en-net-10-con-data-annotations-guia-completa\\\/\",\"name\":\"Validacion de Datos en .NET 10 con Data Annotations: Guia Completa &#183; devops Mauro Bernal\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/#website\"},\"datePublished\":\"2026-03-28T12:00:38+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/validacion-de-datos-en-net-10-con-data-annotations-guia-completa\\\/#breadcrumb\"},\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/validacion-de-datos-en-net-10-con-data-annotations-guia-completa\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/validacion-de-datos-en-net-10-con-data-annotations-guia-completa\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Portada\",\"item\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Validacion de Datos en .NET 10 con Data Annotations: Guia Completa\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/\",\"name\":\"devops Mauro Bernal\",\"description\":\"Cuando tu trabajo es hacer que las cosas funcionen bien...\",\"publisher\":{\"@id\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/#\\\/schema\\\/person\\\/09c4dbdfb59b20e015c703fd19713283\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"es\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/maurobernal.com.ar\\\/blog\\\/#\\\/schema\\\/person\\\/09c4dbdfb59b20e015c703fd19713283\",\"name\":\"Mauro Bernal\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\\\/\\\/i0.wp.com\\\/maurobernal.com.ar\\\/blog\\\/wp-content\\\/uploads\\\/2023\\\/07\\\/logo-maurobernal.png?fit=1740%2C1740&ssl=1\",\"url\":\"https:\\\/\\\/i0.wp.com\\\/maurobernal.com.ar\\\/blog\\\/wp-content\\\/uploads\\\/2023\\\/07\\\/logo-maurobernal.png?fit=1740%2C1740&ssl=1\",\"contentUrl\":\"https:\\\/\\\/i0.wp.com\\\/maurobernal.com.ar\\\/blog\\\/wp-content\\\/uploads\\\/2023\\\/07\\\/logo-maurobernal.png?fit=1740%2C1740&ssl=1\",\"width\":1740,\"height\":1740,\"caption\":\"Mauro Bernal\"},\"logo\":{\"@id\":\"https:\\\/\\\/i0.wp.com\\\/maurobernal.com.ar\\\/blog\\\/wp-content\\\/uploads\\\/2023\\\/07\\\/logo-maurobernal.png?fit=1740%2C1740&ssl=1\"},\"description\":\"Desarrollo de Sistemas en .Net, IT Callcenters, DBA de SQL Server, Mikrotik, Pentest y T\u00e9cnico consultor de Sistemas Bejerman\",\"sameAs\":[\"https:\\\/\\\/maurobernal.com.ar\",\"https:\\\/\\\/x.com\\\/_maurobernal\",\"https:\\\/\\\/youtube.com\\\/maurobernal\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Validacion de Datos en .NET 10 con Data Annotations: Guia Completa &#183; devops Mauro Bernal","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/maurobernal.com.ar\/blog\/validacion-de-datos-en-net-10-con-data-annotations-guia-completa\/","og_locale":"es_ES","og_type":"article","og_title":"Validacion de Datos en .NET 10 con Data Annotations: Guia Completa &#183; devops Mauro Bernal","og_description":"Aprende a validar datos en .NET 10 usando Data Annotations: atributos nativos, validaciones personalizadas, integracion con Minimal APIs y controllers, y cuando usar esta estrategia.","og_url":"https:\/\/maurobernal.com.ar\/blog\/validacion-de-datos-en-net-10-con-data-annotations-guia-completa\/","og_site_name":"devops Mauro Bernal","article_published_time":"2026-03-28T12:00:38+00:00","author":"Mauro Bernal","twitter_card":"summary_large_image","twitter_creator":"@_maurobernal","twitter_site":"@_maurobernal","twitter_misc":{"Escrito por":"Mauro Bernal","Tiempo de lectura":"5 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/maurobernal.com.ar\/blog\/validacion-de-datos-en-net-10-con-data-annotations-guia-completa\/#article","isPartOf":{"@id":"https:\/\/maurobernal.com.ar\/blog\/validacion-de-datos-en-net-10-con-data-annotations-guia-completa\/"},"author":{"name":"Mauro Bernal","@id":"https:\/\/maurobernal.com.ar\/blog\/#\/schema\/person\/09c4dbdfb59b20e015c703fd19713283"},"headline":"Validacion de Datos en .NET 10 con Data Annotations: Guia Completa","datePublished":"2026-03-28T12:00:38+00:00","mainEntityOfPage":{"@id":"https:\/\/maurobernal.com.ar\/blog\/validacion-de-datos-en-net-10-con-data-annotations-guia-completa\/"},"wordCount":645,"commentCount":0,"publisher":{"@id":"https:\/\/maurobernal.com.ar\/blog\/#\/schema\/person\/09c4dbdfb59b20e015c703fd19713283"},"keywords":[".NET",".NET 10","API REST","ASP.NET Core","Backend","Buenas Practicas","c#","DataAnnotations","FluentValidation","Validacion"],"articleSection":["Blog"],"inLanguage":"es","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/maurobernal.com.ar\/blog\/validacion-de-datos-en-net-10-con-data-annotations-guia-completa\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/maurobernal.com.ar\/blog\/validacion-de-datos-en-net-10-con-data-annotations-guia-completa\/","url":"https:\/\/maurobernal.com.ar\/blog\/validacion-de-datos-en-net-10-con-data-annotations-guia-completa\/","name":"Validacion de Datos en .NET 10 con Data Annotations: Guia Completa &#183; devops Mauro Bernal","isPartOf":{"@id":"https:\/\/maurobernal.com.ar\/blog\/#website"},"datePublished":"2026-03-28T12:00:38+00:00","breadcrumb":{"@id":"https:\/\/maurobernal.com.ar\/blog\/validacion-de-datos-en-net-10-con-data-annotations-guia-completa\/#breadcrumb"},"inLanguage":"es","potentialAction":[{"@type":"ReadAction","target":["https:\/\/maurobernal.com.ar\/blog\/validacion-de-datos-en-net-10-con-data-annotations-guia-completa\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/maurobernal.com.ar\/blog\/validacion-de-datos-en-net-10-con-data-annotations-guia-completa\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Portada","item":"https:\/\/maurobernal.com.ar\/blog\/"},{"@type":"ListItem","position":2,"name":"Validacion de Datos en .NET 10 con Data Annotations: Guia Completa"}]},{"@type":"WebSite","@id":"https:\/\/maurobernal.com.ar\/blog\/#website","url":"https:\/\/maurobernal.com.ar\/blog\/","name":"devops Mauro Bernal","description":"Cuando tu trabajo es hacer que las cosas funcionen bien...","publisher":{"@id":"https:\/\/maurobernal.com.ar\/blog\/#\/schema\/person\/09c4dbdfb59b20e015c703fd19713283"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/maurobernal.com.ar\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"es"},{"@type":["Person","Organization"],"@id":"https:\/\/maurobernal.com.ar\/blog\/#\/schema\/person\/09c4dbdfb59b20e015c703fd19713283","name":"Mauro Bernal","image":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/i0.wp.com\/maurobernal.com.ar\/blog\/wp-content\/uploads\/2023\/07\/logo-maurobernal.png?fit=1740%2C1740&ssl=1","url":"https:\/\/i0.wp.com\/maurobernal.com.ar\/blog\/wp-content\/uploads\/2023\/07\/logo-maurobernal.png?fit=1740%2C1740&ssl=1","contentUrl":"https:\/\/i0.wp.com\/maurobernal.com.ar\/blog\/wp-content\/uploads\/2023\/07\/logo-maurobernal.png?fit=1740%2C1740&ssl=1","width":1740,"height":1740,"caption":"Mauro Bernal"},"logo":{"@id":"https:\/\/i0.wp.com\/maurobernal.com.ar\/blog\/wp-content\/uploads\/2023\/07\/logo-maurobernal.png?fit=1740%2C1740&ssl=1"},"description":"Desarrollo de Sistemas en .Net, IT Callcenters, DBA de SQL Server, Mikrotik, Pentest y T\u00e9cnico consultor de Sistemas Bejerman","sameAs":["https:\/\/maurobernal.com.ar","https:\/\/x.com\/_maurobernal","https:\/\/youtube.com\/maurobernal"]}]}},"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack-related-posts":[],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/maurobernal.com.ar\/blog\/wp-json\/wp\/v2\/posts\/1322","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/maurobernal.com.ar\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/maurobernal.com.ar\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/maurobernal.com.ar\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/maurobernal.com.ar\/blog\/wp-json\/wp\/v2\/comments?post=1322"}],"version-history":[{"count":0,"href":"https:\/\/maurobernal.com.ar\/blog\/wp-json\/wp\/v2\/posts\/1322\/revisions"}],"wp:attachment":[{"href":"https:\/\/maurobernal.com.ar\/blog\/wp-json\/wp\/v2\/media?parent=1322"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/maurobernal.com.ar\/blog\/wp-json\/wp\/v2\/categories?post=1322"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/maurobernal.com.ar\/blog\/wp-json\/wp\/v2\/tags?post=1322"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}