ASP.NET MVC使用强类型视图模型从视图到控制器保留数据
本文关键字:视图 控制器 保留 数据 模型 ASP MVC 强类型 NET | 更新日期: 2023-09-27 18:06:49
我提前道歉,因为我问了一个以前已经回答过的问题,但我仍然是一个新手,发现很难将解决方案应用到我自己的问题上。
我有一个视图模型,我在创建时填充一些数据,然后打算使用级联下拉列表填充数据(我不能使用任何客户端脚本)
public class StudentPortalModel
{
public SelectList LocationListModel { get; set; }
public SelectList ResidenceListModel { get; set; }
public int ChosenLocation { get; set; }
public int ChosenBlock { get; set; }
public int ChosenFlat { get; set; }
public int ChosenRoom { get; set; }
public int ChosenResidence { get; set; }
}
我在控制器中有一个动作,它填充了一些列表的视图模型,我使用的下拉菜单,如下所示:
[HttpGet]
public ActionResult SelectResidence()
{
List<Location> objLocationList = (from data in db.Locations select data).ToList();
SelectList objLocationModelData = new SelectList(objLocationList, "LocationId", "LocationName", 0);
List<Residence> objResidenceList = (from data in db.Residences select data).ToList();
SelectList objResidenceModelData = new SelectList(objResidenceList, "ResidenceId", "BlockNumber", 0);
StudentPortalModel objStudentPortalModel = new StudentPortalModel();
objStudentPortalModel.LocationListModel = objLocationModelData;
objStudentPortalModel.ResidenceListModel = objResidenceModelData;
return View(objStudentPortalModel);
}
我希望发送给视图的模型数据返回给控制器
@using (Html.BeginForm("SelectLocation", "StudentPortal", FormMethod.Post))
{
@Html.DropDownListFor(x => x.ChosenLocation, Model.LocationListModel, "---Select Location---")
<input type="submit" value="Submit"/>
}
我希望在发送回HttpGet方法时保留我发送给视图的所有数据。
[HttpPost]
public ActionResult SelectLocation(StudentPortalModel testPortalInstance)
{
List<Location> objLocationList = (from data in db.Locations select data).ToList();
SelectList objLocationModelData = new SelectList(objLocationList, "LocationId", "LocationName", 0);
List<Residence> objResidenceList = (from data in db.Residences select data).Where(i => i.LocationId == testPortalInstance.ChosenLocation).DistinctBy(x => x.BlockNumber).ToList();
SelectList objResidenceModelData = new SelectList(objResidenceList, "ResidenceId", "BlockNumber", 0);
testPortalInstance.LocationListModel = objLocationModelData;
testPortalInstance.ResidenceListModel = objResidenceModelData;
return View("SelectResidence", testPortalInstance);
}
你们可能都知道,唯一被发送回来的数据是ChosenLocation当最终用户从下拉列表中选择它时,它被发送回来,其他的都是空的
本质上,我需要一种方法来保留用户为每个下拉列表选择的选项。这使我能够缩小用户希望选择的房间,直到我能够从表格中破译一个房间并将其分配给用户。
我最大的问题是我似乎找不到我发送给视图的视图模型数据,并将其分配给相同的值发送回来。当我返回到控制器时,一切都是空的,这意味着我必须重新创建数据。
我为我的胡言乱语道歉,我把它归结为我刚编程一个月的事实。
提前感谢您的帮助!
不太清楚为什么你不想使用javascript/jquery(它会提供更好的性能),但你需要将选择的值从相关的POST方法传递给每个GET方法。假设第一步是选择一个位置,然后是住所,那么控制器方法将是
public ActionResult SelectResidence()
{
List<Location> locations = (from data in db.Locations select data).ToList();
StudentPortalModel model = new StudentPortalModel()
{
LocationListModel = new SelectList(locations, "LocationId", "LocationName")
}
return View(model);
}
注意,为ResidenceListModel
生成SelectList
是没有意义的,因为它没有在第一个视图(
@model StudentPortalModel
@using (Html.BeginForm()) // no need to add parameters
{
@Html.DropDownListFor(x => x.ChosenLocation, Model.LocationListModel, "---Select Location---")
<input type="submit" value="Submit"/>
}
将返回到
[HttpPost]
public ActionResult SelectResidence(StudentPortalModel model)
{
if (!ModelState.IsValid)
{
// repopulate locations and return view
}
return RedirectToAction("SelectResidence", new { locationID = model.ChosenLocation });
}
将重定向到
public ActionResult SelectResidence(int locationID)
{
List<Residence> residences = (from data in db.Residences select data).Where(i => i.LocationId == locationID).ToList();
StudentPortalModel model = new StudentPortalModel()
{
ChosenLocation = locationID,
ResidenceListModel = new SelectList(residences, "ResidenceId", "BlockNumber")
}
return View(model);
}
,其视图将为
@model StudentPortalModel
@using (Html.BeginForm())
{
@Html.HiddenFor(x => x.ChosenLocation)
@Html.DropDownListFor(x => x.ChosenResidence, Model.ResidenceListModel , "---Select Residence---")
<input type="submit" value="Submit"/>
}
将返回到
public ActionResult SelectResidence(StudentPortalModel model)
{
if (!ModelState.IsValid)
{
// repopulate residences based on the value of model.ChosenLocation and return view
}
// your model now contains values for both ChosenLocation and ChosenResidence
}
同样,如果你需要去一个视图选择一个房间,你会重定向到(比如)public ActionResult SelectResidence(int locationID, int residenceID)
局部视图,应该使用
@Html.RenderChildAction
这是你在razor视图中使用的Html Helper上的一个方法。
你的控制器方法应该用(ChildActionOnly)
这是一个属性,使MVC路由操作的方式,它只能通过RenderChildAction调用,这防止人们去到它的url在他们的浏览器。
其次,您应该在级联的每个步骤上将您的模型实例传递给视图。
return Partial(theModel);
或return Partial("somePartialView", theModel);
这些返回将是返回ActionResult类型的控制器动作的示例返回。
最后,表单标记可以将模型传递给回发。MVC将自动JSON序列化它和JSON反序列化它为你,所以不需要有大量的隐藏标签(可能在旧版本的MVC,但我知道这在MVC 4+工作)。
下面是一个局部视图示例:@model StudentPortalModel
@using (Html.BeginForm("SetSelection", "StudentPortal", new { model = Model}, FormMethod.Post, null))
{
//Do Form Stuff Here
}
注意,上面我将模型作为路由数据对象传递…MVC会将其序列化为json, post到post data中,然后控制器会自动将其反序列化为model参数,因为它是一个匿名对象,它的model属性和json类型info与控制器动作上的"model"参数名称匹配。
控制器方法示例
[HttpPost]
public ActionResult SetSelection(StudentPortalModel model)
{
return View("NextCascade", Model)
}
现在,我没有使用ChildAction只在上面,因为你想要能够发布到这个。[ChildActionOnly]是用来加载你的局部视图的Action,而不是用来返回给它的Action,那些get [HttpPost]。
三个属性一共是:
[ChildActionOnly]
[HttpGet]
[HttpPost]
你可以在同一个操作上同时使用HttpGet和HttpPost,但这是默认的。换句话说,如果您将所有属性放在一起,它将路由get和post请求。Put如果你只放HttpGet,它不会路由Post请求(你不能向它发送),等等。
现在,我们说PartialView叫做StudentSelection:
控制器上应该有一个父操作,在get请求(第一次加载)时返回它,装饰为[ChildActionOnly]。你应该使用@Html。
post action中的Model应该具有与用户填写的表单中的输入名称相匹配的字段。这允许默认MVC模型绑定将用户选择的值设置为StudentPortalModel中的字段。