I am working on MVC.Net project which contains ViewModels and Controller. For why I don't use Model, because I use ADO.Net instead of Entity Framework for my DB connection.
To do so, I separate ViewModels with Controller in different project. Here is my problem,
I utilize SelectListItem class in using System.Web.MVC
, but only install it in my Controller project.
Here example of Controller code snippet:
public ActionResult Index()
{
ViewBag.ddlistname = new List<SelectListItem> {
new SelectListItem { Text = "Anthony", Value = "1" },
new SelectListItem { Text = "Miranda", Value = "2" },
new SelectListItem { Text = "Jhon", Value = "3" }
};
ViewBag.ddlistpos = new List<SelectListItem> {
new SelectListItem { Text = "Store Clerk", Value = "A" },
new SelectListItem { Text = "Waiter", Value = "B" },
new SelectListItem { Text = "Cook", Value = "C" }
};
var result = new CRViewModel();
return View(result);
}
View:
@Html.DropDownListFor(model => model.EmpName,(IEnumerable<SelectListItem>)ViewBag.ddlistname )
@Html.DropDownListFor(model => model.EmpPost,(IEnumerable<SelectListItem>)ViewBag.ddlistpos )
I know it's a bad practice to fill List<SelectListItem>()
using ViewBag which resulted in a lot of ViewBag inside Controller, not to mention casting ViewBag in View.
Which why I want my ViewModels like this
public class CRViewModels
{
public string EmpName { get; set; }
public string EmpPos { get; set; }
public List<SelectListItem> EmpList = new List<SelectListItem>
{
new SelectListItem { Text = "Anthony", Value = "1" },
new SelectListItem { Text = "Miranda", Value = "2" },
new SelectListItem { Text = "Jhon", Value = "3" }
};
public List<SelectListItem> PosList = new List<SelectListItem>
{
new SelectListItem { Text = "Store Clerk", Value = "A" },
new SelectListItem { Text = "Waiter", Value = "B" },
new SelectListItem { Text = "Cook", Value = "C" }
};
}
So in Controller I could write
public ActionResult Index()
{
var result = new CRViewModel();
return View(result);
}
and in View :
@Html.DropDownListFor(model => model.EmpName,Model.EmpList )
@Html.DropDownListFor(model => model.EmpPost,Model.PosList )
but I can't because in my ViewModels(VM) project, I don't have namespace System.Web.MVC
. It's rather a waste if I add dll and include System.Web.MVC
namespace to my VM project only for using the SelectListItem class.
If it is possible, How could I add SelectListItem class without adding whole namespace?
Edit : for your request, I add my real code example This is how my code works.
In DAL class:
public List<SelectListItem> getcustlist()
{
string SQL = "select cust_name, cust_id from tbl_cust";
List <SelectListItem> result = getdropdownfromSQL(SQL, "cust_name", "cust_id ");
return result;
}
public List<SelectListItem> getpostype()
{
string SQL = "select pos_name, pos_code from tbl_pos";
List<SelectListItem> result = getdropdownfromSQL(SQL, "pos_name", "pos_code");
return result;
}
public List<SelectListItem> getdropdownfromSQL(string SQL, string Text, string Value)
{
string Conn = GetConn();//function to get connection string
List<SelectListItem> result = new List<SelectListItem>();
string errmsg;
DataTable fetch = getdt(SQL, Conn, out errmsg);
if (fetch == null)
return result;
int rowaffect = fetch.Rows.Count;
for (int i = 0; i < rowaffect; i++)
{
result.Add(new SelectListItem
{
Text = fetch.Rows[i][Text].ToString(),
Value = fetch.Rows[i][Value].ToString()
});
}
return result;
}
public DataTable getdt(string SQL, string strconn, out string errormsg)
{
errormsg = "";
DataTable dt = new DataTable();
try
{
using (SqlConnection conn = new SqlConnection(strconn))
{
using (SqlDataAdapter da = new SqlDataAdapter(SQL, conn))
{
conn.Open();
da.Fill(dt);
}
}
}
catch (Exception ex)
{
errormsg = ex.Message;
return null;
}
return dt;
}
in controller :
private DAL func = new DAL();
public ActionResult Index()
{
ViewBag.ddlistname = func.getcustlist();
ViewBag.ddlistpos = func.getpostype();
var result = new CRViewModel();
return View(result);
}
You can not achieve this behaviour without adding the namespace, as it stored info about this class.
However, you can create your own select item class and create an extension method for converting items of your class to
SelectListItem
as following:SimpleItem
should be stored in assembly to whichViewModel
s andView
s have access.And in the MVC project create an extension method:
You should include
System.Web.Mvc.Html
for enablingDropDownListFor
method call fromhelper
.If it is your first
HtmlHelper
extension, would be better to includenamespace
of this class into page web.config. Or you will be required to include it on page manually:After all you could simple call it on page: