您好我正在为我的应用程序创建Dashboard。它包含控制器中的多个动作。我想将Single View与多个动作绑定,因为我想在视图中显示不同类型的结果。但模型在单一模型中。每个动作都使用相同的模型。
我的模型(客户类型ViewModel)
public class CustomerTypeViewModel
{
public System.Guid CustomerID { get; set; }
public string CustomerName { get; set; }
public DateTime CreatedDate { get; set; }
public string SalesCount { get; set; }
public string CustomerType { get; set; }
public List<View_VisitorsForm> Visits { get; set; }
}
}
我的控制器(这里有两个动作)
这里我创建了两个动作,这两个动作做了不同的计算,这两个动作的模型是相同的(即CustomerTypeViewModel),这两个动作也重定向到同一视图。
public ActionResult Dashboard()
{
List<Customer> n = (from c in db.Customers where c.IsDeleted == false select c).ToList();
var customertype = string.Empty;
List<CustomerTypeViewModel> obj = new List<CustomerTypeViewModel>();
for (var i = 0; i < n.Count; i++)
{
var objCustomerName = n[i].DisplayName;
var objCustomerID = n[i].CustomerID;
var objCusCreatedDate = n[i].CreatedDate;
var objNextDate = objCusCreatedDate.GetValueOrDefault().AddDays(120);
var ObjTodayDate = DateTime.Now.Date;
var salescount = (from sc in db.SalesOrders where sc.CustomerID == objCustomerID && sc.CreatedDate >= objCusCreatedDate && sc.CreatedDate <= objNextDate select sc.SalesOrderID).Count();
var ordercount = (from oc in db.SalesOrders where oc.CustomerID == objCustomerID && oc.CreatedDate >= objCusCreatedDate && oc.CreatedDate <= ObjTodayDate select oc.SalesOrderID).Count();
if (ordercount >= 3)
{
customertype = "Existing Customer";
}
else if (ordercount == 0 && ordercount <= 0)
{
customertype = "New Customer";
}
else if (ordercount <= 2 && ordercount >= 1)
{
customertype = "Potential Customer";
}
obj.Add(new CustomerTypeViewModel()
{
CustomerName = objCustomerName,
CustomerType = customertype,
SalesCount = ordercount.ToString()
});
}
return View("Dashboard",obj);
}
public ActionResult NextFollowup()
{
var userID = System.Web.HttpContext.Current.Session["UserID"].ToString();
var objEmpDepUTID = db.UserRightsSettings.Where(u => u.UserID.ToString() == userID).Select(e => new
{
objemployeeID = e.EmployeeID,
objdepartmentID = e.DepartmentID,
objusertypeID = e.UserTypeID
}).FirstOrDefault();
var EmployeeID = objEmpDepUTID.objemployeeID;
var DepartmentID = objEmpDepUTID.objdepartmentID;
var UserTypeID = objEmpDepUTID.objusertypeID;
var TodayDate = DateTime.Now.Date;
List<View_VisitorsForm> objVisitorsList = new List<View_VisitorsForm>();
if (DepartmentID == new Guid("47D2C992-1CB6-44AA-91CA-6AA3C338447E") &&
(UserTypeID == new Guid("106D02CC-7DC2-42BF-AC6F-D683ADDC1824") ||
(UserTypeID == new Guid("B3728982-0016-4562-BF73-E9B8B99BD501"))))
{
objVisitorsList = db.View_VisitorsForm.Where(X => X.NextAppointment == TodayDate).ToList();
}
else
{
objVisitorsList = db.View_VisitorsForm.Where(x => x.NextAppointment == TodayDate && x.EmployeeID == EmployeeID).ToList();
}
CustomerTypeViewModel objvvm = new CustomerTypeViewModel();
objvvm.Visits = objVisitorsList;
return View("Dashboard",objvvm);
}
我的观点
在这个视图中,我给出的模型就像这样意味着它显示错误
@model CostToWafe.Areas.Sales.Models.CustomerTypeViewModel
@using CostToWafe.Areas.Sales.Models
它显示
附近的错误 @Model.Select(x => x.CustomerName).Count()
如果我给出模型名称与IEnumerable像
@model IEnumerable<CostToWafe.Areas.Sales.Models.CustomerTypeViewModel>
@using CostToWafe.Areas.Sales.Models
它显示了
表(Model.Visits)附近的错误 @foreach (View_VisitorsForm item in Model.Visits)
我的完整视图
@model CostToWafe.Areas.Sales.Models.CustomerTypeViewModel
@using CostToWafe.Areas.Sales.Models
@{
ViewBag.Title = "Dashboard";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div class="container body">
<div class="main_container">
<div class="right_col" role="main">
<!-- top tiles -->
<div class="row tile_count">
<div class="right">
<span class="count_top"><i class="fa fa-user"></i> Total Customer</span>
<div class="count">@Model.Select(x => x.CustomerName).Count()</div>
</div>
<div class="right">
<span class="count_top"><i class="fa fa-user"></i> Existing Customer</span>
<div class="count">@Model.Where(x => x.CustomerType == "Existing Customer").Count()</div>
</div>
<div class="row">
<table>
<thead>
<tr>
<th>Employee </th>
<th>Customer Name</th>
<th>Purpose of Visit</th>
</tr>
<thead>
<tbody>
@foreach (View_VisitorsForm item in Model.Visits)
{
<tr>
<td>@item.Employee;</td>
<td>@item.CustomerName;</td>
<td>@item.POVisit;</td>
</tr>
}
<tbody>
</table>
</div>
</div>
</div>
</div>
</div>
我的问题不长。我尽力解释这个问题。任何人都理解我的问题并帮助我解决这个问题。
谢谢..
答案 0 :(得分:1)
根据评论和提供的屏幕截图(https://i.stack.imgur.com/DomTM.jpg),我想我现在明白了你想要实现的目标。
问题在于你的方法存在许多逻辑缺陷。
1)您的视图的模型定义为CostToWafe.Areas.Sales.Models.CustomerTypeViewModel
,但您的Dashboard
操作正在尝试提供IEnumerable<CostToWafe.Areas.Sales.Models.CustomerTypeViewModel>
作为模型。这两个是不兼容的类型。
2)在问题中,您询问是否可以在单个视图中使用多个操作。答案是肯定的(假设他们都提供正确的模型类型)。但是,您无法同时在同一个View 上调用两个操作(即在同一请求期间)。根据您的要求,您似乎希望Dashboard
和NextFollowUp
Action方法返回的数据在单个View中一次显示。使用两种操作方法是不可能的。如果您希望View在不同时间具有不同的内容,则您只能使用多种操作方法。
3)在CustomerTypeViewModel
课程中,您已将List<View_VisitorsForm> Visits
定义为班级的属性。这意味着Vists列表以某种方式连接到特定的CustomerType
,即CustomerTypeViewModel
的任何一个实例中该列表中包含的vists将仅与仅由该实例表示的CustomerType相关联。现在从要求中可以清楚地看出情况并非如此。相反,访问列表中包含的数据不是由客户类型确定的,而是由当前系统用户确定的。因此,将此列表设为CustomerType
的属性是一种不合逻辑的关联,会引起一些混淆。
4)在视图代码中,因为@model被错误地定义为CustomerTypeViewModel
而不是IEnumerable<CustomerTypeViewModel>
的单个实例。尽管如此,您还是尝试使用@Model.Select(x => x.CustomerName).Count()
以某种方式计算列表中的对象数。这不起作用,因为View并不认为@Model
是IEnumerable<T>
,因此您无法对其进行Select
。
5)CustomerTypeViewModel
类似乎更像是客户的表示而不是客户类型 - 它包含客户名称和销售计数等字段,这些字段甚至不需要此视图。所以这是另一个逻辑问题。如果ViewModel被称为CustomerType
,则它应该完全代表客户类型,而不是客户,并且不应包含不相关的字段。
鉴于所有这些,您的设计需要彻底重新思考。您需要一个更高级别的ViewModel对象,该对象将包括CustomerTypes列表以及Visits列表。然后可以将其返回到视图,您可以
a)循环显示CustomerTypes列表以显示所有统计信息
b)遍历访问列表以显示所有访问者。
因此,Dashboard
操作将构建此DashboardViewModel
对象并将其返回到View。不再需要NextFollowUp
操作,可以将其删除。
代码应如下所示。如果有任何语法错误或类似问题,我还没有对它进行测试,所以道歉。
查看模型
//This no longer includes Visits, because they aren't specific to a CustomerType
public class CustomerType
{
public string CustomerTypeDescription { get; set; }
public int CustomerCount { get; set; }
}
//This is now the ViewModel used by the View:
public class DashboardViewModel
{
public List<CustomerType> CustomerTypes { get; set; }
public List<View_VisitorsForm> Visits { get; set; }
}
行动方法
public ActionResult Dashboard()
{
//first work out the customer type statistics
List<Customer> customers = (from c in db.Customers where c.IsDeleted == false select c).ToList();
CustomerType allCustomers = new CustomerType();
allCustomers.CustomerTypeDescription = "Total Customers";
allCustomers.CustomerCount = customers.Count;
CustomerType existingCustomers = new CustomerType();
existingCustomers.CustomerTypeDescription = "Existing Customers";
CustomerType potentialCustomers = new CustomerType();
potentialCustomers.CustomerTypeDescription = "Potential Customers";
CustomerType newCustomers = new CustomerType();
newCustomers.CustomerTypeDescription = "New Customers";
foreach (Customer cus in customers)
{
var ordercount = (from oc in db.SalesOrders where oc.CustomerID == cus.CustomerID && oc.CreatedDate >= cus.CreatedDate && oc.CreatedDate <= DateTime.Now.Date select oc.SalesOrderID).Count();
if (ordercount >= 3)
{
existingCustomers.CustomerCount++;
}
else if (ordercount == 2 || ordercount == 1)
{
potentialCustomers.CustomerCount++;
}
else if (ordercount <= 0)
{
newCustomers.CustomerCount++;
}
}
//now get the list of visits
var userID = System.Web.HttpContext.Current.Session["UserID"].ToString();
var currentUser = db.UserRightsSettings.Where(u => u.UserID.ToString() == userID).Select(e => new
{
employeeID = e.EmployeeID,
departmentID = e.DepartmentID,
usertypeID = e.UserTypeID
}).FirstOrDefault();
List<View_VisitorsForm> visitList = new List<View_VisitorsForm>();
if (currentUser.departmentID == new Guid("47D2C992-1CB6-44AA-91CA-6AA3C338447E") &&
(currentUser.usertypeID == new Guid("106D02CC-7DC2-42BF-AC6F-D683ADDC1824") ||
(currentUser.usertypeID == new Guid("B3728982-0016-4562-BF73-E9B8B99BD501")))
{
visitList = db.View_VisitorsForm.Where(X => X.NextAppointment == DateTime.Now.Date).ToList();
}
else
{
visitList = db.View_VisitorsForm.Where(x => x.NextAppointment == DateTime.Now.Date && x.EmployeeID == currentUser.employeeID).ToList();
}
//finally bring it all together to create the ViewModel
DashboardViewModel vm = new DashboardViewModel();
vm.CustomerTypes = new List<CustomerType>();
vm.CustomerTypes.Add(allCustomers);
vm.CustomerTypes.Add(existingCustomers);
vm.CustomerTypes.Add(potentialCustomers);
vm.CustomerTypes.Add(newCustomers);
vm.Visits = visitList;
return View("Dashboard", vm);
}
查看强>
@model CostToWafe.Areas.Sales.Models.DashboardViewModel
@using CostToWafe.Areas.Sales.Models
@{
ViewBag.Title = "Dashboard";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div class="container body">
<div class="main_container">
<div class="right_col" role="main">
<!-- top tiles -->
<div class="row tile_count">
@foreach (CustomerType cusType in Model.CustomerTypes)
{
<div class="right">
<span class="count_top"><i class="fa fa-user"></i>@cusType.CustomerTypeDescription</span>
<div class="count">@cusType.CustomerCount</div>
</div>
}
</div>
<div class="row">
<table>
<thead>
<tr>
<th>Employee </th>
<th>Customer Name</th>
<th>Purpose of Visit</th>
</tr>
</thead>
<tbody>
@foreach (View_VisitorsForm visit in Model.Visits)
{
<tr>
<td>@visit.Employee;</td>
<td>@visit.CustomerName;</td>
<td>@visit.POVisit;</td>
</tr>
}
</tbody>
</table>
</div>
</div>
</div>
</div>
我希望这对你有用,并有助于澄清你的想法。将来,如果您事先仔细设计ViewModel并考虑所需的可能数据,并确保您创建的任何类实际上代表他们以其命名的逻辑实体,并且不包含项目与该实体无关,那么理解自己的代码并使事情顺利进行将会容易得多。
关于您的代码的其他一些简短评论:
你有一些冗余变量(特别是var salescount)。不要将代码留在不被使用的地方 - 这会让事情变得混乱。
有一些不正确的HTML(例如,您有两次<thead>
:<thead>...
instead of closing the tag properly:
...`。
代码更加冗长,需要它。例如,EmployeeID,DepartmentID的所有声明,然后再次使用。它们是来自早期变量的直接映射,因此只需使用它。
使用有意义的变量名称,可以在整个代码中理解,而无需回顾定义(例如,使用List<Customer> customers
代替客户列表而不是List<Customer> n
,并且不要使用obj
称之为简单objEmpDepUTID
- 没有机会知道它是什么。
C#是一种强类型语言,因此您并不需要使用Hungarian Notation作为变量名称的前缀(即objVisitorsList
,obj
)。在任何情况下,当变量的类型实际上是像字符串或int的原语而根本不是对象时,你在许多地方也错误地使用了{{1}}前缀。关于使用它的意见各不相同,但一般来说,我发现它只会使代码混乱,并且不会通过读取其余代码(或使用Visual中的Intellisense)来传达任何已经看不到的信息。工作室)。
N.B。从屏幕截图中可以看出,View还有一些其他内容(设备使用,快速设置等),但您还没有提供这些内容的详细信息,因此我假设您将这些内容添加到ViewModel中后面。