Asp.net mvc 2 用于实现CanExecute样式命令的ASP MVC 2模式

Asp.net mvc 2 用于实现CanExecute样式命令的ASP MVC 2模式,asp.net-mvc-2,Asp.net Mvc 2,我来自WPF(MVVM)背景,并试图转换到MVC2。MVC2中是否有任何模式可以使用命令/命令按钮(如)提交表单,以便在尝试渲染视图时隐藏/禁用 在MVVM世界中,您的命令可以实现ICommand接口,并且它具有非常有用的CanExecute方法。我想知道ASP MVC 2中是否有类似的东西 我能想到的唯一方法是在视图中执行该操作,这样我就可以检查ViewModel(CanSave)上的标志,并根据该标志显示/隐藏标记 基本上我想有两个版本的网站运行,一个在只读模式和其他编辑模式 如果您需要任何

我来自WPF(MVVM)背景,并试图转换到MVC2。MVC2中是否有任何模式可以使用命令/命令按钮(如
)提交表单,以便在尝试渲染视图时隐藏/禁用

在MVVM世界中,您的命令可以实现ICommand接口,并且它具有非常有用的CanExecute方法。我想知道ASP MVC 2中是否有类似的东西

我能想到的唯一方法是在视图中执行该操作,这样我就可以检查ViewModel(CanSave)上的标志,并根据该标志显示/隐藏
标记

基本上我想有两个版本的网站运行,一个在只读模式和其他编辑模式


如果您需要任何澄清,请告诉我

我发现的一种方法是使用过滤器属性,您可以将其放入操作中,但这只能在服务器端处理CanExecute


对于GUI方面,找不到比使用If语句检查用户是否有权运行特定操作(即编辑/删除按钮)更好的方法了。

如果您无法让MVC这样做,那么手工编写类似于vb风格的伪代码是相对值得的。这涉及到

子类化控件。 不像听起来那么痛苦,但是,它是中等大小的。因此,它只适用于中型到大型应用程序。但这对他们来说是值得的

Interface BaseUIControl
    Property Enabled as Boolean
    Property Visible as Boolean
    Property Name as String
    Property EntireStateAsXML as string ' You can use this to do EVERYTHING!        

Interface UserActionItem
    Event Clicked(sender as UserActionItem ... don't pass anything from UI namespaces!)

Class MyButton (or link, etc.) Implement BaseUIControl, UserActionItem Inherits UI.Button
    
这有什么帮助?您基本上已经替换了缺少的功能。您的控制器(甚至应用程序层)可以仅通过接口了解UI组件,因此它们不必查看UI类型

更多 你可以利用这一理念来控制一切。这为我节省了数千小时的猴子代码

Interface TextControl
    Property Value as text

Interface CheckControl 
    Property Checked as boolean 
以上两个是非常基本的-您从UI版本继承MyCheckBox和MyTextBox,并实现适当的

当然,您可以设置公共代码来循环遍历所有控件并自动验证(或者循环遍历并获取每个控件的XML以自动绑定整个表单)

如果在2个子类中内置了文本或数字掩码或限制

Interface ValidationNumeric           
    Property MinVal, MaxVal as double 

Interface ValidationText
    Property MinLen, MaxLen as double 
不,它不会为你进入数据库。但是这会把一吨的积垢扫到地毯下面

您甚至可以在UI设计器中设置这些属性值-是的,将BL与UI放在一起,但是,如果BL只有一个UI,实际上效果非常好

现在想象一个UI,它混合了listbox/multiselect、双列表选择器控件、选中的listbox、选项按钮/复选框的groupbox

Interface Selector
    property Items as list (of string) 
    property SelectedItems as list (of string)
使用在UI上工作的东西-你的通用例程可以不关心它们看起来像什么!!子类化的UI片段将只实现它们以设置/获取正确的值

此外。。。我们添加了“validationEquation”、ActivatesEquation(gray/ungray)、SetValueTriggerEquation(如果为true,则将值设置为SetValueEquation,否则就不用管了),这允许通过Pascal Gayane(读取.net类型!)将控件设置为来自其他项的简单值(基本上使用反射从绑定对象获取值)

您还可以对主窗体进行子类化,让它通过所有子控件进行递归,将整个屏幕的XML放在一起,然后像这样序列化它。您可以让自己的类在非UI层中实现这些,并使用它们来完全(反/)序列化UI状态,如果它们与业务对象相关,也可以使用它们来读取UI并映射到它

这让一个复杂的应用程序变得如此简单,令人难以置信。我们有一个1200多个数据输入面板(…页面…我们是一个thickclient应用程序),将以250K LOC填写250份不同的纸质表格。表单定义包含每个控件的“名称”,这是从屏幕生成的XML中提取的。我们可能节省了500K LOC,因为许多屏幕后面没有代码,或者只有琐碎的代码;所有数据绑定、验证等都由引用接口的公共例程处理


就像我说的,这只适用于大型应用程序。不过,至少要花2-3周的时间开发90%的功能;这两年可能还要一个月。如果你关心ICommand及其便利性,我猜你的应用程序会很大。我会把回报放在15-20个中等复杂的页面上。

如果我正确理解了这个问题,您可以编写一个
ControllerCommand
类来封装这个问题。大概是这样的:

public class ControllerCommand
{
    public string Action { get; set; }
    public string Controller { get; set; }
    public object RouteValues { get; set; }
    public bool IsEnabled { get; set; }
}
public class DetailsModel
{
    public guid Id { get; set;}
    // some other viewmodel properties
    public ControllerCommand Edit { get; set; }
}
您的Details viewmodel可能会这样使用它:

public class ControllerCommand
{
    public string Action { get; set; }
    public string Controller { get; set; }
    public object RouteValues { get; set; }
    public bool IsEnabled { get; set; }
}
public class DetailsModel
{
    public guid Id { get; set;}
    // some other viewmodel properties
    public ControllerCommand Edit { get; set; }
}
您可以在
HtmlHelper
上编写扩展方法来替换内置方法:

public MvcHtmlString CommandLink(this HtmlHelper html, string linkText, ControllerCommand command, object htmlAttributes)
{
    if (command.IsEnabled)
    {
        return html.ActionLink(linkText, command.Action, command.Controller, command.RouteValues, htmlAttributes);
    }
    else
    {
        return MvcHtmlString.Create(linkText);
        // perhaps return <span class="disabled-command">linkText</span>
    }
}
public MvcHtmlString CommandLink(此HtmlHelper html、字符串链接文本、ControllerCommand命令、对象htmlAttributes)
{
if(command.IsEnabled)
{
返回html.ActionLink(linkText、command.Action、command.Controller、command.routeValue、htmlAttributes);
}
其他的
{
返回MvcHtmlString.Create(linkText);
//可能返回链接文本
}
}

ASP.NET MVC没有像经典的ASP.NET和WPF中那样采用“控件”的概念。ASP.NET MVC的基本块是HTML元素,如
等等。当然,它们不提供您想要的功能(即ICommand接口的实现)

您正在查看的场景(即表单的两种模式)可以(也可以说应该)在视图级别处理。您已经面临正确的方向:在模型上具有“CanSave”属性,并在视图中使用该属性来确定生成的内容

例如:

<% if (Model.CanSave)
    { %>
        <p>First Name: <%= Html.TextBox("firstname", Model.firstname) %> </p>
<%  }
    else
    { %>
        <p>First Name: <%=Model.firstname %></p>
<%  } %>

名字:

名字:

您可能想查看DisplayTemplates和EditorTemplates。。。对于这种情况非常方便。布拉德·威尔逊做得很好

它将帮助您实现以下目标:

<%= (Model.CanSave) ? Html.EditorFor(x => x.firstname) : Html.DisplayFor(x => x.firstname) %>
x.firstname):Html.DisplayFor(x=>x.firstname)%%>
…whic