Varias formas de pasar valores de Controller a View en MVC
Directorio de artículos
1. Ver modelo
ViewModel es una clase fuertemente tipada que se usa para representar vistas de ASP.NET MVC y se puede usar para pasar datos de uno o más modelos de vista (es decir, clases) o tablas de datos. Piense en ello como un puente que conecta el modelo, los datos y la vista. su 生命期为当前视图
_ El modelo de vista está fuertemente tipado, por lo que hay sugerencias inteligentes y detección estática en VS.
Usar modelo de vista
Primero cree una clase de modelo de vista para representar la vista:
public class Student
{
public int ID {
get; set; }
public string Name {
get; set; }
public DateTime Birth {
get; set; }
}
Defina esta clase en su controlador:
public IActionResult Index()
{
Student student=new Student()
{
ID = 1,
Birth = new DateTime(2000,1,1),
Name = "test"
};
return View(student);
}
utilizado en la vista
Razor视图
Úselo al principio @model
para especificar un tipo fuerte, y una vista que usa @model
se llama una vista fuertemente tipada, y una vista fuertemente tipada puede obtener inteligencia y verificación estática. Si no usa @mdoel
, el siguiente @Model
es un tipo dinámico y no obtendrá sugerencias inteligentes ni comprobaciones estáticas.
Al mismo tiempo, un Modelo fuertemente tipado puede usar métodos auxiliares, mientras que un Modelo débilmente tipado no puede usar métodos auxiliares, porque los árboles de expresión C# no pueden contener operaciones dinámicas.
Vista de índice:
@model Student
<div>
@Html.DisplayNameFor(m=>m.ID)
@Html.DisplayFor(m=>m.ID)
</div>
<div>
Birth @Model.Birth
</div>
<div>
Name @Model.Name
</div>
Vista fuertemente tipada:
Las vistas débilmente tipeadas carecen de inteligencia:
Dos, Ver datos
ViewData
es un Dictionary<string,object>
diccionario cuyos datos se almacenan en forma de pares clave-valor ViewData
. ViewData
Se utiliza para pasar datos entre controladores y vistas, y entre vistas y vistas parciales. Su vida útil es el final de la representación de la vista actual. Dado que ViewData
se devuelve un objeto cuando se usa object
, se requiere una conversión para aplicar el tipo real de propiedad o valor. No se requiere conversión cuando los datos pasados se usan en la vista como una cadena, porque c#
cada objeto tiene un método que se llama automáticamente ToString
en la vista.c#
Además de las definiciones directas ViewData[""]
, las definiciones de atributos ASP.NET Core
son compatibles con las propiedades de los controladores .
[TempData]
ViewData
Sin embargo, ViewData
no se puede usar en situaciones de solicitud cruzada, es decir, la página posterior al salto no puede usar la definición de la página anterior al salto ViewData
, y la siguiente mencionada TempData
se puede usar para la transferencia de datos de solicitud cruzada.
Use ViewData para pasar datos entre el controlador y la vista
public IActionResult ViewDataTest()
{
ViewData["student"]=new Student()
{
ID = 1,
Birth = DateTime.Now,
Name = "test"
};
ViewData["Greeting"] = "Hello";
return View();
}
Usar los datos de ViewData en la vista ViewDataTest
@{
Student student = ViewData["student"] as Student;
ViewData["test"] = "test";
}
@ViewData["greeting"]
<div>ID: @student.ID</div>
<div>Name: @student.Name</div>
<div>Birth: @student.Birth</div>
<br/>
@Html.ActionLink("Test","Test")
Método de prueba y vista para probar entre solicitudes:
public IActionResult Test()
{
return View();
}
@{
ViewData["Title"] = "Test";
}
<h2>Test</h2>
@ViewData["test"]
Use directamente las propiedades de los datos en ViewData:
cuando se usa entre una vista y una vista parcial ViewData
, la definición en la vista parcial ViewData
no sobrescribirá la vista original ViewData
. Al pasar entre vistas y vistas parciales , ViewData
se utilizan los PartialAsync
métodos auxiliares principales y <partial>
los métodos auxiliares de marcado .
Uso de ViewData entre vistas y vistas parciales
public static Task<IHtmlContent> PartialAsync(this IHtmlHelper htmlHelper, string partialViewName, ViewDataDictionary viewData)
El primer parámetro se pasa en 部分视图名称
, y el segundo parámetro se pasa en uno ViewDataDictionary 对象
. Si no se especifica el segundo parámetro, la vista actual se pasará ViewData
a la vista parcial.
ViewDataTest2 vista:
<h2>ViewDataTest2</h2>
@{
ViewData["Student"] = new Student()
{
ID = 1,
Birth = DateTime.Now,
Name = "test"
};
ViewData["Greeting"] = "Good morning";
}
View: @ViewData["Greeting"]
<br/>
@await Html.PartialAsync("PartialView",new ViewDataDictionary(ViewData))
View: @ViewData["Greeting"]
vista vista parcial:
@{
Student student = ViewData["Student"] as Student;
}
Partial: @ViewData["Greeting"]
<hr/>
<div>ID: @student.ID</div>
<div>Name: @student.Name</div>
<div>Birth: @student.Birth</div>
<hr/>
@{
ViewData["Greeting"] = "Good afternoon";
}
<div>Partial: @ViewData["Greeting"]</div>
Utilice el método auxiliar de etiquetas parciales:
Acerca del método auxiliar de marcado parcial: https://docs.microsoft.com/en-us/aspnet/core/mvc/views/partial?view=aspnetcore-2.1
Cuando se use, pase el nombre de la vista parcial para el atributo de nombre y el nombre del objeto view-data
para el atributo ViewDataDictionary
:
<h2>ViewDataTest2</h2>
@{
ViewData["Student"] = new Student()
{
ID = 1,
Birth = DateTime.Now,
Name = "test"
};
ViewData["Greeting"] = "Good morning";
}
View: @ViewData["Greeting"]
<br/>
@*@await Html.PartialAsync("PartialView",new ViewDataDictionary(ViewData))*@
<partial name="PartialView" view-data="ViewData" />
View: @ViewData["Greeting"]
El resultado es consistente con el uso PartialAsync
del método auxiliar.
3. VerBolsa
ViewBag
ViewData
es un tipo dinámico que se ajusta ControllerBase
y se hereda de , por lo que no se puede usar en las páginas de visualización ViewBag
. Dado que ViewBag
es un objeto dinámico, puede agregarle propiedades arbitrarias. Además, debido a que ViewBag
es un tipo dinámico, puede llamar directamente a sus propiedades para operar.
ViewBag
La diferencia entre y ViewData
es:
- No es posible pasar un ViewBag específico en la página de vista.
- Aunque ViewBag se puede definir en la vista para usar en la vista actual, no se puede definir para pasar a vistas parciales.
ViewBag no está disponible en las páginas de Razor.
Ver datos
- Derivado de
ViewDataDictionary
, por lo que tiene atributos de diccionario disponibles comoContainsKey、Add、Remove
yClear
. Las claves del diccionario son cadenas, por lo que se permiten espacios.ViewData["Some Key With Whitespace"]
- Cualquier elemento que no sea de
string
tipo debe convertirse en la vista antes de que pueda usarseViewData
.
VerBolsa
- Derivado de
DynamicViewData
, por lo que puede usar la notación de puntos(@ViewBag.SomeKey = <value or object>)
para crear propiedades dinámicas sin conversión. La sintaxis de ViewBag hace que agregar controladores y vistas sea mucho más rápido. (en realidad casi) - Es más fácil comprobar los valores NULL.
@ViewBag.Person?.Name
public IActionResult ViewBagTest()
{
ViewBag.Student = new Student()
{
ID = 1,
Birth = new DateTime(1997,1,1),
Name = "test"
};
return View();
}
ViewBagTest vista:
<h2>ViewBagTest</h2>
<div>View: @(ViewBag.Student.ID+1)</div>
@await Html.PartialAsync("_ViewBagPartial")
_ViewBagVista parcial:
<div>ID: @ViewBag.Student.ID</div>
<div>Name: @ViewBag.Student.Name</div>
<div>Birth: @ViewBag.Student.Birth</div>
4, datos temporales
TempData
es un System.Web.Mvc.TempDataDictionary
tipo heredado de y es un Dictionary<string,object>
diccionario de . El tiempo de vida es desde el comienzo de la vida en el controlador TempData
hasta el final cuando se lee, incluso si se redirige a otro método de controlador, siempre que TempData
no se lea, todavía existe. TempData
Al actualizar una página que se ha visitado TempData
, se volverá a visitar la página y TempData
se eliminará la vigencia no extendida. TempData
Normalmente se usa para pasar datos (como mensajes de error) entre métodos de acción.
Si desea conservar el objeto después de un acceso TempData
, debe llamar al método en el método del controlador TempData.Keep
o usar el método en la vista TempData.Peek
para acceder TempData
al objeto. Sin embargo, debe tenerse en cuenta que el método no extenderá la vida útil del objeto TempData.Keep
al que se accede en la vista redirigida . TempData
Una vista redirigida es RedirectXXX
una vista alcanzada usando .
Dado que TempData
se guarda en ASP.NET
el archivo , debe usarse con precaución y puede ser problemático Session
cuando se aloja la aplicación en varios servidores . TempData
Para resolver este problema, puede optar por session
asignar todas las solicitudes de los usuarios al mismo servidor durante la vida útil del servidor o reenviar session
información entre servidores.
Además de usar TempData[""]
para TempData
definir, también puede usar para [TempData]
modificar atributos para TempData
definir.
public IActionResult TempDataTest()
{
TempData["error"] = "An error";
TempData["greeting"] = "Hello";
//将 TempData["error"] 生存期延长一次
TempData.Keep("error");
return View();
}
public IActionResult ReceiveTempData()
{
return View();
}
public IActionResult ReceiveTempData2()
{
return View();
}
Vista TempDataTest:
@{
ViewData["Title"] = "TempDataTest";
}
<h2>TempDataTest</h2>
<div>@TempData["error"]</div>
@*访问 TempData["greeting"] 并将 TempData["greetng"] 延长一次*@
<div>@TempData.Peek("greeting")</div>
<br/>
<div>@Html.ActionLink("Another", "Index", "TempData")</div>
@Html.ActionLink("ReceiveTempData","ReceiveTempData")
La vista ReceiveTempData utilizada para probar entre solicitudes:
@{
ViewData["Title"] = "ReceiveTempData";
}
<h2>ReceiveTempData</h2>
<div>@TempData["error"]</div>
@*将 TempData["greetng"] 生命期延长一次*@
<div>@TempData.Peek("greeting")</div>
<br/>@Html.ActionLink("ReceiveTempData2", "ReceiveTempData2")
Vista ReceiveTempData2:
@{
ViewData["Title"] = "ReceiveTempData2";
}
<h2>ReceiveTempData2</h2>
<div>@TempData["error"]</div>
<div>@TempData["greeting"]</div>
Otro controlador TempDataController:
public class TempDataController : Controller
{
public IActionResult Index()
{
return View();
}
}
La vista de índice para este controlador:
@{
ViewData["Title"] = "Index";
}
<h2>Index</h2>
<div>@TempData["error"]</div>
resultado:
Usar redirección:
public IActionResult TempDataTest()
{
TempData["error"] = "An error";
TempData["greeting"] = "Hello";
TempData.Keep("error");
//return View();
return RedirectToAction("ReceiveTempData");
}
Resultado:
TempData["error"] que debería haberse extendido no lo fue.
5. Sesión
session
es Web.SessionState
un objeto clave-valor heredado de . Pasar datos entre controladores, que se pueden usar para pasar datos entre controladores y vistas a través de estados de solicitud. Por lo general, se Session
usa para guardar datos de un usuario específico, pero es mejor no colocar datos confidenciales en él. El tiempo de vida dura hasta que es destruido explícitamente por timeout
un evento vinculado por el parámetro, llamando al método o cerrando el navegador. Clear、RemoveAll、Abandon
Es mejor reducir Session
el uso de porque no es confiable en entornos de clúster de servidores y siempre ocupará recursos del servidor mientras está en uso.
Session
Debe Startup.cs
configurarse cuando se usa (detalles de configuración).
Instrucciones:
Aquí establecemos el tiempo de caducidad de la sesión en 5 segundos, que se calcula después de cada operación.
En el método ConfigureServices:
services.AddDistributedMemoryCache();
services.AddSession(options =>
{
options.IdleTimeout = TimeSpan.FromSeconds(5);
options.Cookie.HttpOnly = true;
});
En el método Configurar:
app.UseSession();
app.UseMvc();
El orden del middleware es importante.
Se produce una excepción cuando se UseMvc
llama después de .UseSession
InvalidOperationException
En la implementación predeterminada de ASP.NET Core, los métodos para obtener y configurar flujo de bytes, int y datos de cadena se proporcionan en Sesión, respectivamente:
Get(ISession, String)
GetInt32(ISession, String)
GetString(ISession, String)
SetInt32(ISession, String, Int32)
SetString(ISession, String, String)
Por conveniencia, implemente un método de extensión genérico de Set
y respectivamente:Get
ISession
public static void Set<T>(this ISession session, string key, T value)
{
session.SetString(key, JsonConvert.SerializeObject(value));
}
public static T Get<T>(this ISession session, string key)
{
var value = session.GetString(key);
return value == null ? default(T) : JsonConvert.DeserializeObject<T>(value);
}
En el controlador:
//用来获取和设置值的键
public const string SessionKeyStudent = "_Student";
public string AddSession()
{
if (HttpContext.Session.Get<Student>(SessionKeyStudent)==default(Student))
{
Student student=new Student()
{
Birth = new DateTime(1996,1,1),
ID = 2,
Name = "test"
};
HttpContext.Session.Set<Student>(SessionKeyStudent,student);
}
return "Session has been set";
}
public IActionResult SessionTest()
{
Student student = HttpContext.Session.Get<Student>(SessionKeyStudent) ?? new Student();
return View(student);
}
Vista de prueba de sesión:
@model Student
@{
ViewData["Title"] = "SessionTest";
}
<h2>SessionTest2</h2>
<div>ID: @Model.ID</div>
<div>Name: @Model.Name</div>
<div>Birth: @Model.Birth</div>