How to do basic CRUD with Entity Framework 6 in a ASP.NET Web Forms website - webforms

I am in the process of learning Entity Framework 6. I am looking for a tutorial explaining how to setup an ASP.NET Web Forms site (not ASP.NET MVC) and create basic CRUD pages. The only tutorials I can find are based on MVC and/or Console Apps rather than web application.
I am familiar with MVC but I do not want to use MVC for this project. Entity Framework 6 webforms only. All tutorials seem to be based on MVC or they step you through creating a Console App rather than a Web App.
An example of what I am running into is trying to add a simple gridview to a webform page.
It seems this should be a simple procedure but I have not found the code to make it work yet. I think I must be missing a simple step. The page has a gridview named Gridview1. In the code behind I am using:
namespace EFTestSchool.Models
{
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Student db = new Student();
GridView1.DataSource
}
}
}
When I add the .Models to the namespace, it says that the Gridview1 cannot be found. When I use the namespace as simply EFTestSchool, the Gridview1 is recognized but my line Student db = New Student() says Student cannot be found.
The name of my project is EFTestSchool. The name of my model is SchoolModel.
This is based on the standard School database used in some tutorials.
I must be missing something very simple that is preventing me from adding a simple grid to a webform page.
Any suggestions would be appreciated.

I can't think of why you would want to choose ASP.NET Web Forms over the more modern .Net alternatives that there are now. But assuming you have a good reason here is my answer.
Firstly here is a tutorial I found on Entity framework, crud and webforms. The entity framework code is a little out of date now. But if you understand the console app demos that you have mentioned you should be able to see from this how to apply it to webforms.
Going by your description I think what is happening is you are getting confused with how namespaces work. This code will hopefully help with that.
using AnotherNamespace; //this means the code on the page can access the public
//parts of AnotherNamespace
namespace MyNamespace
{
//code in here belongs to MyNamespace
}
Below is a simple example of what I think your code should look like.
First your dbcontext
using EFTestSchool.Models;
using System.Data.Entity;
namespace EFTestSchool.Data
{
public class MyDbContext: DbContext
{
public DbSet<Student> Students { get; set; }
public MyDbContext()
:base("{your connection string}")
{
Database.SetInitializer<MyDbContext>(null);
}
}
}
The student model
namespace EFTestSchool.Models
{
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
}
}
The Default.aspx file
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="EFTestSchool.Default" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<asp:GridView ID="Gridview1" runat="server">
</asp:GridView>
</form>
</body>
</html>
The code behind, i.e. default.aspx.cs
using EFTestSchool.Data;
using System;
using System.Linq;
using System.Web.UI;
using System.Web.UI.WebControls;
using EFTestSchool.Models; //use this in your code to remove the student cannot be found compiler error
namespace EFTestSchool //needs to stay as this or it won't be able to recognise the controls in the aspx file
{
public partial class Default : Page
{
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
using (var ctx = new MyDbContext())
{
var students = ctx.Students.ToList();
Gridview1.DataSource = students;
Gridview1.DataBind();
}
}
}
}
}

Related

Why am I getting "Type does not exist" error adding a new razor page using entity framework

I am experimenting with Visual Studio 2022 and EF Core 6. I created a solution with three projects, one with my razor pages one with my dbcontext and one with my entity. I was able to get the migration working with no issue, creating the database and single table which to me indicates I have everything working properly, but when I go to add a razor page and allow VS to wire up a "List" template for me, it spins for a minute and gives me an error: A type with the name Scaffolding.Entities.EncylopediaEntry does not exist.
Here is the class that apparently doesn't exist
using System.ComponentModel.DataAnnotations;
namespace Scaffolding.Entitites
{
public class EncylopediaEntry
{
public Guid Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
}
And here is the DbContext with a hard coded connection string for now as I'm trying to figure out why scaffolding isn't working
using Microsoft.EntityFrameworkCore;
using Scaffolding.Entitites;
namespace ScaffoldingTest.Data
{
public class ScaffoldingContext : DbContext
{
public DbSet<EncylopediaEntry> encyclopediaEntries { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("{remove}");
}
}
}
I'd got same error. Visual Studio 2022 (preview too) with NET 6.0.
I installed NET 5.0 and tested with new project net 5 then works well.
But not with NET 6.0.

Entity Framework, Ninject dependency injection, and ASP.NET MVC 3, with existing .MDF file as database

I'm making a long and detailed post here, but I sincerely believe it's better to provide as much info up front. If any further clarification is needed, please ask. My heartfelt thanks to you for reading my query.
I'm using the book Pro ASP.NET MVC3 Framework by Adam Freeman and Steven Sanderson (Apress, Third Edition), and working through the Sports Store example beginning with Chapter VII. Note that the project entails the use of DI through the use of Ninject, and this is the main reason I wanted to take the time for this walkthrough. Another impressive contribution in this tutorial is the fact that it shows you how to develop an MVC 3 solution into separate projects the way it might be done in in a real world implementation--a thing I've found to be lacking in just about every other book I've ever looked at. (BTW I think the Apress books are just about the best ones out there, generally speaking.)
OK, so I've worked through Chapter 7 and well into Chapter 8, which means that I've successfully created and populated a database and retrieved its contents to appear in my List view. I've also gotten the formatting to work through the .css file. However, there's a catch here: When going through this the first time, I created the database from the IDE itself, which was no problem because there's only one small table (Products) to worry about. Everything was working fine. But then, for reasons I will shortly make clear, I decided to start over. This time, I wanted to follow through the same walkthrough with the exception that I would access the data by attaching to an existing .MDF file rather than creating a new DB from scratch as I coded the project. All this is to pave the way for me to use a similar pattern for my real project, for which I already have built a complex DB, replete with tables, FK relationships, views, functions--and data. I hardly need to say that I want to use my existing database in my "real" project, because recreating all that from scratch would be virtually impossible.
OK, now let's return to the Sports Store example. Try as I might, I cannot get the data from the database to my UI view. There are no error messages at compile time or run time, but instead of seeing the data in the List view, I see nothing but a blank page. Note that in this case it's correct in that there are no column headings or panes because there isn't any scaffolding here.
As far as I can see I have all the parts I need. Let's begin with the Ninject controller factory:
NinjectControllerFactory : DefaultControllerFactory
{
private IKernel ninjectKernel;
public NinjectControllerFactory()
{
ninjectKernel = new StandardKernel();
AddBindings();
}
protected override
IController GetControllerInstance
(RequestContext requestContext, Type controllerType)
{
return controllerType == null ? null
: (IController)ninjectKernel.Get(controllerType);
}
private void AddBindings()
{
//Had the mockup here before, which worked fine.
ninjectKernel.Bind<IProductRepository>().To<SportsStore2.Domain.Concrete.EFProductRepository>();
} ...
}
IProductRepository is as follows:
namespace SportsStore2.Domain.Abstract
{
public interface IProductRepository
{
IQueryable<Product> Products { get; }
}
}
And EFProductRepository is implemented thus:
namespace SportsStore2.Domain.Concrete
{
public class EFProductRepository:IProductRepository
{
private EFDbContext context = new EFDbContext();
public IQueryable<Product> Products
{
get { return context.Products; }
}
}
}
Why yes, of course EFDbContext is defined; viz the declaration:
namespace SportsStore2.Domain.Concrete
{
class EFDbContext : DbContext
{
public DbSet<Product> Products { get; set; }
}
}
And the connection string in Web.config file; this is supposed to wire up the context object definition with the actual database in the .MDF file, at least as I understand it.
<connectionStrings>
<add name="EFDbContext"
connectionString="Data Source=Owner-PC\SQLEXPRESS;Initial Catalog = SportsStore20130205; Integrated security=SSPI"
providerName="System.Data.SqlClient" />
</connectionStrings>
Last and almost certainly least, I have the Product controller defined as follows. I say "least" because I'm almost positive the problem isn't here. In Debug mode, I can tell that the productRepository object isn't being populated. I can see some SQL code in there which is supposed to be run, or have been run by this point. But the invocation of repository.Products returns nothing.
namespace SportsStore2.WebUI.Controllers
{
public class ProductController : Controller
{
private IProductRepository repository;
public ProductController(IProductRepository productRepository)
{
repository = productRepository;
}
public ViewResult List()
{
return View(repository.Products);
}
public ViewResult Count()
{
int counter = repository.Products.Count();
return View(repository.Products.Count());
}
}
}
namespace SportsStore2.WebUI.Controllers
{
public class ProductController : Controller
{
private IProductRepository repository;
public ProductController(IProductRepository productRepository)
{
repository = productRepository;
}
public ViewResult List()
{
return View(repository.Products);
}
}
}

How can you inject objects into non-controller objects using Ninject 3.0 with ASP.NET MVC3

I have an MVC3 project that I am using Ninject to inject an Entity Framework context into. I am using the Ninject package (3.0.0.15), Ninject.MVC3 (3.0.0.6), and Ninject.Web.Common (3.0.0.7). Everything is working really great, except when I try to inject into a WebForms code behind file. I am assuming that this is because I don't have something wired in correctly, but am not sure at how to wire it in. Ninject is also not working in files that Razor instantiates.
Here is my code for my Code Behind:
[Inject]
public IDbContext DataContext { get; set; }
The Context property comes out null every time. It worked just fine until I updated to Ninject 3.0.
My start method is as follows:
public static void Start()
{
DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
Bootstrapper.Initialize(CreateKernel);
}
Any ideas on how to make Ninject inject the DataContext into the WebForm and into classes instantiated by Razor?
For this to work you need to install the Ninject.Web NuGet (the latest version at the time of this writing is 3.0.0.5) and then have your webform derive from Ninject.Web.PageBase instead of System.Web.UI.Page:
public partial class WebForm1 : Ninject.Web.PageBase
{
[Inject]
public IDbContext Ctx { get; set; }
protected void Page_Load(object sender, EventArgs e)
{
}
}
Also notice that I used Ctx as property name because there's already a property called Context on the System.Web.UI.Page class that you are hiding (you should have gotten a compile time warning).

MVC3 ViewModel namespace Question

I am trying to create a ViewModel class. After I created class in "ViewModels" folder. My List type declaration are not recognized. My questions and code is below:
Are there some special way of creating ViewModel Classes?
Are ViewModels a methodology, rather than a feature in MVC3?
Can someone please tell me what I have missed thanks -P
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MvcApplication8.ViewModels
{
//compiler does not recongize List class or SelectListitem
private List<SelectListItem> _products = new List<SelectListItem>();
//compiler does not recongize List class
public List<SelectListItem> products
{
get { return _products; }
}
}
Are there some special way of creating ViewModel Classes?
No, create them like creating any other class. The convention is to place them in the Models folder.
Are ViewModels a methodology, rather than a feature in MVC3?
Kind of. They're not a feature of the framework itself, but a recommendation to keep your View's simple and clean, and simplify model binding.
Can someone please tell me what I have missed thanks
Where's your class declaration?
namespace MvcApplication8.ViewModels
{
public class ThisIsTheClassNameAndMustGoFirst
create a new empty MVC 3 project, using Razor.
add a class definition under Models folder, i.e:
namespace MvcApplication1.Models
{
public class WhateverNameYouWantModel
{
public string Foo { get; set; }
public string Bar { get; set; }
}
}
right click on Controllers folder and add a new controller. the name must end with "Controller". don't bother checking option to add action methods. the controller would look like this:
using System.Web.Mvc;
using MvcApplication1.Models;
namespace MvcApplication1.Controllers
{
public class HelloController : Controller
{
public ActionResult Index()
{
return View(new WhateverNameYouWantModel());
}
}
}
right click on the Index() signature above and choose "Add View". Make sure nothing is checked, the view name matches the action name "Index" and Razor is the engine. add the model type at the top:
#model MvcApplication1.Models.WhateverNameYouWantModel
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<title>Index</title>
</head>
<body>
<div>hello world!</div>
</body>
</html>
set the mvc project as your startup project, press F5, the browser will open to http://localhost:xxxx now you will need to point to http://localhost:xxxx/Hello/Index
In asp.net mvc names are everything between the views, actions and controllers. Its all convention, you don't need to stick to it but if you don't you are gonna have to do some extra plumbing.

asp.net mvc3 and multi-level navigation

i am writing new asp.net mvc application and i have question about creating multi-level navigation system.
For example i have web with main navigation (Cpu --- Gpu ---- Ram)
and sub-navigation with (intel,amd --- ati,nvidia --- DDR2,DD3)
Well, my first implementation is here :
public class NavigationItem
{
public virtual int Id { get; set; }
public virtual string Title { get; set; }
public virtual string Controller { get; set; }
public virtual string Action { get; set; }
public virtual string Url { get; set; }
public virtual string Section { get; set; }
}
public class NavigationController : Controller
{
private readonly IUnitOfWork _unitOfWork;
public NavigationController(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}
public ActionResult MainMenu()
{
return View(_unitOfWork.NavigationItems.Where(x => x.Section == null).ToList());
}
public ActionResult SectionMenu()
{
return View(_unitOfWork.NavigationItems.Where(x => x.Section == "// name of section").ToLis());
}
}
And finally my layout page is :
<!DOCTYPE html>
<html>
<head>
<title>#ViewBag.Title</title>
</head>
<body>
<div class="main-menu">
#{Html.RenderAction("MainMenu", "Navigation");}
</div>
<div class="section-menu">
#{Html.RenderAction("SectionMenu", "Navigation");}
</div>
#RenderBody()
</body>
</html>
With this implementation i have problem how i handle in SectionMenu with MainMenu is active, because i want generate SectionMenu depends on MainMenu and highlight them.
One workaround of witch i think is handle url(controller) in SectionMenu.
For example :
if (RouteData.Values["controller"].ToString() == "Administration")
{
// Generate section menu for Administration main menu
}
I dont like this solution because i work with "magic string" values and i havent only one controller per one MainMenu.
How implement this solution?
Thanks for advice
I guess you have to get deeper into MVC's routing system. It doesn't look very straightforward in the beginning, but this is probably the most important area of the entire MVC. Sometimes though you can easily get confused especially if you have many routes defined in Global.asax. There is a project called Route debugger, it helps. I don't remember the link. Try to google it... If you can't find it I'll send the link later...
Ok, I use ViewBag feature. Not clean, but works

Resources