I'm fairly new to razor pages Asp.Net MVC Razor pages,
I created a model with the user fields and wanted to fill it with data once i logged in and access that same data in other pages by calling on the model instead of making another db call
This is my code currently
Model:
public class Utilizador
{
[Key]
public int id { get; set; }
[Required, MaxLength(100)]
public string username { get; set; }
[Required, MaxLength(100)]
public string email { get; set; }
[Required, MaxLength(100)]
public string password { get; set; }
}
then i added a sigleton to Program.cs
builder.Services.AddSingleton<Utilizador>();
You can store your data in the Session or Cache during the first login verification, and then you can call the data directly from the Session without calling the database again.
My test code:
Utilizador.cs:
public class Utilizador
{
public int id { get; set; }
public string username { get; set; }
public string test { get; set; }
}
Startup.cs:
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
services.AddScoped<Utilizador>();
services.AddSession();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// other middleware
app.UseSession();
// other middleware
}
Test1.cshtml.cs:
public class Test1Model : PageModel
{
private readonly Utilizador _Utilizador;
private Utilizador model { get; set; }
public Utilizador getValue { get; set; }
public Test1Model(Utilizador Utilizador)
{
_Utilizador=Utilizador;
}
public async Task<IActionResult> OnGetAsync(int id)
{
if (id == 1)
{
_Utilizador.username = "MyTest";
_Utilizador.test = "Success";
}
else
{
_Utilizador.username = "MyTest";
_Utilizador.test = "Fail";
}
model = _Utilizador;
HttpContext.Session.Set<Utilizador>(id.ToString(),model);
getValue=HttpContext.Session.Get<Utilizador>(id.ToString());
return Page();
}
}
Get data directly from the corresponding page:
Test1.cshtml:
#page
#model CacheTest.Pages.TestPage.Test1Model
<div>#Model.getValue.username</div>
<div>#Model.getValue.test</div>
Test2.cshtml.cs:
public class Test2Model : PageModel
{
public Utilizador getValue { get; set; }
public void OnGet(int id)
{
getValue = HttpContext.Session.Get<Utilizador>(id.ToString());
}
}
Test2.cshtml:
#page
#model CacheTest.Pages.TestPage.Test2Model
<div>#Model.getValue.username</div>
<div>#Model.getValue.test</div>
Test Result
In Test1, store first and then read:
Directly read the data stored in the session in Test2:
You could try with EF Core,the official document:
https://learn.microsoft.com/en-us/aspnet/core/tutorials/razor-pages/page?view=aspnetcore-6.0&tabs=visual-studio
https://learn.microsoft.com/en-us/aspnet/core/tutorials/razor-pages/sql?view=aspnetcore-6.0&tabs=visual-studio
Related
I am trying to use MVC with a controller a view a model and the database.
But I premise I do not know how to use entity framework in my case to connect the model and the database. So I get this runtime error:
"InvalidOperationException: Unable to resolve service for type 'WebCoreFly.Models.FlightsList' while attempting to activate 'WebCoreFly.Controllers.HomeController"
My code consists in:
the controller code:
public class HomeController : Controller
{
private FlightsList l;
public HomeController(FlightsList theList)
{ l = theList; }
public ViewResult Index()
{
return View(l.Flights);
}
}
the Model Code for Flights:
public partial class Flights
{
public long ID { get; set; }
public long Id_Destination { get; set; }
public string Id_Source { get; set; }
public string Nome { get; set; }
public string Company { get; set; }
public System.DateTime Time { get; set; }
public string Id_Plane { get; set; }
public Nullable<System.DateTime> TimeOfArrival { get; set; }
}
and the model for FlightsList:
public class FlightsList
{
private FlyDBContext context;
public FlightsList(FlyDBContext ctx)
{
context = ctx;
}
public IQueryable<Flights> Flights => context.Flights;
}
finally I have defined my dbcontext:
public class FlyDBContext : DbContext
{
public FlyDBContext(DbContextOptions<FlyDBContext> options)
: base(options)
{
}
public DbSet<WebCoreFly.Models.Passengers> Passengers { get; set; }
public DbSet<WebCoreFly.Models.Bookings> Bookings { get; set; }
public DbSet<WebCoreFly.Models.Flights> Flights { get; set; }
}
And in my startup code, I configure services to accept my dbcontext with a link to Existing SQL Database called Fly:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddDbContext<FlyDBContext>(options =>
options.UseSqlServer(#"Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=Fly;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False"));
}
And this is the Configure method of startup:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseBrowserLink();
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
My question is: who is responsible to pass to my controller the flights list? and since the flightlist is tied to the dbcontext, is the problem somehow related to the fact I did not use entityframework? (For semplicity Idid not post the code for my view, but I can do it if necessary)
the issue is coming because of the dependency Injection. Here How the application would know that Flights List object requires in Home Controller. To fix this you have to configure it in StartUp.Cs class Configure Service method.
services.AddSingelton<FlightsList>();
There are various ways to configure it like Transient, AddScoped etc.
It is better if you use repository pattern here. Register here the Interface. like following.
services.AddSingelton<IRepository, FlightsList>();
In controller side.
public class HomeController : Controller
{
private IRepository l;
public HomeController(IRepository theList)
{ l = theList; }
public ViewResult Index()
{
return View(l.Flights);
}
}
Hope it will help.
I am trying to make a sample application using code first approach in MVC so I don't have any database. Now I have setup all class files and context class. In next step I have created a controller(Emplty) and want to create own Create/List/Delete functionalities. How can I do it.
Some of the codes are below
public class Employee
{
public int EmployeeID { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public int DepartmentID { get; set; }//Foreign Key
public virtual ICollection<Enrollment> Enrollments { get; set; }
}
public class Department
{
public int DepartmentID { get; set; }
public string DepartmentName { get; set; }
public virtual ICollection<Enrollment> Enrollments { get; set; }
}
public class EmployeeDBContext: DbContext
{
public EmployeeDBContext()
: base("EmployeeDBContext")//EmployeeDBContext will be name of database.
{ }
public virtual DbSet<Employee> Employees { get; set; }
public virtual DbSet<Department> Departments { get; set; }
public virtual DbSet<Enrollment> Enrollments { get; set; }
}
public class EmployeeInitializer:DropCreateDatabaseIfModelChanges<EmployeeDBContext>
{
protected override void Seed(EmployeeDBContext context)
{
var employee = new List<Employee>
{
new Employee{EmployeeID=1, Name="Aman", Age=15, DepartmentID=11},
new Employee {EmployeeID=2, Name="Supriya", Age=12, DepartmentID=22},
new Employee {EmployeeID=3, Name="Rishabh", Age=10, DepartmentID=44}
};
employee.ForEach(x => context.Employees.Add(x));
context.SaveChanges();
var department = new List<Department> {
new Department{DepartmentID=11, DepartmentName="IT"},
new Department{DepartmentID=22, DepartmentName="HR"},
new Department{DepartmentID=33, DepartmentName="Mechanical"},
new Department{DepartmentID=44, DepartmentName="NGO"}
};
department.ForEach(x=>context.Departments.Add(x));
context.SaveChanges();
var enrollment = new List<Enrollment>() {
new Enrollment{EnrollmentID=111, EmployeeID=1, DepartmentID=11},
new Enrollment{EnrollmentID=222, EmployeeID=3, DepartmentID=44},
new Enrollment{EnrollmentID=333, EmployeeID=2, DepartmentID=22}
};
enrollment.ForEach(x=>context.Enrollments.Add(x));
context.SaveChanges();
}
}
I wish to add code from below controller onward
public ActionResult CreateEmployee(Employee employee)
{
//my desired code here
return View();
}
[HttpGet]
public ActionResult ListEmployee()
{
//my desired code here
return View();
}
you mean how to do something like:
[HttpGet]
public ActionResult ListEmployee()
{
//my desired code here
using(var context=new EmployeeDBContext())
{
return View(context. Employee.ToList());
}
}
[HttpPost]
[Route("api/Employee/CreateEmployee")]
public ActionResult CreateEmployee([FromBody]Employee employee)
{
//add to ef
_db.Add(employee);
_db.SaveChanges();
//my desired code here
return Ok();
}
I hate these kind of errors.
I have an ASP.NET Core MVC form. When I submit the form I get the dreaded "No parameterless constructor defined for this object." error.
I can't seem to hit anything in the debugger to help me find where I have went wrong.
My controller:
using Brand.Extensions;
using Brand.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace Brand.Controllers
{
public class ContentController : Controller
{
public IActionResult Index()
{
return View();
}
[HttpGet]
public IActionResult Upload()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Upload(UploadedContentModel uploadedContentModel, FormCollection formCollection, IFormFileCollection uploadedFiles)
{
ContentExtensions contentExtensions = new ContentExtensions();
FileExtensions fileExtensions = new FileExtensions();
FileModel file = new FileModel();
file = fileExtensions.GetFileModel(uploadedFiles["File"]);
uploadedContentModel.File = fileExtensions.UploadFile(file).ID;
FileModel thumbnail = new FileModel();
thumbnail = fileExtensions.GetFileModel(uploadedFiles["Thumbnail"]);
uploadedContentModel.Thumbnail = fileExtensions.UploadFile(thumbnail).ID;
uploadedContentModel.ID = contentExtensions.UploadContent(uploadedContentModel).ID;
return View();
}
}
}
My model:
public class UploadedContentModel
{
public Guid ID { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public Guid File { get; set; }
public Guid Thumbnail { get; set; }
public string ContentType { get; set; }
public string Solutions { get; set; }
public string Industries { get; set; }
public string AdditionalTags { get; set; }
public DateTime Publish { get; set; }
public DateTime Expire { get; set; }
public string AuthorizedRoles { get; set; }
public string Author { get; set; }
public DateTime Created { get; set; }
}
Im having trouble linking my loaned items to my Library for each customer. It does it fine when it goes through the "AddToLibrary" method but when it comes to retreiving it, the medialibrary is empty and the query in the IEnumerable<Item> ItemsOnLoan method is returning null. This is a very basic ASP.NET MVC 4 application and im very new to this so its probably something silly ive missed out.
I just want to be able to add an item to the loaned items table, have the list of loaned items for each customer appear in their personal Library (defined in model) and then retreive the list of their items. Below is all the code and I am using a code first approach. Thank you :)
Model
public class Customer
{
public int Id { get; set; }
public string ForeName { get; set; }
public string SurName { get; set; }
public Address address { get; set; }
public string Email { get; set; }
public string Telephone { get; set; }
public string Mobile { get; set; }
public List<LoanedItem> Library { get; set; }
public Customer()
{
if (Library == null || Library.Count == 0)
{
Library = new List<LoanedItem>();
}
}
public IEnumerable<Item> ItemsOnLoan
{
get
{
var items = (from i in Library
where i.Customer.Id == this.Id
select i).OfType<item>();
return items;
}
}
}
Loaned Item model
public class LoanedItem
{
public int? Id { get; set; }
public Customer Customer { get; set; }
public MediaItem Item { get; set; }
}
ItemController --> adding to library method
public ActionResult AddToLibrary(int id)
{
Item libraryItem = db.Items.Find(id);
Customer c = db.Customers.Find(1);
LoanedItem newLoanGame = new LoanedItem()
{
Customer = c,
Item = libraryItem
};
db.LoanedItems.Add(newLoanGame);
db.SaveChanges();
return RedirectToAction("Index");
}
Customer Controller
public ActionResult ViewProfile(int id = 1)
{
Customer c = db.Customers.Find(id);
if (c == null)
{
return HttpNotFound();
}
return View(c);
}
public ActionResult GetLibraryItems(int id = 1)
{
var items = db.Customers.Find(id).ItemsOnLoan;
return View(items);
}
Context
public class LibraryContext : DbContext
{
public DbSet<Address> Addresses { get; set; }
public DbSet<Customer> Customers { get; set; }
public DbSet<LoanedItem> LoanedItems { get; set; }
public DbSet<Item> Items { get; set; }
public LibraryContext()
: base("LbContext")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new CustomerConfiguration());
modelBuilder.Configurations.Add(new LoanedItemConfiguration());
modelBuilder.Entity<Item>();
modelBuilder.Entity<Address>();
base.OnModelCreating(modelBuilder);
}
}
Assuming that Proxy generation is enabled try this:
public class Customer
{
public int Id { get; set; }
public string ForeName { get; set; }
public string SurName { get; set; }
public Address address { get; set; }
public string Email { get; set; }
public string Telephone { get; set; }
public string Mobile { get; set; }
public virtual ICollection<LoanedItem> ItemsOnLoan { get; set; }
public Customer()
{
}
}
using this to acccess:
public ActionResult GetLibraryItems(int id = 1)
{
var customer = db.Customers.Find(id);
if (customer != null)
{
var items = customer.ItemsOnLoan;
return View(items);
}
//handle not found or throw an exception
throw new Exception();
}
follow this link for more information on Proxies and Lazy Loading.
I have an ASP.NET MVC application which uses Entity Framework to get data.
I need to transform Entites to Models before passing them to View. Projections can be very complex, but to keep it simple:
public static IQueryable<UserModel> ToModel(this IQueryable<User> users)
{
return from user in users
select new UserModel
{
Name = user.Name,
Email = user.Email,
};
}
This can be used in a controller like this:
return View(Repository.Users.ToModel().ToList());
Very good. But what if I want to use this projection inside another one? Example:
public static IQueryable<BlogPostModel> ToModel(this IQueryable<BlogPost> blogs)
{
return from blogs in blogs
select new BlogPostModel
{
Title = blog.Title,
Authors = blog.Authors.AsQueryable().ToModel(), // (entities are POCOs)
// This does not work, because EF does not understand method ToModel().
};
}
(let's suppose blog can have more then one author and it is of type User).
Can I somehow separate the projections and reuse them inside another ones?
Here's something that actually works (in a simple test application) to only select the requested fields:
namespace Entities
{
public class BlogPost
{
public virtual int Id { get; set; }
public virtual string Title { get; set; }
public virtual DateTime Created { get; set; }
public virtual ICollection<User> Authors { get; set; }
}
public class User
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual string Email { get; set; }
public virtual byte[] Password { get; set; }
public virtual ICollection<BlogPost> BlogPosts { get; set; }
}
}
namespace Models
{
public class BlogPostModel
{
public string Title { get; set; }
public IEnumerable<UserModel> Authors { get; set; }
}
public class UserModel
{
public string Name { get; set; }
public string Email { get; set; }
}
public static class BlogPostModelExtensions
{
public static readonly Expression<Func<BlogPost, BlogPostModel>> ToModelConverterExpression =
p =>
new BlogPostModel
{
Title = p.Title,
Authors = p.Authors.AsQueryable().Select(UserModelExtensions.ToModelConverterExpression),
};
public static readonly Func<BlogPost, BlogPostModel> ToModelConverterFunction = ToModelConverterExpression.Compile();
public static IQueryable<BlogPostModel> ToModel(this IQueryable<BlogPost> blogPosts)
{
return blogPosts.Select(ToModelConverterExpression);
}
public static IEnumerable<BlogPostModel> ToModel(this IEnumerable<BlogPost> blogPosts)
{
return blogPosts.Select(ToModelConverterFunction);
}
}
public static class UserModelExtensions
{
public static readonly Expression<Func<User, UserModel>> ToModelConverterExpression =
u =>
new UserModel
{
Name = u.Name,
Email = u.Email,
};
public static readonly Func<User, UserModel> ToModelConverterFunction = ToModelConverterExpression.Compile();
public static IQueryable<UserModel> ToModel(this IQueryable<User> users)
{
return users.Select(ToModelConverterExpression);
}
public static IEnumerable<UserModel> ToModel(this IEnumerable<User> users)
{
return users.Select(ToModelConverterFunction);
}
}
}
To test it without actually creating a database:
var blogPostsQuery = (
from p in context.BlogPosts
where p.Title.StartsWith("a")
select p).ToModel();
Console.WriteLine(((ObjectQuery)blogPostQuery).ToTraceString());