我有一个带有多个链接的导航栏,如下所示:
<a href="MyController/Browse/2">MenuItem1</a>
此请求将触发我的操作方法:
public ActionResult Browse(int departmentId)
{
var complexVM = MyCache.GetComplexVM(departmentId);
return View(complexVM);
}
这是我的ComplexVM
:
public class ComplexVM
{
public int DepartmentId { get; set; }
public string DepartmentName { get; set; }
}
MyCache
是部门的静态列表,我将其保留在内存中,因此,当用户传入DepartmentId
时,无需从数据库中获取相应的DepartmentName
这工作正常...但是如果我能以某种方式在自定义模型绑定程序中初始化ComplexVM
,而不是在Controller中初始化它,那将是很好的选择。因此,我仍然想使用链接(菜单项目),但这一次,CustomModelBinder
将我的参数2绑定到ComplexVM
:它需要从MyCache
查找id = 2的部门名称并初始化{{1 }},然后将ComplexVM
传递给该操作方法:
ComplexVM
我想在不执行回发的情况下点击上面的控制器,因为我的导航栏中有很多菜单项链接...不确定是否可行?还是这是个好主意?
我看过this link,它描述了我想要的东西...但是我不确定路由如何工作...即路由public ActionResult Browse(ComplexVM complexVM)
{
return View(complexVM);
}
=> id:2
< / p>
或者可以在ComplexVM
中这样做,如下所示:
RouteConfig
答案 0 :(得分:3)
那是可能的。这也是一个好主意:)将部分责任分担给模型/动作过滤器是很棒的。唯一的问题是,因为它们使用一些特殊的类来继承,所以测试它们有时可能比仅测试控制器要难一些。一旦掌握了它,那就更好了。
您的复杂模型应该看起来像
// Your model class
[ModelBinder(typeof(ComplexVMModelBinder)]
public class ComplexVMModel
{
[Required]
public int DepartmentId { get; set; }
public string DepartmentName { get; set; }
}
// Your binder class
public class ComplexVMModelBinder : IModelBinder
{
// Returns false if you can't bind.
public bool BindModel(HttpActionContext actionContext, ModelBindingContext modelContext)
{
if (modelContext.ModelType != typeof(ComplexVMModel))
{
return false;
}
// Somehow get the depid from the request - this might not work.
int depId = HttpContext.Current.Request.Params["DepID"];
// Create and assign the model.
bindingContext.Model = new ComplexVMModel() { DepartmentName = CacheLookup(), DepId = depId };
return true;
}
}
然后在操作方法的开头,检查ModelState以查看其是否有效。
有几件事会使模型状态无效(例如没有[Required]
参数。)
public ActionResult Browse(ComplexVM complexVM)
{
if (!ModelState.IsValid)
{
//If not valid - return some error view.
}
}
现在,您只需要注册此Model Binder。
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
ModelBinders.Binders.Add(typeof(ComplexVMModel), new ComplexVMModelBinder());
}
您应该能够使用您提供的路由配置。
答案 1 :(得分:3)
我只需一点改动和一个技巧就可以实现这一目标
<a href="MyController/Browse?id=1">MenuItem1</a>
控制器动作
public ActionResult Browse(ComplexVM complexVM)
{
return View(complexVM);
}
查看模型
public class ComplexVM
{
public int DepartmentId { get; set; }
public string DepartmentName { get; set; }
public ComplexVM()
{
this.DepartmentId = System.Convert.ToInt32(HttpContext.Current.Request("id").ToString);
this.DepartmentName = "Your name from cache"; // Get name from your cache
}
}
这不使用模型联编程序。技巧可能会有所帮助。