Escolar Documentos
Profissional Documentos
Cultura Documentos
net-mvc
#asp.net-
mvc
Tabla de contenido
Acerca de 1
Observaciones 2
Versiones 2
Examples 3
Hola MVC! 3
Capítulo 2: ActionResult 6
Observaciones 6
Examples 6
Devolver un archivo 6
Devuelve un json 7
Capítulo 3: ActionResult 8
Examples 8
Ver resultado 8
PartialViewResult 8
RedirectResult 9
RedirectToRouteResult 9
ContentResult 10
JsonResult 10
Capítulo 4: ActionResult 12
Sintaxis 12
Examples 12
Métodos de acción 12
Introducción 14
Examples 14
Ver 14
Controlador 15
Validación remota 15
RequiredAttribute 17
StringLengthAttribute 17
Atributo de rango 18
Comparar atributo 19
Capítulo 6: Áreas 24
Introducción 24
Observaciones 24
Examples 24
Configurar RouteConfig.cs 24
Examples 26
Introducción 29
Examples 29
HtmlHelper.Action() 30
HtmlHelper.ActionLink() 30
@HtmlHelper.BeginForm() 30
Examples 33
Dockerfile y Nuget 33
Soporte POSTGRESQL. 33
Dockerización 34
Examples 36
Minificación 36
Introducción 38
Examples 38
Enrutamiento personalizado 38
Ruta de todo 41
Introducción 44
Parámetros 44
Observaciones 45
Examples 45
Formas de Ajax 45
Capítulo 13: Filtros de accion 46
Examples 46
Introducción 51
Sintaxis 51
Observaciones 51
Precaución 51
Examples 51
Uso básico 51
Controlador (YourController.cs) 52
Parámetros 56
Examples 56
Observaciones 57
Examples 58
Configuraciones de Ninject 58
Dependencia codificada 60
parámetro DI 60
Examples 65
Introducción 67
Examples 67
Configuración básica 67
Introducción 69
Sintaxis 69
Observaciones 69
Examples 69
Añadir comentarios 69
Sintaxis basica 71
Escapando a @ personaje 72
Plantillas de editor 73
Introducción 77
Observaciones 77
Examples 77
Atadura a objetos 78
Ajax vinculante 78
Subir archivo 81
Validación de campos de fecha manualmente con formatos dinámicos utilizando el cuaderno de 81
Examples 83
Introducción 87
Sintaxis 87
Observaciones 87
Examples 87
Desventajas 88
Introducción 90
Observaciones 90
Examples 90
Introducción 97
Examples 97
Plantilla de pantalla 97
Plantilla de editor 98
Capítulo 25: Registro de errores 101
Examples 101
Examples 105
Introducción 106
Examples 106
Introducción 109
Examples 109
Capítulo 29: Validación automática del lado del cliente a partir de atributos 112
Observaciones 112
Examples 112
Modelo 112
Global.asax.cs 114
Introducción 115
Sintaxis 115
Examples 115
Introducción 119
Sintaxis 119
Examples 119
Vista parcial a una cadena - para contenido de correo electrónico, etc. 119
Examples 122
Creditos 123
Acerca de
You can share this PDF with anyone you feel could benefit from it, downloaded the latest version
from: asp-net-mvc
It is an unofficial and free asp.net-mvc ebook created for educational purposes. All the content is
extracted from Stack Overflow Documentation, which is written by many hardworking individuals at
Stack Overflow. It is neither affiliated with Stack Overflow nor official asp.net-mvc.
The content is released under Creative Commons BY-SA, and the list of contributors to each
chapter are provided in the credits section at the end of this book. Images may be copyright of
their respective owners unless otherwise specified. All trademarks and registered trademarks are
the property of their respective company owners.
Use the content presented in this book at your own risk; it is not guaranteed to be correct nor
accurate, please send your feedback and corrections to info@zzzprojects.com
https://riptutorial.com/es/home 1
Capítulo 1: Empezando con asp.net-mvc
Observaciones
El patrón arquitectónico Modelo-Vista-Controlador (MVC) separa una aplicación en tres
componentes principales: el modelo, la vista y el controlador. El marco MVC de ASP.NET
proporciona una alternativa al patrón de formularios web de ASP.NET para crear aplicaciones
web. El marco de ASP.NET MVC es un marco de presentación ligero y altamente comprobable
que (al igual que con las aplicaciones basadas en Web Forms) se integra con las características
existentes de ASP.NET, como las páginas maestras y la autenticación basada en membresía. El
marco MVC se define en el ensamblado System.Web.Mvc.
• Modelos Los objetos modelo son las partes de la aplicación que implementan la lógica para
el dominio de datos de la aplicación. A menudo, los objetos del modelo recuperan y
almacenan el estado del modelo en una base de datos. Por ejemplo, un objeto Producto
podría recuperar información de una base de datos, operar en ella y luego escribir
información actualizada en una tabla de Productos en una base de datos de SQL Server. En
aplicaciones pequeñas, el modelo es a menudo una separación conceptual en lugar de una
física. Por ejemplo, si la aplicación solo lee un conjunto de datos y lo envía a la vista, la
aplicación no tiene una capa de modelo físico y clases asociadas. En ese caso, el conjunto
de datos asume el rol de un objeto modelo.
• Vistas . Las vistas son los componentes que muestran la interfaz de usuario (UI) de la
aplicación. Normalmente, esta IU se crea a partir de los datos del modelo. Un ejemplo sería
una vista de edición de una tabla de Productos que muestra cuadros de texto, listas
desplegables y cuadros de verificación según el estado actual de un objeto Producto.
• Controladores Los controladores son los componentes que controlan la interacción del
usuario, trabajan con el modelo y, en última instancia, seleccionan una vista para
representar que muestra la interfaz de usuario. En una aplicación MVC, la vista solo
muestra información; El controlador maneja y responde a la entrada e interacción del
usuario. Por ejemplo, el controlador maneja los valores de cadena de consulta y pasa estos
valores al modelo, que a su vez podría usar estos valores para consultar la base de datos.
Versiones
https://riptutorial.com/es/home 2
Versión Versión .NET Fecha de lanzamiento
Examples
Hola MVC!
Modelo : los modelos reflejan los objetos de su negocio y son un medio para pasar datos entre
controladores y vistas.
Vista : las vistas son las páginas que representan y muestran los datos del modelo al usuario. Las
vistas de ASP.NET MVC se escriben normalmente utilizando la sintaxis de Razor.
Controlador : los controladores manejan las solicitudes HTTP entrantes de un cliente y, por lo
general, devuelven uno o más modelos a una vista apropiada.
https://riptutorial.com/es/home 3
creación de aplicaciones que son ligeras y dan control total a los desarrolladores.
Vamos a crear una aplicación MVC simple que muestra detalles personales. Crea un nuevo
proyecto MVC usando Visual Studio. Agregue un nuevo modelo llamado Person a la carpeta de
modelos como sigue:
<div>
<h5>Details:</h5>
<div>
@Html.LabelFor(m => m.Surname)
@Html.DisplayFor(m => m.Surname)
</div>
<div>
@Html.LabelFor(m => m.FirstName)
@Html.DisplayFor(m => m.FirstName)
</div>
<div>
@Html.LabelFor(m => m.Patronymic)
@Html.DisplayFor(m => m.Patronymic)
https://riptutorial.com/es/home 4
</div>
<div>
@Html.LabelFor(m => m.BirthDate)
@Html.DisplayFor(m => m.BirthDate)
</div>
</div>
https://riptutorial.com/es/home 5
Capítulo 2: ActionResult
Observaciones
Un ActionResult es el mejor punto de vista como un punto final web en MVC. Se puede acceder al
método Ever ActionResult escribiendo la dirección web adecuada según lo configurado por su
motor de enrutamiento.
Examples
Regresar una página de visualización
Este ActionResult devuelve una página de vista de Razor. Bajo la plantilla de enrutamiento
estándar, este método ActionResult se alcanzaría en http: // localhost / about / me
Devolver un archivo
El tipo MIME se puede configurar automáticamente según el tipo de archivo usando el método
GetMimeMapping , o se puede definir manualmente en el formato adecuado, por ejemplo, "texto /
plano".
Como FileContentResult requiere que se FileContentResult una matriz de bytes como una
secuencia de archivos, System.IO.File.ReadAllBytes se puede usar para leer el contenido de los
archivos como una matriz de bytes antes de enviar el archivo solicitado.
https://riptutorial.com/es/home 6
Devuelve un json
https://riptutorial.com/es/home 7
Capítulo 3: ActionResult
Examples
Ver resultado
Los métodos de acción generalmente devuelven un resultado que se conoce como un resultado
de acción. La clase ActionResult es la clase base para todos los resultados de acción. El
ActionInvoker decide qué tipo de resultado de acción devolver según la tarea que realiza el
método de acción.
Es posible ser explícito sobre qué tipo devolver, pero generalmente no es necesario.
PartialViewResult
// Renders a partial view, which defines a section of a view that can be rendered inside
another view.
return PartialView("_foodTable", foodVms);;
}
Los métodos de acción generalmente devuelven un resultado que se conoce como un resultado
de acción. La clase ActionResult es la clase base para todos los resultados de acción. El
ActionInvoker decide qué tipo de resultado de acción devolver según la tarea que realiza el
método de acción.
Es posible ser explícito sobre qué tipo devolver, pero generalmente no es necesario.
// Renders a partial view, which defines a section of a view that can be rendered inside
another view.
https://riptutorial.com/es/home 8
return PartialView("_foodTable", foodVms);
}
RedirectResult
Los métodos de acción generalmente devuelven un resultado que se conoce como un resultado
de acción. La clase ActionResult es la clase base para todos los resultados de acción. El
ActionInvoker decide qué tipo de resultado de acción devolver según la tarea que realiza el
método de acción.
Es posible ser explícito sobre qué tipo devolver, pero generalmente no es necesario.
RedirectToRouteResult
Los métodos de acción generalmente devuelven un resultado que se conoce como un resultado
de acción. La clase ActionResult es la clase base para todos los resultados de acción. El
ActionInvoker decide qué tipo de resultado de acción devolver según la tarea que realiza el
método de acción.
Es posible ser explícito sobre qué tipo devolver, pero generalmente no es necesario.
En caso de que desee redirigir a otra acción con un parámetro, puede usar la sobrecarga
RedirectToAction :
https://riptutorial.com/es/home 9
}
.....................
.....................
.....................
return RedirectToAction("SomeActionWithParameterFromThisController", new { parameterName =
parameter });
ContentResult
Los métodos de acción generalmente devuelven un resultado que se conoce como un resultado
de acción. La clase ActionResult es la clase base para todos los resultados de acción. El
ActionInvoker decide qué tipo de resultado de acción devolver según la tarea que realiza el
método de acción.
Es posible ser explícito sobre qué tipo devolver, pero generalmente no es necesario.
Puede saber más sobre esto aquí: Asp.Net Mvc: ContentResult vs. string
JsonResult
Los métodos de acción generalmente devuelven un resultado que se conoce como un resultado
de acción. La clase ActionResult es la clase base para todos los resultados de acción. El
ActionInvoker decide qué tipo de resultado de acción devolver según la tarea que realiza el
método de acción.
Es posible ser explícito sobre qué tipo devolver, pero generalmente no es necesario.
https://riptutorial.com/es/home 10
return Json(result, JsonRequestBehavior.AllowGet);
}
https://riptutorial.com/es/home 11
Capítulo 4: ActionResult
Sintaxis
• // El método ActionResult devuelve una instancia que deriva de ActionResult. Puede crear
un método de acción que puede devolver cualquier instancia que esté ajustada en el tipo de
ActionResult apropiado.
• Vista parcial(); // PartialViewResult presenta una vista parcial, que se puede utilizar como
parte de otra vista.
• JavaScript (); // JavaScriptResult devuelve un script que puede ejecutarse en el lado del
cliente.
Examples
Métodos de acción
https://riptutorial.com/es/home 12
ViewData["ExampleData"] = "Hello world!";
return View();
}
}
Si hubiera otro valor en la URL como: / Example / ProcessInput / 2, las reglas de enrutamiento
amenazarán el último número como un parámetro pasado a la acción ProcessInput del
controlador Ejemplo.
https://riptutorial.com/es/home 13
Capítulo 5: Anotaciones de datos
Introducción
Podemos agregar validaciones a nuestra aplicación al agregar Anotaciones de datos a nuestras
clases modelo. Las anotaciones de datos nos permiten describir las reglas que queremos que se
apliquen a las propiedades de nuestro modelo, y ASP.NET MVC se encargará de hacerlas
cumplir y mostrar los mensajes apropiados a los usuarios.
Examples
Atributos básicos de validación utilizados en ViewModel
Modelo
using System.ComponentModel.DataAnnotations;
[Editable(false)]
public string Address{ get; set; }
}
Ver
@using (Html.BeginForm("Index","Home") {
https://riptutorial.com/es/home 14
@Html.TextBoxFor(model => model.Age)
@Html.ValidationMessageFor(model => model.Age)
Controlador
Validación remota
RemoteAttribute funciona al realizar una llamada AJAX desde el cliente a una acción del
controlador con el valor del campo que se está validando. La acción del controlador luego
devuelve una respuesta JsonResult indica el éxito o el fracaso de la validación. Devolviendo true
de su acción indica que la validación pasó. Cualquier otro valor indica falla. Si devuelve false , se
utiliza el mensaje de error especificado en el atributo. Si devuelve algo más, como una cadena o
incluso un entero, se mostrará como el mensaje de error. A menos que necesite que su mensaje
de error sea dinámico, tiene sentido devolver verdadero o falso y dejar que el validador use el
mensaje de error especificado en el atributo.
https://riptutorial.com/es/home 15
ViewModel
Controlador
[HttpPost]
public JsonResult IsEmailAvailable(string Email)
{
// Logic to check whether email is already registered or Not.
var emailExists = IsEmailRegistered();
return Json(!emailExists);
}
Puede pasar propiedades adicionales del modelo al método del controlador utilizando la
propiedad AdditionalFields de RemoteAttribute . Un escenario típico sería pasar la propiedad de ID
del modelo en forma de 'Editar', de modo que la lógica del controlador pueda ignorar los valores
del registro existente.
Modelo
Controlador
[HttpPost]
public ActionResult Validate(string email, int? id)
{
if (id.HasValue)
{
return Json(!db.Users.Any(x => x.Email == email && x.ID != id);
}
else
{
return Json(!db.Users.Any(x => x.Email == email);
}
}
Nota adicional
https://riptutorial.com/es/home 16
El mensaje de error predeterminado es comprensiblemente vago, por lo que siempre recuerde
anular el mensaje de error predeterminado cuando use el RemoteAttribute .
RequiredAttribute
El atributo Required especifica que una propiedad es requerida. Se puede especificar un mensaje
de error al usar la propiedad ErrorMessage en el atributo.
using System.ComponentModel.DataAnnotations;
[Required(ErrorMessageResourceName = "ProductDescriptionRequired",
ErrorMessageResourceType = typeof(ResourceClass))]
public string Description { get; set; }
}
StringLengthAttribute
using System.ComponentModel.DataAnnotations;
https://riptutorial.com/es/home 17
public class User
{
// set the maximum
[StringLength(20, ErrorMessage = "The username cannot exceed 20 characters. ")]
public string Username { get; set; }
[StringLength(MinimumLength = 3,
MaximumLength = 16,
ErrorMessageResourceName = "StringLength",
ErrorMessageResourceType = typeof(ResoucesKeys))]
public string Password { get; set; }
}
Atributo de rango
El atributo Range puede decorar cualquier propiedad o campo público y especifica un rango en el
que un campo numérico debe estar entre para ser considerado válido.
[Range(minimumValue, maximumValue)]
public int Property { get; set; }
Además, acepta una propiedad opcional ErrorMessage que se puede usar para configurar el
mensaje recibido por el usuario cuando se ingresan datos no válidos:
Ejemplo
https://riptutorial.com/es/home 18
[RegularExpression(validationExpression)]
public string Property { get; set; }
Además, acepta una propiedad opcional ErrorMessage que se puede usar para configurar el
mensaje recibido por el usuario cuando se ingresan datos no válidos:
Ejemplo (s)
Comparar atributo
Para usar el atributo Compare incluya using para el siguiente espacio de nombres:
using System.ComponentModel.DataAnnotations;
[Compare("Email", ErrorMessage = "The Email and Confirm Email fields do not match.")]
public string ConfirmEmail { get; set; }
}
Cuando se valida este modelo, si Email y ConfirmEmail tienen valores diferentes, la validación
fallará.
Al igual que con todos los atributos de validación, es posible usar mensajes de error de archivos
de recursos. En este ejemplo, el mensaje de error se cargará desde los recursos del archivo de
Resources , el nombre del recurso es CompareValidationMessage :
https://riptutorial.com/es/home 19
["Email", ErrorMessageResourceType = typeof(Resources), ErrorMessageResourceName =
"CompareValidationMessage")]
public string ConfirmEmail { get; set; }
}
Para evitar utilizar la cadena para el valor de la propiedad, en C # 6+ puede usar la palabra clave
nameof :
Puede utilizar marcadores de posición en sus mensajes de error. El marcador de posición {0} se
reemplaza con el nombre de visualización de la propiedad actual y {1} se reemplaza con el
nombre de visualización de la propiedad relacionada:
Cuando se trata de validar algunas reglas que no son validación de datos genéricos, por ejemplo,
asegurarse de que se requiere un campo o algún rango de valores, pero que son específicos para
su lógica de negocios, puede crear su propio Validador personalizado . Para crear un atributo
de validación personalizado, solo necesita inherit clase ValidationAttribute y override su método
IsValid . El método IsValid toma dos parámetros, el primero es un object denominado como value
y el segundo es un ValidationContext object llamado validationContext . Value refiere al valor real
del campo que va a validar su validador personalizado.
https://riptutorial.com/es/home 20
public class MyCustomValidator : ValidationAttribute
{
private static string myEmail= "admin@dotnetfiddle.net";
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
//make sure the namespace is equal to the other partial class ItemRequest
namespace MvcApplication1.Models
{
[MetadataType(typeof(ItemRequestMetaData))]
public partial class ItemRequest
{
}
https://riptutorial.com/es/home 21
public int RequestId {get;set;}
//...
}
}
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace YourApplication.Models
{
public interface IEntityMetadata
{
[Required]
Int32 Id { get; set; }
}
[MetadataType(typeof(IEntityMetadata))]
public partial class Entity : IEntityMetadata
{
/* Id property has already existed in the mapped class */
}
}
[MetadataType(typeof(RoleMetaData))]
public partial class ROLE
{
}
[Display(Name = "Username")]
public string ROLE_USERNAME { get; set; }
}
Este código fue generado a partir de una plantilla. Los cambios manuales en este
archivo pueden causar un comportamiento inesperado en su aplicación. Los cambios
manuales en este archivo se sobrescribirán si el código se regenera
https://riptutorial.com/es/home 22
de-datos
https://riptutorial.com/es/home 23
Capítulo 6: Áreas
Introducción
¿Qué es el área?
Un área es una unidad más pequeña en la aplicación MVC que se utiliza como una forma de
separar una gran cantidad de módulos de aplicaciones en grupos funcionales. Una aplicación
puede contener múltiples áreas que se almacenan en la carpeta Áreas.
Cada área puede contener diferentes modelos, controladores y vistas según los requisitos. Para
usar un área, es necesario registrar el nombre del área en RouteConfig y definir el prefijo de la ruta.
Observaciones
Si quieres ir a esta área a través de tu controlador predeterminado
return RedirectToAction("Index","Home",new{area="areaname"});
Examples
Crear una nueva área
Haga clic derecho en la carpeta / nombre de su proyecto y cree un área nueva y asígnele un
nombre.
En la aplicación mvc internet / empty / basic se creará una carpeta con el nombre del área, que
contendrá tres carpetas diferentes llamadas controlador, modelo y vistas y un archivo de clase
llamado
Configurar RouteConfig.cs
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional
},
namespaces:new []{"nameofyourproject.Controllers"}// add this line ;
);
https://riptutorial.com/es/home 24
maproute
context.MapRoute(
"nameofarea_default",
"nameofarea/{controller}/{action}/{id}", // url shown will be like this in
browser
new {controller="Home", action = "Index", id = UrlParameter.Optional }
);
https://riptutorial.com/es/home 25
Capítulo 7: Asp.net mvc enviar correo
Examples
Formulario de contacto en Asp MVC
1. Modelo:
2. Controlador:
3. Web.Config:
<system.net>
<mailSettings>
https://riptutorial.com/es/home 26
<smtp from="you@outlook.com">
<network host="smtp-mail.outlook.com"
port="587"
userName="you@outlook.com"
password="password"
enableSsl="true" />
</smtp>
</mailSettings>
</system.net>
4. Ver:
Contact.cshtml
@model ContectModel
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<h4>Send your comments.</h4>
<hr />
<div class="form-group">
@Html.LabelFor(m => m.SenderName, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.TextBoxFor(m => m.SenderName, new { @class = "form-control" })
@Html.ValidationMessageFor(m => m.SenderName)
</div>
</div>
<div class="form-group">
@Html.LabelFor(m => m.SenderEmail, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.TextBoxFor(m => m.SenderEmail, new { @class = "form-control" })
@Html.ValidationMessageFor(m => m.SenderEmail)
</div>
</div>
<div class="form-group">
@Html.LabelFor(m => m.Message, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.TextAreaFor(m => m.Message, new { @class = "form-control" })
@Html.ValidationMessageFor(m => m.Message)
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" class="btn btn-default" value="Send" />
</div>
</div>
}
SuccessMessage.cshtml
De esta manera, puede ser muy útil, pero algunas personas (como yo) tienen un código de
repetición, y como usted nos muestra, significa que necesito crear un controlador de contacto con
https://riptutorial.com/es/home 27
el mismo código en cada proyecto que tenemos, por lo que , Creo que esto puede ser útil también
(ConfigurationManager.AppSettings["MailPort"]))
{
Credentials = new
NetworkCredential(ConfigurationManager.AppSettings["MailSender"],
ConfigurationManager.AppSettings["MailSenderPassword"]),
EnableSsl = Ssl
};
Como se ve, se leerá desde el webconfig, así que necesitamos configurarlo, esta configuración es
para Gmail, pero cada host tiene su propia configuración.
<appSettings>
<add key="webpages:Version" value="3.0.0.0" />
<add key="webpages:Enabled" value="false" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
<add key="AdminUser" value="sgrysoft@gmail.com" />
<add key="AdminPassWord" value="123456789" />
<add key="SMTPName" value="smtp.gmail.com" />
<add key="SMTPPort" value="587" />
</appSettings>
https://riptutorial.com/es/home 28
Capítulo 8: Ayudantes html
Introducción
Los ayudantes de HTML son métodos utilizados para representar elementos HTML en una vista.
Son parte del espacio de nombres System.Web.Mvc.HtmlHelper .
Ayudantes HTML estándar : se utilizan para representar elementos HTML normales, por
ejemplo, Html.TextBox() .
Ayudantes HTML personalizados : el usuario puede crear un método auxiliar personalizado que
devuelve MvcHtmlString .
Examples
Ayudante HTML personalizado - Nombre para mostrar
/// <summary>
/// Gets displayName from DataAnnotations attribute
/// </summary>
/// <typeparam name="TModel"></typeparam>
/// <typeparam name="TProperty"></typeparam>
/// <param name="htmlHelper"></param>
/// <param name="expression"></param>
/// <returns></returns>
public static MvcHtmlString GetDisplayName<TModel, TProperty>(this HtmlHelper<TModel>
htmlHelper, Expression<Func<TModel, TProperty>> expression)
{
var metaData = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
var value = metaData.DisplayName ?? (metaData.PropertyName ??
ExpressionHelper.GetExpressionText(expression));
return MvcHtmlString.Create(value);
}
/// <summary>
/// Creates simple button
/// </summary>
/// <param name="poHelper"></param>
/// <param name="psValue"></param>
/// <returns></returns>
public static MvcHtmlString SubmitButton(this HtmlHelper poHelper, string psValue)
{
return new MvcHtmlString(string.Format("<input type=\"submit\" value=\"{0}\">", psValue));
https://riptutorial.com/es/home 29
}
HtmlHelper.Action()
• @Html.Action(actionName: "Index")
salida: el HTML representado por un método de acción denominado Index()
HtmlHelper.ActionLink()
• @Html.ActionLink()
salida: <a href=""></a>
@HtmlHelper.BeginForm()
Html.TextBox ()
https://riptutorial.com/es/home 30
• @Html.TextBox("Name", null, new { @class = "form-control" })
salida: <inputclass="form-control" id="Name"name="Name"type="text"value=""/>
• @Html.TextBox("Name", "Stack Overflow", new { @class = "form-control" })
salida: <input class="form-control" id="Name"name="Name"type="text" value="Stack Overflow"/>
Html.TextArea ()
Html.Label ()
• @Html.Label("Name","FirstName")
output: <labelfor="Name"> FirstName </label>
• @Html.Label("Name", "FirstName", new { @class = "NameClass" })
output: <label for="Name" class="NameClass">FirstName</label>
Html.Hidden ()
• @Html.Hidden("Name", "Value")
salida: <input id="Name" name="Name" type="hidden" value="Value" />
Html.CheckBox ()
• @Html.CheckBox("isStudent", true)
salida: <input checked="checked" id="isStudent" name="isStudent" type="checkbox"
value="true" />
Html.Password ()
• @Html.Password("StudentPassword")
salida: <input id="StudentPassword" name="StudentPassword" type="password" value="" />
https://riptutorial.com/es/home 31
MvcHtmlString radioButton = self.RadioButtonFor(expression, value, new { id = idAttr
});
MvcHtmlString label = self.Label(idAttr, labelText);
Ejemplo:
https://riptutorial.com/es/home 32
Capítulo 9: Dockerización de la aplicación
ASP.NET
Examples
Dockerfile y Nuget
FROM microsoft/dotnet:latest
COPY . /app
WORKDIR /app
EXPOSE 5000/tcp
Soporte POSTGRESQL.
https://riptutorial.com/es/home 33
"Data": {
"DefaultConnection": {
"ConnectionString":
"Host=localhost;Username=postgres;Password=******;Database=postgres;Port=5432;Pooling=true;"
}
},
Dockerización
Instalando DOTNET
Ubuntu 16.04
CORTESÍA: https://www.microsoft.com/net/core#ubuntu
POR PUERTO:
EXPOSE 5000/tcp
https://riptutorial.com/es/home 34
Para visitar el sitio:
$ ifconfig
eth0 : ***.***.**
server-ip-address
http://server-ip-address:8195
$ sudo docker ps
https://riptutorial.com/es/home 35
Capítulo 10: Empaquetado y Minificación
Examples
Minificación
La minificación se utiliza para reducir el tamaño de los archivos CSS y Javascript para acelerar
los tiempos de descarga. Este proceso se realiza mediante la eliminación de todos los espacios
en blanco, comentarios y cualquier otro contenido no esencial de los archivos.
using System.Web.Optimization;
// Use the development version of Modernizr to develop with and learn from. Then, when
you're
// ready for production, use the build tool at http://modernizr.com to pick only the tests
you need.
bundles.Add(new ScriptBundle("~/bundles/modernizr").Include(
https://riptutorial.com/es/home 36
"~/Scripts/modernizr-*"));
bundles.Add(new StyleBundle("~/Content/css").Include("~/Content/site.css"));
bundles.Add(new StyleBundle("~/Content/themes/base/css").Include(
"~/Content/themes/base/jquery.ui.core.css",
"~/Content/themes/base/jquery.ui.resizable.css",
}
}
Los paquetes se registran en el archivo Global.asax dentro del método Application_Start ():
using System.Web.Optimization;
@using System.Web.Optimization
@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/modernizr")
@Styles.Render("~/Content/css")
@Styles.Render("~/Content/themes/base/css")
Tenga en cuenta que la agrupación no se produce cuando está en modo de desarrollo (donde el
elemento de compilación en el archivo Web.config se establece en debug = "true"). En su lugar,
las declaraciones de Render en sus Vistas incluirán cada archivo individual en un formato no
agrupado, no minificado, para facilitar la depuración.
Una vez que la aplicación está en modo de producción (donde el elemento de compilación en el
archivo Web.config se establece en debug = "false"), se realizará la agrupación.
Esto puede llevar a complicaciones para los scripts que hacen referencia a rutas relativas de otros
archivos, como las referencias a los archivos de iconos de Twitter Bootstrap. Esto se puede
abordar utilizando la clase CssRewriteUrlTransform de System.Web.Optimization:
bundles.Add(new StyleBundle("~/bundles/css").Include(
"~/Content/css/*.css", new CssRewriteUrlTransform()));
La clase CssRewriteUrlTransform reescribirá las URL relativas dentro de los archivos agrupados
en rutas absolutas, de modo que las referencias permanecerán intactas después de que la
referencia de llamada se mueva a la ubicación del paquete (p. Ej., Utilizando el código anterior,
pasando de "~ / Content / css / bootstrap.css "a" ~ / bundles / css / bootstrap.css ").
https://riptutorial.com/es/home 37
Capítulo 11: Enrutamiento
Introducción
El enrutamiento es cómo ASP.NET MVC hace coincidir un URI con una acción. El módulo de
enrutamiento es responsable de asignar las solicitudes entrantes del navegador a las acciones
particulares del controlador MVC.
Examples
Enrutamiento personalizado
Para definir rutas personalizadas, tenga en cuenta que el orden de las rutas que agrega a la tabla
de rutas es importante.
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // Route pattern
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Default
values for defined parameters above
);
}
https://riptutorial.com/es/home 38
controller y action nombres de action están reservados. Por defecto, MVC asigna {controller}
parte de la URL a la <controller>Controller y luego busca un método con el nombre <action> sin
agregar ningún sufijo.
Aunque puede ser tentador crear una familia de rutas utilizando la plantilla
{controller}/{action}/{parameter} al hacer esto usted revela la estructura de su aplicación y hace
que las URL sean algo frágiles porque cambiar el nombre del controlador cambia la configuración.
Ruta y rompe los enlaces guardados por el usuario.
routes.MapRoute(
"CustomRoute", // Route name
"Custom/Index/{id}", // Route pattern
new { controller = "Custom", action = nameof(CustomController.Index), id =
UrlParameter.Optional }
);
(no puede usar el nameof operador para el nombre del controlador, ya que tendrá un sufijo
adicional Controller ) que se debe omitir al configurar el nombre del controlador en la ruta.
El usuario puede agregar una ruta personalizada, asignando una URL a una acción específica en
un controlador. Esto se utiliza para propósitos de optimización de motores de búsqueda y hace
que las URL sean legibles.
routes.MapRoute(
name: "AboutUsAspx", // Route name
url: "AboutUs.aspx", // URL with parameters
defaults: new { controller = "Home", action = "AboutUs", id = UrlParameter.Optional } //
Parameter defaults
);
Junto con la forma clásica de definición de ruta, MVC WEB API 2 y luego MVC 5 introdujeron el
Attribute routing :
// This enables attribute routing and must go before other routes are added to the
routing table.
// This makes attribute routes have higher priority
routes.MapMvcAttributeRoutes();
}
}
https://riptutorial.com/es/home 39
Para rutas con el mismo prefijo dentro de un controlador, puede establecer un prefijo común para
todos los métodos de acción dentro del controlador utilizando el atributo RoutePrefix .
[RoutePrefix("Custom")]
public class CustomController : Controller
{
[Route("Index")]
public ActionResult Index()
{
...
}
}
RoutePrefix es opcional y define la parte de la URL que tiene el prefijo de todas las acciones del
controlador.
Si tiene varias rutas, puede establecer una ruta predeterminada al capturar la acción como
parámetro y luego aplicarla a todo el controlador, a menos que se defina el atributo de Route
específico en ciertos métodos de acción que anulan la ruta predeterminada.
[RoutePrefix("Custom")]
[Route("{action=index}")]
public class CustomController : Controller
{
public ActionResult Index()
{
...
}
Cada aplicación tiene una tabla de ruta donde almacena el patrón de ruta e información sobre
dónde dirigir la solicitud. Así que cuando creas tu aplicación mvc, hay una ruta predeterminada ya
registrada en la tabla de enrutamiento. Puedes ver eso en la clase RouteConfig.cs .
Puedes ver que la entrada tiene un nombre y una plantilla. La plantilla es el patrón de ruta que
https://riptutorial.com/es/home 40
debe verificarse cuando llega una solicitud. La plantilla predeterminada tiene Home como el valor
del segmento url del controlador y el Index como el valor del segmento de acción. Eso significa
que, si no pasa explícitamente un nombre y una acción del controlador en su solicitud, utilizará
estos valores predeterminados. Esta es la razón por la que obtiene el mismo resultado cuando
accede a su yourSite/Home/Index y su yourSite
Es posible que haya notado que tenemos un parámetro llamado id como el último segmento de
nuestro patrón de ruta. Pero en los valores por defecto, especificamos que es opcional. Esa es la
razón por la que no tuvimos que especificar el valor de id int url que intentamos.
Ahora pon un punto de vista visual de estudio en este método. Ejecute su proyecto y acceda a su
yourSite/Home/Index/999 en su navegador. Se alcanzará el punto de interrupción y debería poder
ver que el valor 999 ahora está disponible en el parámetro id .
Digamos que nos gustaría configurarlo para que se llame al mismo método de acción para un
patrón de ruta diferente. Podemos hacerlo agregando una nueva definición de ruta a la tabla de
rutas.
La nueva definición que agregué tiene un patrón Important/{id} donde id es nuevamente opcional.
Eso significa que cuando solicite su yourSiteName\Important o su yourSiteName\Important\888 , se
enviará a la acción del Índice de HomeController.
El orden de registro de ruta es importante. Siempre debe registrar los patrones de ruta específicos
antes de la ruta genérica predeterminada.
Ruta de todo
https://riptutorial.com/es/home 41
Supongamos que queremos tener una ruta que permita un número ilimitado de segmentos así:
Tendríamos que agregar una ruta, normalmente al final de la tabla de rutas, ya que esto
probablemente detectaría todas las solicitudes, de este modo:
routes.MapRoute("Final", "Route/{*segments}",
new { controller = "Product", action = "View" });
public void ActionResult View(string[] segments /* <- the name of the parameter must match the
name of the route parameter */)
{
// use the segments to obtain information about the product or category and produce data
to the user
// ...
}
Es una buena práctica codificar el estado de la aplicación de página única (SPA) en url:
my-app.com/admin-spa/users/edit/id123
En este caso, el servidor solo devuelve SPA y luego se inicializa de acuerdo con la ruta. Este
enfoque es más flexible, ya que no depende del módulo url-rewrite .
https://riptutorial.com/es/home 42
Para usar el enrutamiento de atributos en áreas, se requieren áreas de registro y las
[RouteArea(...)] .
En RouteConfig.cs :
https://riptutorial.com/es/home 43
Capítulo 12: Extensiones Ajax MVC
Introducción
Esto documenta el uso de la biblioteca System.Web.Mvc.Ajax .
Parámetros
https://riptutorial.com/es/home 44
Opciones de AJAX Descripción
Observaciones
El paquete Jquery.Unobtrusive-Ajax es obligatorio en el proyecto. Los archivos javascript
correspondientes deben incluirse en un paquete ( jquery.unobtrusive-ajax.js o
jquery.unobtrusive-ajax.min.js ). Finalmente, debe activarse también en el archivo web.config :
<appSettings>
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>
Las acciones invocadas ( SomeAction en los ejemplos) deben devolver un Json o PartialView .
Examples
Ajax Action Link
Formas de Ajax
https://riptutorial.com/es/home 45
Capítulo 13: Filtros de accion
Examples
Un filtro de acción de registro.
Por lo general, los procesos de autenticación y autorización se realizan mediante cookies y token
compatibles en .net MVC. Pero si decide hacerlo usted mismo con Session , puede usar la lógica
siguiente para las solicitudes de página y las solicitudes de ajax.
/// user is logged in (the "loggedIn" should be set in Login action upon a successful
login request)
if ( session["loggedIn"] != null && (bool)session["loggedIn"] )
https://riptutorial.com/es/home 46
return;
/// we set a field 'IsAjaxRequest' in ViewBag according to the actual request type
filterContext.Controller.ViewBag.IsAjaxRequest =
filterContext.HttpContext.Request.IsAjaxRequest();
}
}
1. Global
2. Controlador
3. Acción
Colocar un filtro global significa que se ejecutará en las solicitudes a cualquier ruta. La colocación
de uno en un controlador hace que se ejecute en las solicitudes de cualquier acción en ese
controlador. Colocar uno en una acción significa que se ejecuta con la acción.
https://riptutorial.com/es/home 47
}
Podemos agregarlo a nivel global agregándolo a la colección de filtro global. Con la configuración
típica del proyecto MVC de ASP.NET, esto se hace en App_Start / FilterConfig.cs.
[CustomActionFilter("HomeController")]
public class HomeController : Controller
{
[CustomActionFilter("Index")]
public ActionResult Index()
{
return View();
}
}
1. Global
2. Controlador
3. Acción
1. Filtros de autentificación
2. Filtros de autorizacion
3. Filtros de registro
https://riptutorial.com/es/home 48
Atributo de manejador de excepciones
Este atributo maneja todas las excepciones no manejadas en el código, (esto es principalmente
para solicitudes Ajax - que tratan con JSON - pero pueden extenderse)
}
}
Digamos que siempre tienes que enviar una respuesta JSON similar a esto:
data: {},
Así que en lugar de manejar excepciones en las acciones del controlador, como esto:
https://riptutorial.com/es/home 49
}
catch(Exception ex)
{
return Json(new {Success = false, data = null, Message = ex.Message});
}
}
Puedes hacerlo:
[ExceptionHandler]
public ActionResult PerformMyAction()
{
var myData = new { myValue = 1};
[ExceptionHandler]
public class MyTestController : Controller
{
https://riptutorial.com/es/home 50
Capítulo 14: Html.AntiForgeryToken
Introducción
El token anti-falsificación se puede usar para ayudar a proteger su aplicación contra la
falsificación de solicitudes entre sitios. Para usar esta función, llame al método AntiForgeryToken
desde un formulario y agregue el atributo ValidateAntiForgeryTokenAttribute al método de acción
que desea proteger.
Genera un campo de formulario oculto (token anti-falsificación) que se valida cuando se envía el
formulario.
Sintaxis
• @ Html.AntiForgeryToken ()
Observaciones
Al enviar una solicitud ajax con el token CSRF ( __RequestVerificationToken ), asegúrese de que el
tipo de contenido no esté establecido en application/json . Si está utilizando jQuery,
automáticamente establece el tipo de contenido en application/x-www-form-urlencoded que luego
es reconocido por ASP.NET MVC.
Precaución
Tenga cuidado al establecer este valor. Su uso inadecuado puede abrir vulnerabilidades de
seguridad en la aplicación.
Examples
Uso básico
https://riptutorial.com/es/home 51
<!-- ... -->
}
<form>
@Html.AntiForgeryToken()
<!-- ... -->
</form>
Controlador (YourController.cs)
El método de acción objetivo:
[ValidateAntiForgeryToken]
[HttpPost]
public ActionResult ActionMethod(ModelObject model)
{
// ...
}
Anti forgery token is meant for user "" but the current user is "username"
Esto se debe a que el token de Anti-falsificación también está vinculado al usuario que ha iniciado
sesión actualmente. Este error aparece cuando un usuario inicia sesión pero su token sigue
vinculado a ser un usuario anónimo para el sitio.
Hay algunas formas de solucionar este comportamiento, pero si prefiere no tener los tokens
CSRF vinculados al estado de inicio de sesión de un usuario, puede desactivar esta función.
Coloque esta línea en su archivo Global.asax o en una lógica de inicio de aplicación similar.
AntiForgeryConfig.SuppressIdentityHeuristicChecks = true;
Debido a la vulnerabilidad causada por CSRF, generalmente se considera una buena práctica
verificar un AntiForgeryToken en todos los HttpPosts, a menos que haya una buena razón para
no hacerlo (algún problema técnico con la publicación, hay otro mecanismo de autenticación y / o
el la publicación no muta el estado como guardarlo en un db o archivo). Para asegurarse de no
olvidar, puede agregar un GlobalActionFilter especial que verifique automáticamente todos los
HttpPosts a menos que la acción esté decorada con un atributo especial de "ignorar".
[AttributeUsage(AttributeTargets.Class)]
https://riptutorial.com/es/home 52
public class ValidateAntiForgeryTokenOnAllPosts : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
var request = filterContext.HttpContext.Request;
if (skipCheck)
return;
// Ajax POSTs and normal form posts have to be treated differently when it comes
// to validating the AntiForgeryToken
if (request.IsAjaxRequest())
{
var antiForgeryCookie = request.Cookies[AntiForgeryConfig.CookieName];
AntiForgery.Validate(cookieValue,
request.Headers["__RequestVerificationToken"]);
}
else
{
new ValidateAntiForgeryTokenAttribute()
.OnAuthorization(filterContext);
}
}
}
}
/// <summary>
/// this should ONLY be used on POSTS that DO NOT MUTATE STATE
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false,
Inherited = true)]
public sealed class DontCheckForAntiForgeryTokenAttribute : Attribute { }
Para asegurarse de que se verifique en todas las solicitudes, solo agréguelo a sus filtros de
acción global
https://riptutorial.com/es/home 53
Uso anticipado: aplique el filtro antiforgery predeterminado para cada POST
Podemos olvidar aplicar el Antiforgery attribute para cada solicitud POST por lo que deberíamos
hacerlo por defecto. Esta muestra asegurará que el Antiforgery filter siempre se aplique a cada
solicitud POST .
return result;
}
}
Por lo tanto, ahora todas sus solicitudes POST están protegidas de forma predeterminada mediante
los atributos de Antiforgery, por lo que ya no necesitamos tener el atributo
https://riptutorial.com/es/home 54
[ValidateAntiForgeryToken] en cada método POST.
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
}
Método de acción
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Test(FormViewModel formData)
{
// ...
}
Guión
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script>
var formData = new FormData($('form')[0]);
$.ajax({
method: "POST",
url: "/demo/test",
data: formData ,
success: function (data) {
console.log(data);
},
error: function (jqXHR, textStatus, errorThrown) {
console.log(errorThrown);
}
})
</script>
https://riptutorial.com/es/home 55
Capítulo 15: Html.RouteLink
Parámetros
Parámetro Detalles
Examples
Ejemplo básico usando el texto de enlace y el nombre de la ruta
Como alternativa al uso de Html.ActionLink para generar enlaces en una vista, puede usar
Html.RouteLink
Para utilizar esta función, necesita configurar una ruta, por ejemplo:
Usar RouteLink() es conveniente si termina cambiando los nombres del controlador o los nombres
de los métodos de acción, ya que usar Html.ActionLink() significa tener que cambiar los
parámetros del controlador y el nombre del método de acción en la llamada, para que coincidan
con los nuevos nombres que tienen ha cambiado
Con RouteLink() puede cambiar los detalles de la ruta en la llamada MapRoute() , en otras palabras,
en una ubicación, y no se requerirá que ningún código que haga referencia a esa ruta a través de
RouteLink() cambie.
https://riptutorial.com/es/home 56
Capítulo 16: Inyección de dependencia
Observaciones
Todo el punto de la inyección de dependencia (DI) es reducir el acoplamiento de código. Imagine
cualquier tipo de interacción que implique la creación de algo como en el "Ejemplo de
dependencia de código duro".
Una gran parte de escribir código es la capacidad de probarlo. Cada vez que creamos una nueva
dependencia, hacemos que nuestro código sea difícil de probar porque no tenemos control sobre
esa dependencia.
¿Cómo probaría el código que depende de DataTime.Now por ejemplo? Siempre cambia así que
no tienes referencia. Esto es cuando se inyecta un parámetro estable como su punto de partida.
Puede controlarlo, puede escribir pruebas basadas en varios valores y asegurarse de que
siempre obtenga el resultado correcto.
Por lo tanto, una buena opción es pasar una interfaz o una clase abstracta como un parámetro en
el constructor DI.
Una interfaz representa un contrato bien definido, siempre puede confiar en los métodos para
estar allí y siempre puede confiar en las firmas del método.
Una vez que empieces a usar DI se abrirán otros aspectos. Por ejemplo, incluso si pasa una
interfaz en algún momento, necesitará una implementación real para realizar cualquier trabajo.
Aquí es donde aparecen otros conceptos. Podemos usar IOC (Inversión de control) para resolver
nuestras dependencias. Esto significa que le indicamos a nuestro código que siempre use una
implementación específica para cualquier contrato. Por supuesto que hay otras formas de hacer
esto. Siempre podríamos crear una instancia de cada contrato con una implementación específica
y, a partir de ese momento, nuestro código puede usar esa parte:
esto siempre funcionará siempre y cuando nuestra clase cumpla con el contrato esperado:
a partir del momento de inicialización siempre utilizamos el objeto de registro. Esto hace la vida
más fácil porque si alguna vez decidimos cambiar y usar un DatabaseLogging, por ejemplo, solo
tenemos que cambiar el código en un lugar y aquí es exactamente donde inicializamos la clase de
registro.
https://riptutorial.com/es/home 57
¿Es DI solo bueno para la prueba? No, DI también es importante al escribir código mantenible.
Permite que la separación de inquietudes sea clara.
Cuando escriba cualquier código, piense ... es comprobable, puedo escribir una prueba, es
cuando se inyecta un valor DateTime en lugar de usar DateTime. Ahora tiene sentido.
Examples
Configuraciones de Ninject
return kernel;
}
catch
{
kernel.Dispose();
throw;
}
}
Cree una nueva clase para el enlace que en este caso se llama Container:
https://riptutorial.com/es/home 58
new NinjectAppServiceModule());
}
}
Finalmente, en cada clase de NinjectModule derivada modifique los enlaces que sobrecargan el
método de carga como:
En la clase concreta que necesita el servicio, use la interfaz para acceder al servicio en lugar de
su implementación como:
https://riptutorial.com/es/home 59
}
Ahora, si necesita algo en la clase concreta, no interferirá en el código anterior. Puede cambiar la
implementación del servicio por otra diferencia completamente, y siempre que satisfaga la
interfaz, estará listo. También hace que sea muy fácil probarlo.
Dependencia codificada
public Example()
{
this._logging = new FileLogging();
}
}
parámetro DI
vs
https://riptutorial.com/es/home 60
recomendado) o usar uno de los inyectores de dependencia bien escritos y probados. En este
ejemplo voy a usar Ninject .
En primer lugar, descargue Ninject desde NuGet. Cree una carpeta llamada Infraestructura y
agregue una clase llamada NinjectDependencyResolver :
using Ninject;
using System;
using System.Collections.Generic;
using System.Web.Mvc;
public NinjectDependencyResolver()
{
// Initialize kernel and add bindings
kernel = new StandardKernel();
AddBindings();
}
El MVC Framework llamará a los métodos GetService y GetServices cuando necesite un aviso de
una clase para atender una solicitud entrante.
// .....
https://riptutorial.com/es/home 61
}
CustomCache = customCacheParam;
}
return View();
}
}
https://riptutorial.com/es/home 62
Este es un ejemplo de inyección costructora y es una forma de inyección de dependencia . Como
puede ver, nuestro controlador de inicio no depende de la clase CustomCache itslef. Si queremos
usar otra implementación de ICustomCache en nuestra aplicación, lo único que debemos cambiar
es vincular a ICustomCache con otra implementación y ese es el único paso que debemos tomar.
¿Qué ha pasado aquí es, MVC marco pidió a nuestro solucionador de dependencias registrado
para crear una instancia de la clase HomeController a través del método GetService. El método
GetService le pide al kernel de Ninject que cree el objeto solicitado y el kernel de Ninject examina
el tipo en su término y descubre que el constructor de HomeController vuelve a poner un
ICustomCache y el enlace ya se ha agregado para el ICustomCache . Ninject crea una instancia
de clase enlazada, la usa para crear HomeController y la devuelve MVC Framework.
Cadenas de dependencia.
Cuando Ninject intenta crear un tipo, examina otras dependencias entre el tipo y otros tipos y, si
existe, Ninject intenta crearlos también. Por ejemplo, si nuestra clase CustomCache requiere
ICacheKeyProvider y si se agrega la combinación de ICacheKeyProvider, Ninject puede
proporcionarlo para nuestra clase.
CacheKeyProvider = keyProviderParam;
}
...........
}
https://riptutorial.com/es/home 63
Añadir enlace para ICacheKeyProvider :
https://riptutorial.com/es/home 64
Capítulo 17: jQuery Ajax Call Con Asp MVC
Examples
Publicar objetos JavaScript con jQuery Ajax Call
Ajax llama, solicita y recupera datos para brindar al usuario la sensación de una mejor experiencia
de interfaz de usuario interactiva. Este artículo le mostrará cómo usar jQuery y enviar datos a
través de llamadas Ajax. Para este ejemplo, vamos a enviar el siguiente objeto JavaScript a
nuestro servidor.
var post = {
title: " Posting JavaScript objects with jQuery Ajax Call",
content: " Posting JavaScript objects with jQuery Ajax Call",
tags: ["asp mvc", "jquery"]
};
Todo lo que necesitamos hacer es crear un método de controlador MVC ASP.NET estándar que
tome un solo parámetro del tipo Persona, como tal.
Para enviar objetos de JavaScript, necesitamos usar el método JSON.stringify () para enviar el
objeto a la opción de datos.
$.ajax({
url: '@Url.Action("create", "Post")',
type: "POST",
contentType: "application/json",
data: JSON.stringify({ model: post })
}).done(function(result){
https://riptutorial.com/es/home 65
//do something
});
https://riptutorial.com/es/home 66
Capítulo 18: Manejo de errores Http
Introducción
Cada sitio web necesita para manejar los errores. Puede permitir que sus usuarios vean las
páginas de error 404 o 500 que IIS distribuye o, utilizando el Web.Config y un simple Controlador,
puede capturar estos errores y entregar sus propias páginas de error personalizadas.
Examples
Configuración básica
Este ejemplo cubrirá la creación de una página de error personalizada para 404 Página no
encontrada y 500 Error de servidor. Puede extender este código para capturar cualquier código
de error que necesite.
Web.Config
Si está utilizando IIS7 y superior, ignore el nodo <CustomError.. y use <httpErrors... lugar.
Esto le indica al sitio que dirija cualquier error 404 a ~/error/notfound y cualquier error 500 a
~/error/servererror . También conservará la URL solicitada (piense en transferir en lugar de
redirigir ) para que el usuario nunca vea la URL de la página ~/error/...
https://riptutorial.com/es/home 67
}
Por último, cree las NotFound correspondientes de NotFound y NotFound y ServerError estilo para que
todo esté bien y sin problemas con el diseño de tu sitio.
https://riptutorial.com/es/home 68
Capítulo 19: Maquinilla de afeitar
Introducción
¿Qué es Razor?
Razor es una sintaxis de marcado que le permite incrustar código basado en servidor (Visual
Basic y C #) en páginas web.
El código basado en servidor puede crear contenido web dinámico sobre la marcha, mientras que
una página web se escribe en el navegador. Cuando se llama a una página web, el servidor
ejecuta el código basado en el servidor dentro de la página antes de devolver la página al
navegador. Al ejecutarse en el servidor, el código puede realizar tareas complejas, como acceder
a bases de datos.
Sintaxis
• @ {...}
• @nombre de la variable
• @(nombre de la variable)
• @para(...){ }
• @ (Expresión explícita)
• @ * comentarios * @
Observaciones
ASP.NET Razor incluye motores de visualización para C # y VB.
El motor de visualización C # procesa archivos con una extensión .cshtml , mientras que el motor
de visualización VB funciona con archivos .vbhtml .
Examples
Añadir comentarios
Razor tiene su propia sintaxis de comentario que comienza con @* y termina con *@ .
Comentario en línea:
Comentario multilínea:
https://riptutorial.com/es/home 69
lines *@
Comentario HTML
También puede usar la sintaxis de comentario HTML normal comenzando con <!-- y terminando
con --> en las vistas de Razor. Pero a diferencia de otros comentarios, el código Razor dentro de
un comentario HTML todavía se ejecuta normalmente.
@{
var hello = "Hello World!";
}
<!-- @hello -->
@{
// This is a comment
var Input = "test";
}
@{
var number = 1;
<text>
Hello, I am text
<br / >
Hello, I am more text!
</text>
}
Tenga en cuenta que Razor, cuando está dentro de un bloque de código, entenderá las etiquetas
HTML. Por lo tanto, agregar la etiqueta de text alrededor de las etiquetas HTML es innecesario
(aunque sigue siendo correcto), como por ejemplo:
https://riptutorial.com/es/home 70
@{
var number = 1;
<text>
<div>
Hello, I am text
<br / >
Hello, I am more text!
</div>
</text>
}
Sintaxis basica
El código Razor se puede insertar en cualquier lugar dentro del código HTML. Los bloques de
código de la maquinilla de afeitar están incluidos en @{ ... } . Las variables y funciones en línea
comienzan con @ . El código dentro de los soportes de Razor sigue las reglas normales de C # o
VB.
@{ var firstNumber = 1; }
@{
var secondNumber = 2;
var total = firstNumber + secondNumber;
}
<h2>Item@(item.Id)</h2>
Para este ejemplo en particular, no podremos usar la sintaxis implícita porque Item@item.Id parece
un correo electrónico y Razor lo procesará como tal.
https://riptutorial.com/es/home 71
{
Console.Write("The total is greater than 3");
}
else
{
Console.Write("The total is less than 3");
}
Esta misma sintaxis se usaría para todas las declaraciones como for , foreach , while , if , switch ,
etc.
Escapando a @ personaje
Sin embargo, en algunos casos, el uso del signo @ es más ambiguo, y debe evitarse
explícitamente con @@ , como se muestra en el siguiente ejemplo:
El uso de la palabra clave Razor @functions brinda la capacidad de introducir clases y métodos
para el uso en línea dentro de un archivo Razor:
@functions
{
https://riptutorial.com/es/home 72
string GetCssClass(Status status)
{
switch (status)
{
case Status.Success:
return "alert-success";
case Status.Info:
return "alert-info";
case Status.Warning:
return "alert-warning";
case Status.Danger:
default:
return "alert-danger";
}
}
}
@functions
{
class Helpers
{
//implementation
}
}
no compilará Los atributos de data- * son válidos y comunes en html5 para agregar valores extra
a los elementos.
Esto funciona bien ya que los guiones bajos no son aceptables en los nombres de atributos en
html.
Plantillas de editor
Las plantillas de editor son una buena manera de reutilizar el código Razor. Puede definir
plantillas de editor como vistas parciales de Razor y luego usarlas en otras vistas.
https://riptutorial.com/es/home 73
Las plantillas de editor generalmente existen en la carpeta Views/Shared/EditorTemplates/ , aunque
también se pueden guardar en la carpeta Views/ControllerName/EditorTemplates/ . El nombre de la
vista suele ser el nombre del objeto para el que desea utilizar la plantilla, como <type>.cshtml .
@model DateTime
<div>
<span>
@Html.TextBox("", Model.ToShortDateString(), new { data_date_picker="true" })
</span>
</div>
Luego, use EditorFor para llamar a este código de plantilla en otra vista:
https://riptutorial.com/es/home 74
@model SubModel
<div class="form-group">
@Html.LabelFor(m => m.FirstName)
@Html.TextBoxFor(m => m.FirstName)
</div>
<div class="form-group">
@Html.LabelFor(m => m.LastName)
@Html.TextBoxFor(m => m.LastName)
</div>
@model Model
@Html.EditorFor(m => m.CreatedDate)
@Html.EditorFor(m => m.SubModel, new { @Prefix = "New"})
@* the second argument is how you can pass viewdata to your editor template*@
//call
@WrapInBox(@<div>
I'm a inner div
</div>)
//call
@MenuHelpers.CreatePrimaryBootstrapButton("my button")
Los globales @Url y @Html no están disponibles de forma predeterminada en @Helper definido en
App_code. Puede agregarlos de la siguiente manera (para cada .cshtml en su carpeta App_code)
https://riptutorial.com/es/home 75
@* Make @Html and @Url available *@
@functions
{
private new static HtmlHelper<object> Html
{
get { return ((WebViewPage)CurrentPage).Html; }
}
https://riptutorial.com/es/home 76
Capítulo 20: Modelo de enlace
Introducción
El enlace de modelo es el proceso de tomar parámetros HTTP, normalmente en la Cadena de
consulta de una solicitud GET, o dentro del cuerpo POST, y aplicarlo en un objeto que luego
puede validarse y consumirse de una manera orientada a objetos sin la necesidad de acciones
del Controlador tener un conocimiento íntimo de cómo recuperar los parámetros HTTP.
En otras palabras, el enlace de modelo es lo que permite que las acciones, en MVC, tengan
cualquiera de los parámetros, ya sea un tipo de valor o un objeto.
Observaciones
Para intentar crear una instancia en la acción, el proceso del modelo de enlace buscará datos en
varios lugares:
Examples
Enlace de valor de ruta
Para ampliar la vinculación de ruta, diga que tiene una URL como
https://stackoverflow.com/questions/1558902?sort=desc
https://riptutorial.com/es/home 77
Atadura a objetos
A menudo, estarías trabajando con clases de viewmodel en asp.net-mvc y querrías unirte a las
propiedades en estas. Esto funciona de manera similar a la asignación a parámetros individuales.
Digamos que tienes un modelo de vista simple llamado PostViewModel como este
Luego, publicó los valores de Id y SnappyTitle desde un formulario en la solicitud http y luego se
mapearían directamente en ese modelo si el modelo en sí fuera el parámetro de acción, por
ejemplo
Vale la pena señalar que el enlace no distingue entre mayúsculas y minúsculas para los nombres
de parámetros y propiedades. También emitirá valores cuando sea posible. Estoy dejando más
casos de borde para ejemplos específicos
Ajax vinculante
Estos son valores de formulario que van en la solicitud HTTP usando el método POST. (incluidas
las solicitudes POST de jQuery).
$.ajax({
type: 'POST',
url: window.updatePost,
data: { id: 21, title: 'snappy title' },
//kept short for clarity
});
Aquí los dos valores en json, id y title, estarían vinculados a la acción correspondiente, por
ejemplo,
https://riptutorial.com/es/home 78
requisitos. Si combinamos esto con las poderosas características de unión de modelos de MVC,
obtendremos una forma elegante de hacerlo. Podemos crear un enlace de modelo basado en
sesión genérica en tres sencillos pasos:
using System;
using System.Web.Mvc;
https://riptutorial.com/es/home 79
Monthly, Yearly
}
Podemos registrar el cuaderno de modelos basado en sesión para este modelo en Global.asax
en el método Application_Start :
// Model binders.
// Remember to specy unique SessionKey
ModelBinders.Binders.Add(typeof(ReportInfo),
new SessionDataModelBinder<ReportInfo>("ReportInfo"));
}
return View();
}
return View();
}
}
@using (Html.BeginForm()) {
https://riptutorial.com/es/home 80
@Html.EditorFor(model => model.FirstName)
<input type="submit" value="Save" />
}
Para evitar que un usuario malintencionado asigne IsAdmin, puede usar el atributo Bind en la
acción:
[HttpPost]
public ViewResult Edit([Bind(Exclude = "IsAdmin")] User user)
{
// ...
}
Subir archivo
Modelo:
Ver:
@model HelloWorldMvcApp.SampleViewModel
Acción:
[HttpPost]
public ActionResult Index(SampleViewModel model)
{
if (model.file.ContentLength > 0)
{
string fileName = Path.GetFileName(model.file.FileName);
string fileLocation = "~/App_Data/uploads/"+ fileName;
model.file.SaveAs(Server.MapPath(fileLocation));
}
return View(model);
}
https://riptutorial.com/es/home 81
utilizando el cuaderno de modelos
Si diferentes usuarios necesitan un formato de fecha y hora diferente, es posible que deba
analizar su cadena de fecha entrante a la fecha real de acuerdo con el formato. En este caso este
fragmento puede ayudarte.
https://riptutorial.com/es/home 82
Capítulo 21: Modelo de validación
Examples
Validar modelo en ActionResult
[HttpPost]
public ActionResult ContactUs(ContactUsModel contactObject)
{
// This line checks to see if the Model is Valid by verifying each Property in the Model
meets the data validation rules
if(ModelState.IsValid)
{
}
return View(contactObject);
}
La clase modelo
[Required]
public string Password { get; set; }
[Required]
public string FullName { get; set; }
}
Pero desea excluir FullName de la validación del modelo porque está utilizando el modelo
también en un lugar donde FullName no está completo, puede hacerlo de la siguiente manera:
ModelState.Remove("FullName");
https://riptutorial.com/es/home 83
Mensajes de error personalizados
Cuando sus mensajes de error están en un archivo de recursos (.resx), debe especificar el tipo de
recurso y el nombre del recurso:
[Display(Name = "Age")]
[Required(ErrorMessage = "Please enter your Email Address!")]
[EmailAddress(ErrorMessage = "Invalid Email Address")]
public string EmailAddress { get; set; }
}
Pero tanto usted como yo sabemos que solo puede haber 1 dirección de correo electrónico por
https://riptutorial.com/es/home 84
persona, o bien enviará correos electrónicos a personas potencialmente equivocadas y / o varias
personas. Aquí es donde entra en juego el control del controlador. Así que asumamos que las
personas están creando cuentas para que las guarde a través de Crear acción.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "ID, FirstName, LastName, EmailAddress")]
PersonInfo newPerson)
{
if(ModelState.IsValid) // this is where the custom error messages on your model will
display if return false
{
if(database.People.Any(x => x.EmailAddress == newPerson.EmailAddress)) // checking if
the email address that the new person is entering already exists.. if so show this error
message
{
ModelState.AddModelError("EmailAddress", "This email address already exists!
Please enter a new email address!");
return View(newPerson);
}
db.Person.Add(newPerson);
db.SaveChanges():
return RedirectToAction("Index");
}
return View(newPerson);
}
En los casos en que necesite asegurar la validación del modelo utilizando Jquery, se puede usar
la función .valid ().
[Required]
[Display(Name = "Number of Hospitals")]
public int Hospitals{ get; set; }
[Required]
[Display(Name = "Number of Beds")]
public int Beds { get; set; }
El código de vista
<div class="divPanel">
<div class="row">
<div class="col-md-3">
@Html.LabelFor(m => m.Hospitals)
@Html.TextBoxFor(m => m.Hospitals, new { @class = "form-control", @type =
https://riptutorial.com/es/home 85
"number"})
@Html.ValidationMessageFor(m => m.Hospitals)
</div>
<div class="col-md-3">
</div>
}
if ($('#form1').valid()) {
//Do Something.
}
}
https://riptutorial.com/es/home 86
Capítulo 22: MVC vs Formularios Web
Introducción
Antes de saltar a ASP. Para desarrollar su aplicación web con NET MVC, debe considerar las
ventajas y desventajas del marco y debe saber que existe otro marco web creado y mantenido
por Microsoft que es ASP .NET Web Forms.
Sintaxis
• El motor de vista ASPX utiliza "<% =%>" o "<%:%>" para representar el contenido del lado
del servidor.
• El Razor View Engine usa @ para representar el contenido del lado del servidor.
Observaciones
https://www.asp.net/web-forms
https://www.asp.net/mvc
Examples
Ventajas de los formularios web ASP .NET
• Admite un modelo de evento que conserva el estado a través de HTTP, lo que beneficia el
desarrollo de aplicaciones web de línea de negocio. La aplicación basada en Web Forms
proporciona docenas de eventos que son compatibles con cientos de controles de servidor.
• Utiliza el estado de vista o los formularios basados en servidor, lo que puede facilitar la
administración de la información de estado.
• Funciona bien para pequeños equipos de desarrolladores y diseñadores web que desean
aprovechar la gran cantidad de componentes disponibles para el rápido desarrollo de
aplicaciones.
https://riptutorial.com/es/home 87
(la clase de página, los controles, etc.) están estrechamente integrados y generalmente
requieren menos código que el modelo MVC.
• Modelo de desarrollo fácil para aquellos desarrolladores que vienen del desarrollo de
WindowsForm.
• No utiliza el estado de vista ni los formularios basados en servidor. Esto hace que el marco
MVC sea ideal para los desarrolladores que desean un control total sobre el
comportamiento de una aplicación.
• Utiliza un patrón de controlador frontal que procesa las solicitudes de aplicaciones web a
través de un solo controlador. Esto le permite diseñar una aplicación que admita una
infraestructura de enrutamiento enriquecida. Para obtener más información, consulte Front
Controller en el sitio web de MSDN.
• Funciona bien para aplicaciones web que son compatibles con grandes equipos de
desarrolladores y diseñadores web que necesitan un alto grado de control sobre el
comportamiento de la aplicación.
Desventajas
Formularios Web:
• Ciclo de vida de la página compleja: cada vez que se realiza una solicitud al servidor,
existen al menos 5 métodos para ejecutar antes del controlador de eventos.
• Es difícil trabajar con marcos del lado del cliente como JQuery o Angular.
• Difícil trabajar con Javascript asíncrono y XML (AJAX)
• Manejo de ViewState
• El lado del cliente de la página y el código posterior están estrechamente acoplados.
MVC:
https://riptutorial.com/es/home 88
Razor (MVC) ASPX (Formularios Web)
https://riptutorial.com/es/home 89
Capítulo 23: Operación CRUD
Introducción
La operación CRUD se refiere a las operaciones clásicas (crear, leer, actualizar, eliminar)
relacionadas con los datos.
En el contexto de ASP MVC, hay varias formas de CRUD sus datos utilizando Modelos y,
posteriormente, vistas, Controladores.
Una forma sencilla es hacer uso de la función de andamiaje proporcionada por las plantillas de
Visual Studio y personalizarla según sus necesidades.
Tenga en cuenta que CRUD está muy bien definido y tiene muchas variaciones para satisfacer
sus necesidades. Por ejemplo, primero la base de datos, primero la entidad, etc.
Observaciones
Para simplificar, esta operación CRUD utiliza un contexto de marco de entidad en el controlador.
No es una buena práctica, pero está fuera del alcance de este tema. Haga clic en el marco de la
entidad si desea obtener más información al respecto.
Examples
Crear - Parte del controlador
1. La acción GET utilizada para devolver la vista muestra un formulario que permite al usuario
ingresar datos usando elementos HTML. Si hay algunos valores predeterminados que
deben insertarse antes de que el usuario agregue datos, debe asignarse a las propiedades
del modelo de vista en esta acción.
2. Cuando el usuario complete el formulario y haga clic en el botón "Guardar", trataremos los
datos del formulario. Por eso ahora necesitamos la acción POST . Este método será
responsable de administrar los datos y guardarlos en la base de datos. En caso de cualquier
error, la misma vista devuelta con datos de formulario almacenados y mensaje de error
explica qué problema ocurre después de enviar la acción.
Implementaremos estos dos pasos dentro de dos métodos Create () dentro de nuestra clase de
controlador.
// GET: Student/Create
// When the user access this the link ~/Student/Create a get request is made to controller
Student and action Create, as the page just need to build a blank form, any information is
needed to be passed to view builder
https://riptutorial.com/es/home 90
public ActionResult Create()
{
// Creates a ViewResult object that renders a view to the response.
// no parameters means: view = default in this case Create and model = null
return View();
}
// POST: Student/Create
[HttpPost]
// Used to protect from overposting attacks, see
http://stackoverflow.com/documentation/asp.net-mvc/1997/html-antiforgerytoke for details
[ValidateAntiForgeryToken]
// This is the post request with forms data that will be bind the action, if in the data
post request have enough information to build a Student instance that will be bind
public ActionResult Create(Student student)
{
try
{
//Gets a value that indicates whether this instance received from the view is valid.
if (ModelState.IsValid)
{
// Adds to the context
db.Students.Add(student);
// Persist the data
db.SaveChanges();
// Returns an HTTP 302 response to the browser, which causes the browser to
make a GET request to the specified action, in this case the index action.
return RedirectToAction("Index");
}
}
catch
{
// Log the error (uncomment dex variable name and add a line here to write a log).
ModelState.AddModelError("", "Unable to save changes. Try again, and if the
problem persists see your system administrator.");
}
// view = default in this case Create and model = student
return View(student);
}
@model ContosoUniversity.Models.Student
//The Html.BeginForm helper Writes an opening <form> tag to the response. When the user
submits the form, the request will be processed by an action method.
@using (Html.BeginForm())
{
//Generates a hidden form field (anti-forgery token) that is validated when the form is
submitted.
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Student</h4>
<hr />
//Returns an unordered list (ul element) of validation messages that are in the
ModelStateDictionary object.
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
https://riptutorial.com/es/home 91
<div class="form-group">
//Returns an HTML label element and the property name of the property that is
represented by the specified expression.
@Html.LabelFor(model => model.LastName, htmlAttributes: new { @class = "control-label
col-md-2" })
<div class="col-md-10">
//Returns an HTML input element for each property in the object that is
represented by the Expression expression.
@Html.EditorFor(model => model.LastName, new { htmlAttributes = new { @class =
"form-control" } })
//Returns the HTML markup for a validation-error message for each data field that
is represented by the specified expression.
@Html.ValidationMessageFor(model => model.LastName, "", new { @class = "text-
danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.FirstMidName, htmlAttributes: new { @class = "control-
label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.FirstMidName, new { htmlAttributes = new { @class =
"form-control" } })
@Html.ValidationMessageFor(model => model.FirstMidName, "", new { @class = "text-
danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.EnrollmentDate, htmlAttributes: new { @class = "control-
label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.EnrollmentDate, new { htmlAttributes = new { @class
= "form-control" } })
@Html.ValidationMessageFor(model => model.EnrollmentDate, "", new { @class =
"text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
//Returns an anchor element (a element) the text is Back to List and action is Index
@Html.ActionLink("Back to List", "Index")
</div>
Al ser url ~/Student/Details/5 : (~: raíz del sitio, Student: Controller, Details: Action, 5: student id),
es posible recuperar al alumno por su id.
https://riptutorial.com/es/home 92
// GET: Student/Details/5
public ActionResult Details(int? id)
{
// it good practice to consider that things could go wrong so,it is wise to have a
validation in the controller
if (id == null)
{
// return a bad request
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Student student = db.Students.Find(id);
if (student == null)
{
// if doesn't found return 404
return HttpNotFound();
}
return View(student);
}
// Model is the class that contains the student data send by the controller and will be
rendered in the view
@model ContosoUniversity.Models.Student
<h2>Details</h2>
<div>
<h4>Student</h4>
<hr />
<dl class="dl-horizontal">
<dt>
//Gets the display name for the model.
@Html.DisplayNameFor(model => model.LastName)
</dt>
<dd>
//Returns HTML markup for each property in the object that is represented by the
Expression expression.
@Html.DisplayFor(model => model.LastName)
</dd>
<dt>
@Html.DisplayNameFor(model => model.FirstMidName)
</dt>
<dd>
@Html.DisplayFor(model => model.FirstMidName)
</dd>
<dt>
@Html.DisplayNameFor(model => model.EnrollmentDate)
</dt>
<dd>
@Html.DisplayFor(model => model.EnrollmentDate)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Enrollments)
https://riptutorial.com/es/home 93
</dt>
<dd>
<table class="table">
<tr>
<th>Course Title</th>
<th>Grade</th>
</tr>
@foreach (var item in Model.Enrollments)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.Course.Title)
</td>
<td>
@Html.DisplayFor(modelItem => item.Grade)
</td>
</tr>
}
</table>
</dd>
</dl>
</div>
<p>
//Returns an anchor element (a element) the text is Edit, action is Edit and the route
value is the model ID property.
@Html.ActionLink("Edit", "Edit", new { id = Model.ID }) |
@Html.ActionLink("Back to List", "Index")
</p>
// GET: Student/Edit/5
// It is receives a get http request for the controller Student and Action Edit with the id
of 5
public ActionResult Edit(int? id)
{
// it good practice to consider that things could go wrong so,it is wise to have a
validation in the controller
if (id == null)
{
// returns a bad request
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Este método es muy similar al método de acción de detalles, que es un buen candidato para una
refactorización, pero está fuera del alcance de este tema.
https://riptutorial.com/es/home 94
// POST: Student/Edit/5
[HttpPost]
// Now just save the changes that all the changes made in the form will be
persisted.
db.SaveChanges();
// Returns an HTTP 302 response to the browser, which causes the browser to
make a GET request to the specified action, in this case the index action.
return RedirectToAction("Index");
}
}
catch
{
//Log the error add a line here to write a log.
ModelState.AddModelError("", "Unable to save changes. Try again, and if the
problem persists, see your system administrator.");
}
// GET: Student/Delete/5
public ActionResult Delete(int? id)
{
// it good practice to consider that things could go wrong so,it is wise to have a
validation in the controller
if (id == null)
{
// returns a bad request
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
https://riptutorial.com/es/home 95
}
// POST: Student/Delete/5
[HttpPost]
// Try to remove it
db.Students.Remove(student);
// Returns an HTTP 302 response to the browser, which causes the browser to make a GET
request to the specified action, in this case the index action.
return RedirectToAction("Index");
}
https://riptutorial.com/es/home 96
Capítulo 24: Plantillas de visualización y
editor
Introducción
Al tratar con objetos en una aplicación MVC, si algún objeto se muestra en varios lugares con el
mismo formato, necesitaríamos algún tipo de diseño estandarizado. ASP.NET MVC ha hecho que
este tipo de estandarización sea fácil de hacer con la inclusión de plantillas de visualización y
editor. En resumen, las plantillas de visualización y editor se utilizan para estandarizar el diseño
que se muestra al usuario al editar o mostrar ciertos tipos o clases.
Examples
Plantilla de pantalla
Modelo:
Si queremos mostrar a los usuarios en diferentes Vistas, sería mejor crear un diseño
estandarizado para estos usuarios donde sea necesario. Podemos lograr esto utilizando plantillas
de pantalla.
Una plantilla de visualización es simplemente una vista parcial que está vinculada con el modelo
al objeto que desea mostrar y existe en la carpeta Views/Shared/DisplayTemplates (aunque también
puede ponerla en Views/ControllerName/DisplayTemplates ). Además, el nombre de la vista (de
forma predeterminada) debe ser el nombre del objeto para el que desea utilizarlo como
plantilla .
@model TemplatesDemo.Models.User
Ahora, si queremos mostrar a todos los usuarios de la base de datos y mostrarlos en diferentes
Vistas, simplemente podemos enviar la lista de usuarios a la Vista y usar la Plantilla de
https://riptutorial.com/es/home 97
Visualización para mostrarlos. Podemos usar uno de los dos métodos para hacerlo:
Html.DisplayFor()
Html.DisplayForModel()
DisplayFor llama a la plantilla de pantalla para el tipo de propiedad seleccionada (por ejemplo,
Html.DisplayFor(x => x.PropertyName) . DisplayForModel llama a la plantilla de pantalla para el @model
de la vista
Ver
@model IEnumerable<TemplatesDemo.Models.User>
@{
ViewBag.Title = "Users";
}
<h2>Users</h2>
@Html.DisplayForModel()
Plantilla de editor
Las Plantillas de visualización se pueden usar para estandarizar el diseño de un objeto, así que
ahora veamos cómo podemos hacer lo mismo para estos objetos al editarlos. Al igual que las
plantillas de visualización, hay dos formas de llamar a las plantillas de editor para un tipo dado:
Html.EditorFor()
Html.EditorForModel()
Las plantillas de editor, al igual que las plantillas de visualización, deben existir en Views /
Shared / EditorTemplates o Views / ControllerName / EditorTemplates . Para esta
demostración, los crearemos en la carpeta Compartida. Nuevamente, el nombre de la vista (de
manera predeterminada) debe ser el nombre del objeto para el que desea usarla como
plantilla.
Modelo
https://riptutorial.com/es/home 98
Digamos que queremos poder editar cualquier usuario desde la base de datos en múltiples vistas.
Usaremos un ViewModel para este propósito.
ViewModel
@model TemplatesDemo.Models.UserEditorViewModel
<div class="form-group">
@Html.DisplayNameFor(m => m.User.Id)
@Html.EditorFor(m => m.User.Id)
</div>
<div class="form-group">
@Html.DisplayNameFor(m => m.User.Name)
@Html.EditorFor(m => m.User.Name)
</div>
<div class="form-group">
@Html.DisplayNameFor(m => m.User.DateOfBirth)
@Html.EditorFor(m => m.User.DateOfBirth)
</div>
<div class="form-group">
@Html.DisplayNameFor(m => m.User.Roles.Role)
@Html.DropDownListFor(m => m.User.RoleId, new SelectList(Model.Roles,"Id","Role"))
</div>
Acción
https://riptutorial.com/es/home 99
Role = "Admin"
},
new Roles
{
Id = 2,
Role = "Manager"
},
new Roles
{
Id = 3,
Role = "User"
}
}
};
return View(viewModel);
}
Ver
@model TemplatesDemo.Models.UserEditorViewModel
https://riptutorial.com/es/home 100
Capítulo 25: Registro de errores
Examples
Atributo simple
using System;
using System.Web;
using System.Web.Mvc;
namespace Example.SDK.Filters
{
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
public sealed class CustomErrorHandlerFilter : HandleErrorAttribute
{
public override void OnException(ExceptionContext filterContext)
{
// RouteDate is useful for retrieving info like controller, action or other route
values
string controllerName = filterContext.RouteData.Values["controller"].ToString();
string actionName = filterContext.RouteData.Values["action"].ToString();
base.OnException(filterContext);
}
}
}
filters.Add(new CustomErrorHandlerFilter());
https://riptutorial.com/es/home 101
}
StreamWriter log;
if (!System.IO.Directory.Exists(error_folder))
{
System.IO.Directory.CreateDirectory(error_folder);
}
https://riptutorial.com/es/home 102
{
log = new StreamWriter(String.Format(@"{0}\Log_{1}.txt", error_folder,
timestamp));
}
else
{
log = File.AppendText(String.Format(@"{0}\Log_{1}.txt", error_folder, timestamp));
}
https://riptutorial.com/es/home 103
Paso 6: Registrar FilterConfig en Global.asax
https://riptutorial.com/es/home 104
Capítulo 26: Reglas de reescritura de IIS
Examples
Forzar HTTPS usando la regla de reescritura
Este ejemplo muestra cómo puede usar las reglas de IIS Rewrite para forzar HTTPS haciendo
que todas las solicitudes HTTP devuelvan un Redireccionamiento 301 (Permanente) a la página
HTTPS.
Esto suele ser mejor que usar el atributo [RequireHttps] porque el atributo usa una redirección
302, y al estar en el canal de MVC es mucho más lento que hacerlo a nivel de IIS.
<rewrite xdt:Transform="Insert">
<rules>
<rule name="Enforce HTTPS WWW" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="true">
<add input="{HTTP_HOST}" pattern="^(?!www)(.*)"/>
<add input="{URL}" pattern="^(.*)"/>
<!-- {URL} Gives the base portion of the URL, without any querystring or extra
path information, for example, "/vdir/default.asp". -->
</conditions>
<action type="Redirect" url="https://www.{C:1}{C:2}" appendQueryString="true"
redirectType="Permanent" />
</rule>
</rules>
</rewrite>
https://riptutorial.com/es/home 105
Capítulo 27: T4MVC
Introducción
T4MVC es una plantilla T4 que genera ayudantes fuertemente tipados para usar en los
mecanismos de enrutamiento MVC, a diferencia de las cadenas mágicas. T4MVC detectará los
diversos controladores, acciones y vistas, y creará referencias a esas vistas, cometiendo errores
en tiempo de compilación en el caso de que un intento de enrutar o acceder a una vista no sea
válido.
Examples
Llamando a una acción
En MVC, hay algunos escenarios donde desea especificar una acción para propósitos de
enrutamiento, ya sea para un enlace, una acción de formulario o una redirección a la acción.
Puede especificar una acción a través del espacio de nombres MVC.
T4MVC generará un controlador heredado que anula la acción. Esta anulación establecerá los
datos de la ruta correctamente para que UrlHelper de MVC genere la URL correcta. Puede llamar
a este método y pasarlo a varios métodos para UrlHelper . Los siguientes ejemplos suponen que
se está utilizando la ruta MVC predeterminada:
Enlazar
https://riptutorial.com/es/home 106
//T4MVC also allows you to specify the parameter without creating an anonymous object:
@Html.ActionLink("Link Text", MVC.Home.MyActionWithParameter(1) )
//result: <a href="/Home/MyActionWithParameter/1">Link Text</a>
@Url.Action( MVC.Home.Index() )
//result: /
@Url.Action("Link Text", MVC.Home.MyAction() )
//result: /Home/MyAction
@Url.Action("Link Text", MVC.Home.MyActionWithParameter(1) )
//result: /Home/MyActionWithParameter/1
Tenga en cuenta que T4MVC sigue las mismas reglas que MVC Routing: no especificará las
variables de ruta predeterminadas, por lo que la acción del Index en el HomeController no genera
/Home/Index sino la forma abreviada y perfectamente válida de / .
Método de formulario
Redirigir a la acción
Cuando esté en un controlador, es posible que desee redirigir a una acción de la acción actual.
Esto se puede hacer, likeso:
https://riptutorial.com/es/home 107
}
https://riptutorial.com/es/home 108
Capítulo 28: Usando múltiples modelos en
una vista
Introducción
El enfoque principal de este tema es usar una clase de modelo múltiple en la capa de
visualización de MVC
Examples
Uso de múltiples modelos en una vista con ExpandoObject dinámico
ExpandoObject (el espacio de nombres System.Dynamic ) es una clase que se agregó a .Net
Framework 4.0 . Esta clase nos permite agregar y eliminar dinámicamente propiedades en un
objeto en tiempo de ejecución. Al utilizar el objeto Expando, podemos agregar nuestras clases de
modelo en el objeto Expando creado dinámicamente. El siguiente ejemplo explica cómo podemos
usar este objeto dinámico.
https://riptutorial.com/es/home 109
return students;
}
Ver:
<h2>Teacher List</h2>
<table>
<tr>
<th>Id</th>
<th>Name</th>
</tr>
@foreach (Teacher teacher in Model.Teachers)
{
<tr>
<td>@teacher.TeacherId</td>
<td>@teacher.Name</td>
</tr>
}
</table>
<h2>Student List</h2>
<table>
<tr>
<th>Id</th>
<th>Name</th>
</tr>
@foreach (Student student in Model.Students)
{
<tr>
<td>@student.StudentId</td>
<td>@student.Name</td>
</tr>
}
</table>
https://riptutorial.com/es/home 110
Lea Usando múltiples modelos en una vista en línea: https://riptutorial.com/es/asp-net-
mvc/topic/10144/usando-multiples-modelos-en-una-vista
https://riptutorial.com/es/home 111
Capítulo 29: Validación automática del lado
del cliente a partir de atributos
Observaciones
Por defecto, Safari no impone la validación de elementos HTML5. Debe anular esto manualmente
utilizando otros medios.
Examples
Modelo
[Required]
[StringLength(6, MinimumLength = 3)]
[RegularExpression(@"(\S)+", ErrorMessage = "White space is not allowed")]
public string UserName { get; set; }
[Required]
[StringLength(8, MinimumLength = 3)]
public string FirstName { get; set; }
[Required]
[StringLength(9, MinimumLength = 2)]
public string LastName { get; set; }
[Required]
public string City { get; set; }
configuración de web.config
<appSettings>
<add key="ClientValidationEnabled" value="true"/>
<add key="UnobtrusiveJavaScriptEnabled" value="true"/>
</appSettings>
Vista de formulario
https://riptutorial.com/es/home 112
@model WebApplication4.Models.UserModel
@{
ViewBag.Title = "Register";
}
<h2>@ViewBag.Title.</h2>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
"~/Scripts/jquery.validate*"));
https://riptutorial.com/es/home 113
}
}
Global.asax.cs
Lea Validación automática del lado del cliente a partir de atributos en línea:
https://riptutorial.com/es/asp-net-mvc/topic/6044/validacion-automatica-del-lado-del-cliente-a-
partir-de-atributos
https://riptutorial.com/es/home 114
Capítulo 30: ViewData, ViewBag, TempData
Introducción
ViewData y ViewBag se utilizan para transferir datos desde el controlador para ver.
ViewData no es más que un diccionario de objetos y es accesible por cadena como clave.
ViewBag es muy similar a ViewData. ViewBag es una propiedad dinámica. ViewBag es solo una
envoltura alrededor de ViewData.
TempData mantiene los datos durante el tiempo de la solicitud HTTP, lo que significa que
mantiene los datos entre dos solicitudes consecutivas. TempData nos ayuda a transferir datos
entre controladores o entre acciones. Usos de sesión interna.
Sintaxis
1. ViewData [clave] = valor;
2. ViewBag.Key = valor;
Examples
¿Qué son ViewData, ViewBag y TempData?
ViewData es el mecanismo para que un controlador proporcione datos a la vista que presenta, sin
usar ViewModel. Específicamente, ViewData es un diccionario que está disponible tanto en los
métodos de acción MVC como en las vistas. Puede usar ViewData para transferir algunos datos
de su método de acción a la vista devuelta por el método de acción.
Como es un diccionario, puede usar el diccionario como sintaxis para configurar y obtener datos
de él.
Por ejemplo, si desea pasar un mensaje de cadena de su método de acción de índice a su vista
de índice Index.cshtml , puede hacer esto.
https://riptutorial.com/es/home 115
Para acceder a esto en su vista Index.cshtml , simplemente puede acceder al diccionario
ViewData con la tecla utilizada en el método de acción.
<h2>@ViewData["Message"]</h2>
ViewBag es el equivalente dinámico del diccionario ViewData sin tipo. Aprovecha el tipo dynamic
C # para la experiencia del azúcar sintáctico.
ViewBag.Key = Value;
Entonces, si queremos pasar la cadena de mensaje en nuestro ejemplo anterior usando ViewBag,
será
y en su vista de índice,
<h2>@ViewBag.Message</h2>
Los datos no se comparten entre ViewBag y ViewData. ViewData requiere encasillado para
obtener datos de tipos de datos complejos y buscar valores nulos para evitar errores cuando View
Bag no requiere encasillado.
TempData se puede usar cuando desea conservar datos entre una solicitud http y la siguiente
solicitud HTTP solamente. La vida útil de los datos almacenados en TempDataDictionary finaliza
después de la segunda solicitud. Por lo tanto, TempData es útil en situaciones en las que estás
siguiendo el patrón PRG.
[HttpPost]
public ActionResult Create(string name)
{
// Create a user
// Let's redirect (P-R-G Pattern)
TempData["Message"] = "User created successfully";
return RedirectToAction("Index");
}
public ActionResult Index()
{
var messageFromPreviousCall = TempData["Message"] as String;
// do something with this message
// to do : Return something
}
https://riptutorial.com/es/home 116
"SomeActionMethod" y el navegador le enviará una solicitud totalmente nueva. ViewBag /
ViewData no funcionará en ese caso para compartir algunos datos entre estas 2 llamadas.
Necesitas usar TempData en tales escenarios.
El uso típico se parece a la siguiente secuencia (donde cada línea se invoca desde una solicitud
diferente):
//third request, value is not there as it was deleted at the end of the second request
TempData["value"] == null
Este comportamiento puede ser más controlado con los métodos Peek y Keep .
• Con Peek puede recuperar los datos almacenados en TempData sin marcarlos para
eliminarlos, por lo que los datos seguirán estando disponibles en una futura solicitud.
//second request, PEEK value so it is not deleted at the end of the request
object value = TempData.Peek("value");
• Con Keep , puede especificar que una clave que se marcó para su eliminación debería
conservarse. En este caso, recuperar los datos y guardarlos para eliminarlos requiere 2
llamadas de método:
Con esto en mente, use Peek cuando siempre quiera conservar el valor para otra solicitud y use
Keep cuando el valor se Keep dependiendo de la lógica adicional.
https://riptutorial.com/es/home 117
Lea ViewData, ViewBag, TempData en línea: https://riptutorial.com/es/asp-net-
mvc/topic/1286/viewdata--viewbag--tempdata
https://riptutorial.com/es/home 118
Capítulo 31: Vistas parciales
Introducción
Una vista parcial es una vista que se representa dentro de otra vista. Las vistas parciales se
pueden reutilizar y así evitar la duplicación de código. Pueden ser renderizados por Html.Partial o
Html.RenderPartial
Sintaxis
• @ Html.Partial ("ViewName")
@ {Html.RenderPartial ("ViewName");}
Examples
Vista parcial con modelo.
@model Solution.Project.Namespace.MyModelClass
<p>@Model.Property</p>
<div>
@Html.Partial("PartialViewExample", new MyModelClass(){Property="my property value"})
</div>
<div>
@{ Html.RenderPartial("PartialViewExample", new MyModelClass(){Property="my property
value"}); }
</div>
Llamando a la función
https://riptutorial.com/es/home 119
Función para generar HTML
routeData.Values.Add("controller",
controller.GetType().Name.ToLower().Replace("controller", ""));
controller.ViewData.Model = model;
return sw.ToString();
}
}
@model eDurar.Models.BuyOnlineCartMaster
<h2>hello customer - @Model.CartID </h2>
Html.Partial Vs Html.RenderPartial
Html.Partial devuelve una cadena por otro lado Html.RenderPartial devuelve void.
Html.RenderPartial
Este método devuelve void y el resultado se escribe directamente en el flujo de respuesta HTTP.
Eso significa que usa el mismo objeto TextWriter que se usa en la página web / plantilla actual.
Por este motivo, este método es más rápido que el método parcial. Este método es útil cuando los
datos que se muestran en la vista parcial ya están en el modelo de vista correspondiente.
Ejemplo: en un blog para mostrar los comentarios de un artículo, nos gustaría usar el método
RenderPartial ya que la información de un artículo con comentarios ya está completa en el
modelo de vista.
@{Html.RenderPartial("_Comments");}
https://riptutorial.com/es/home 120
Html.parcial
Este método devuelve una cadena codificada en HTML. Esto se puede almacenar en una
variable. Al igual que el método RenderPartial, el método Parcial también es útil cuando los datos
que se muestran en la vista parcial ya están en el modelo de vista correspondiente.
Ejemplo: en un blog para mostrar los comentarios de un artículo, puede usar el método Parcial,
ya que la información de un artículo con comentarios ya se ha completado en el modelo de vista.
@Html.Partial("_Comments")
https://riptutorial.com/es/home 121
Capítulo 32: Web.config cifrado
Examples
Cómo proteger su archivo web.config
Es una buena práctica cifrar su archivo Web.config si tiene información confidencial allí, por
ejemplo, una cadena de conexión con contraseña.
https://riptutorial.com/es/home 122
Creditos
S.
Capítulos Contributors
No
Dockerización de la
7 SUMIT LAHIRI
aplicación ASP.NET
https://riptutorial.com/es/home 123
Inyección de Adil Mammadov, Andrei Dragotoniu, Cà phê đen, Dave,
14
dependencia PedroSouki
MVC vs Formularios
20 DiegoS, Houssam Hamdan, The_Outsider
Web
Plantillas de
22 Adnan Niloy, SailajaPalakodeti
visualización y editor
Reglas de reescritura
24 SlaterCodes
de IIS
Usando múltiples
26 hasan, Travis Tubbs
modelos en una vista
Validación automática
27 del lado del cliente a Slick86
partir de atributos
https://riptutorial.com/es/home 124
30 Web.config cifrado glaubergft, Jack Spektor
https://riptutorial.com/es/home 125