【问题标题】:Adding SelectListItem() class without include System.Web.MVC in C#在 C# 中添加不包含 System.Web.MVC 的 SelectListItem() 类
【发布时间】:2017-03-07 04:41:51
【问题描述】:

我正在开发包含 ViewModel 和控制器的 MVC.Net 项目。为什么我不使用 Model,因为我使用 ADO.Net 而不是 Entity Framework 进行数据库连接。

为此,我在不同的项目中将 ViewModel 与 Controller 分开。这是我的问题, 我在using System.Web.MVC 中使用了 SelectListItem 类,但只将它安装在我的 Controller 项目中。

这里是控制器代码sn-p的例子:

    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);
    }

查看:

@Html.DropDownListFor(model => model.EmpName,(IEnumerable<SelectListItem>)ViewBag.ddlistname )
@Html.DropDownListFor(model => model.EmpPost,(IEnumerable<SelectListItem>)ViewBag.ddlistpos )

我知道使用 ViewBag 填充 List&lt;SelectListItem&gt;() 是一种不好的做法,这会导致 Controller 中出现大量 ViewBag,更不用说在 View 中投射 ViewBag 了。

为什么我想要这样的 ViewModel

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" }

        };
}

所以我可以在 Controller 中编写

public ActionResult Index()
    {
        var result = new CRViewModel();
        return View(result);
    }

在视图中:

@Html.DropDownListFor(model => model.EmpName,Model.EmpList )
@Html.DropDownListFor(model => model.EmpPost,Model.PosList )

但我不能,因为在我的 ViewModels(VM) 项目中,我没有命名空间 System.Web.MVC。如果我将 dll 和 System.Web.MVC 命名空间添加到我的 VM 项目中,只是为了使用 SelectListItem 类,那就太浪费了。

如果可能,我如何在不添加整个命名空间的情况下添加 SelectListItem 类?

编辑: 根据您的要求,我添加了我的真实代码示例 这就是我的代码的工作原理。

在 DAL 类中:

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;
        }

在控制器中:

private DAL func = new DAL();
public ActionResult Index()
{
    ViewBag.ddlistname = func.getcustlist();
    ViewBag.ddlistpos = func.getpostype();
    var result = new CRViewModel();
    return View(result);
}

【问题讨论】:

  • 你需要添加命名空间。这样做是有道理的。它是一个视图模型,特定于System.Web.MVC 中的视图。无论如何,命名空间都在您的应用中使用,因此没有区别(不清楚您为什么认为 这是一种浪费
  • 因为我使用 Visual Studio 中的 Nuget 包在需要 Internet 访问的项目中添加 dll。在我的工作场所,互联网访问受到限制。我这里只能访问内网。虽然可以要求临时访问,但这里有点复杂,所以要做很多工作。
  • 您正在使用 MVC,因此您的计算机上已经安装了 .dll - 您不需要使用 Nuget
  • 我用的是5.0的MVC,机器最多只有4.0
  • 假设我使用System.Web.MVC 会报错吗?

标签: c# asp.net-mvc razor


【解决方案1】:

如果不添加命名空间,则无法实现此行为,因为它存储了有关此类的信息。

但是,您可以创建自己的选择项类并创建一个扩展方法,用于将您的类的项转换为SelectListItem,如下所示:

public class SimpleItem
{
    public string Text { get; set; }
    public string Value { get; set; }
}

SimpleItem 应存储在 ViewModels 和 Views 可以访问的程序集中。

并在MVC项目中创建扩展方法:

public static class HtmlExtensions 
{
    public static MvcHtmlString LocalDropDownListFor<TModel, TProperty>(
        this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expr, 
        IEnumerable<SimpleItem> items)
    {
        return helper.DropDownListFor(expr, 
            items.Select(x => new SelectListItem { Text = x.Text, Value = x.Value } ));
    }
}

您应该包含 System.Web.Mvc.Html 以启用来自 helperDropDownListFor 方法调用。

如果这是您的第一个HtmlHelper 扩展,最好将此类的namespace 包含到页面web.config 中。或者您将需要手动将其包含在页面上:

@using YourProject.RequiredNamespace

毕竟你可以在页面上简单地调用它:

@Html.LocalDropDownListFor(model => model.EmpName, Model.EmpList)

【讨论】:

  • 谢谢,我确实尝试过创建自己的 selectlistitem 方法但不起作用。我确实有自己的助手扩展。如果有效,将尝试并标记为正确。祝我好运
  • 只是一个注释。我不接受这种行为。 IMO 这是一种在 ViewModel 中存储下拉值的难闻代码,可能还有其他解决方案,正如您从 cmets 中看到的那样。
  • 这不是问题,因为我将它存储在 dB 中并具有调用它的功能。示例仅供参考
猜你喜欢
  • 1970-01-01
  • 2018-01-25
  • 2011-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多