Database first MVC, object not populating - asp.net-mvc

I have to use the Database first approach, the solution has 3 projects. 2 are class libraries the third is the actual MVC project. One class library has the edmx designer. The other has Has different model classes. These 2 libraries are referenced by the MVC project. My problem is that the object is not populating values. I guess it is a naming conflict somewhere. The object tblRDBUser is not getting populated. There is a table in the database with the same object name too. The object attributes match the column names too. I am not getting the values from the view into the controller.
Project one:
RDB.DataModel, it contains the EDMX designer.
Project two: RDB.Models
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using RDB.DataModel;
public class Authenticate
{
public string AuthenticateUser(tblRDBUser User)
{
Book_TradEntities users = new Book_TradEntities();
return (from p in users.tblRDBUsers where p.UserName == User.UserName && p.Password == User.Password select p.UserName).FirstOrDefault();
}
}
Project 3:
View:
#model RDB.DataModel.tblRDBUser
#{
ViewBag.Title = "Index";
}
#Html.TextBoxFor(a => a.UserName)
#Html.TextBoxFor(a => a.Password)
#Html.ActionLink("Login", "Authenticate");
Controller:
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using RDB.DataModel;
using RDB.Models;
namespace CignaRDB.Controllers
{
public class RDBWebController : Controller
{
//
// GET: /RDBWeb/
public ActionResult Index()
{
return View();
}
public ActionResult Authenticate(tblRDBUser User)
{
if (ModelState.IsValid)
{
Authenticate user = new Authenticate();
user.AuthenticateUser(User);
return View();
}
return View();
}
}
}

The main problem. that you create link #Html.ActionLink("Login", "Authenticate") which after click on him just redirect user to Authenticate method. Insted of a link you should generate button which make submit of you form. So your view code should be something like this
#model RDB.DataModel.tblRDBUser
#{
ViewBag.Title = "Index";
}
#using (Html.BeginForm("Authenticate"))
{
#Html.TextBoxFor(a => a.UserName)
#Html.TextBoxFor(a => a.Password)
<input type="submit" value="Login" />
}
Also you controller looks strange, maybe because this is result of code simplification, but at least should be next change when your model is invalid (return View("Index");):
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using RDB.DataModel;
using RDB.Models;
namespace CignaRDB.Controllers
{
public class RDBWebController : Controller
{
//
// GET: /RDBWeb/
public ActionResult Index()
{
return View();
}
public ActionResult Authenticate(tblRDBUser User)
{
if (ModelState.IsValid)
{
Authenticate user = new Authenticate();
user.AuthenticateUser(User);
return View();
}
return View("Index");//because view name and Action method not match
}
}
}

Related

Razor Pages SelectList Won't Populate

My Branch SelectList won't populate with data.
The query does return 15 records, but they are not binding to the Select control.
Any thoughts?
This is what appears in the HTML page results for asp-items, instead of the items. Why does this get added tp asp-items? System.Collections.Generic.List`1[Microsoft.AspNetCore.Mvc.Rendering.SelectListItem]
<select asp-items="System.Collections.Generic.List`1[Microsoft.AspNetCore.Mvc.Rendering.SelectListItem]"
asp-for="Branch"></select>
Here is my HTML Razor Page.
<h5 class="card-title">Choose Branch</h5>
<select id="selectBranches" asp-for="Branch" asp-items="#Model.Branches" disabled="enabled" class="custom-select"></select>
Here is my C# RazorPage.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using SetpointIS.Models;
using SetpointIS.Models.Datawarehouse;
using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Mvc.Rendering;
public class EditModel : PageModel
{
private DBContextVuPoint db;
public List<SelectListItem> Branches { get; set; }
public EditModel(DBContextVuPoint _db)
{
db = _db;
}
public void OnGet()
{
Branches = db.Branch.Select(a =>
new SelectListItem
{
Value = a.BranchId.ToString(),
Text = "(" + a.Abbreviation + ")" + a.Name
}).ToList();
}
}
In asp-for you wrote Branch instead of 'Branches'

How to fetch all the fields form database in Asp.NET MVC?

I have an application in Asp.NET MVC with Entity Data Model. Now I have a model for state_master table where I have only one property 'State_Name' and in database table I have 2 fields 'State_ID' which is auto incremented and 'State_Name' for which I will insert the data.
Now as I have only one property in Model I am not able to fetch both the fields 'State_ID' and 'State_Name' using this model. This is the issue which I am facing.
State Model File :
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
namespace ViewData.Models
{
public class state_model
{
[Key]
public string state_name { get; set; }
}
}
View File :
#using ViewData.Models
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>state_view</title>
</head>
<body>
<div>
<ul>
#foreach (var state in ViewData["states"] as IList<state_model>)
{
<li>
#state.state_name
</li>
}
</ul>
</div>
</body>
</html>
Controller File :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using ViewData.DataAccessLayer;
using ViewData.Models;
namespace ViewData.Controllers
{
public class StateController : Controller
{
// GET: State
public ActionResult Index()
{
DataLayer dl = new DataLayer();
IList<state_model> data = (from o in dl.states select o).ToList();
ViewData["states"] = data;
return View("state_view");
}
}
}
You need to create a View Model for state to fetch and bind all the fields from database. For example,
public class state_ViewModel
{
[Key]
public int state_Id { get; set; } //check with your data type
public string state_name { get; set; }
}
So in your controller method, You can use this one for fetch and bind. And for insert record you can use state_model
And in your action method,
public ActionResult Index()
{
DataLayer dl = new DataLayer();
IList<state_ViewModel> data = (from o in dl.states select o).ToList();
ViewData["states"] = data;
return View("state_view");
}
See, View Model is nothing but rendering your data in your view.
To know more about view model click here

N2 for MVC - how to get Zones working?

I'm looking at the N2 CMS Minimal Example for MVC (from here)
I've figured out most of it, but I see that N2 supports 'Parts' that you can drop into 'Zones'.
How do I get Zones and Parts working in the minimal example?
The Html.Zone() command doesn't seem to work out-of-the-box.
With a bit of help from libardo at the N2 forum
Here's the 'minimal' way of adding Zones and Parts to the N2 Minimal Example for MVC:
1) Add this namespace in the web.config pages.namespaces node:
<pages>
<namespaces>
...
<add namespace="N2.Web.Mvc.Html"/>
...
2) Add a Container page model, using the AvailableZones attribute:
using N2.Integrity;
...
[Definition("ContainerPage")]
[AvailableZone("Right", "MyRightZone")]
public class ContainerPage : N2.ContentItem
{
...
3) Add Container controller in the usual N2 manner, nothing special needed here to make it a container:
[Controls(typeof(ContainerPage))]
public class ContainerController : ContentController<ContainerPage>
{
...
4) In the view for the container, use the Html.DroppableZone function:
<div class="n2zone">
<% Html.DroppableZone("MyRightZone").Render(); %>
</div>
5) Add a part model, e.g. this one just shows Title as a string. Note that PartDefinition is what makes it a Part that can be dropped into a Zone:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using N2;
using N2.Details;
namespace MyProject.Models
{
[PartDefinition("SimplePart")]
[WithEditableTitle("Title", 10)]
public class SimplePart : ContentItem
{
[DisplayableLiteral()]
public override string Title
{
get { return base.Title; }
set { base.Title = value; }
}
}
}
6) Add a Controller for the Part. This is the usual N2 controller except that we override Index to return a PartialView:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using N2.Web;
using N2.Web.Mvc;
using MyProject.Models;
namespace MyProject.Controllers
{
[Controls(typeof(SimplePart))]
public class SimplePartController : ContentController<SimplePart>
{
public override ActionResult Index()
{
return PartialView(CurrentItem);
}
}
}
7) Finally, add a partial view for the Part controller. Nothing special is needed here:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<MyProject.Models.SimplePart>" %>
<div class="simplePart">
<%= Html.DisplayContent(m => m.Title) %>
</div>
In the N2 editor you can then drop as many SimpleParts as you like into the ContainerPage pages.

Base controller class

I have a base controller class and I would like to pass a Message from the Base class to all controllers and for that message to be available to all views.
I've created a basic version below...
Section Controller
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace Website.Controllers
{
public class SectionController : Controller
{
//
// GET: /Section/
public ActionResult Section()
{
ViewData["Message"] = "THIS IS A TEST";
return View();
}
}
}
Home Controller
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace Website.Controllers
{
public class HomeController : SectionController
{
public ActionResult Index()
{
return View();
}
}
}
View
<%= Html.Encode(ViewData["Message"]) %>
I know I can do this in the home controller but I'm just testing at the mo.
I'm not getting any errors with the above but I'm also not displaying the message on my view?
I'm using this tutorial http://www.asp.net/LEARN/mvc/tutorial-13-cs.aspx The Good Solution part, if that helps.
Think I've got it working now used the code below on my sectionController...
namespace Website.Controllers
{
public class SectionController : Controller
{
//
// GET: /Section/
public SectionController()
{
ViewData["Message"] = "THIS IS A TEST";
//return View();
}
}
}
Is this an ok solution?
You're setting your ViewData in the Section action method of your base controller, do you actually want to be setting it in the constructor of your base controller?
public SectionController()
{
ViewData["Message"] = "THIS IS A TEST";
}
HomeController.Index isn't calling SectionController.Section.
Because none of the requests are mapped to action "Section" in SectionController. If you mapped a request like domain/Section/Section, you would see your message in your view (Assuming that you are using default routing and have a view named "Section").
What you need to do is, placing your message into the viewdata on a method that runs every time an action is run. You can do it in OnActionExecuting like:
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
ViewData["Message"] = "THIS IS A TEST";
base.OnActionExecuting(filterContext);
}
in the SectionController.

How to create a strongly typed MVC View based on a custom Linq2Sql class

I have created a custom entity because I need to populate an entity with some data from a join in L2S.
When I right click on the ActionResult code in the Controller to "Add View", and then choose "Create strongly typed view", my class doesn't show up in the classes available in the selector. I'm not sure why. Here is my code:
//The Model
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data;
using System.Data.SqlClient;
namespace FurnitureStore.Models.Repository
{
public class FurnitureRepository
{
public IQueryable<Listing> GetProductListings()
{
FurnitureDataContext dc = new FurnitureDataContext();
return (from p in dc.Products
join c in dc.Categories
on p.CategoryId equals c.CategoryId
select new Listing
{
ProductName = p.ProductName,
CategoryDescription = c.CategoryDescription
});
}
}
}
//The entity class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace FurnitureStore.Models
{
public class Listing
{
public string ProductName { get; set; }
public string CategoryDescription { get; set; }
}
}
//The Method in the Controller
public ActionResult ProductListings()
{
FurnitureRepository fr = new FurnitureRepository();
var listings = fr.GetProductListings();
return View("ProductListings",listings);
}
Make sure that you compile the code, if the code is not compiled the newly added classes dont showup in the classes available in the selector
Just create a normal view and edit the view's page definition (inherits attribute specifically) yourself.
<%# Page ... Inherits="System.Web.Mvc.ViewPage<IQueryable<FurnitureStore.Models.Listing>>" %>
Off the top of my head I can't answer why it isn't appearing in your class selector.
HTHs
Charles

Resources