在asp.net-mvc站点上,是否有处理可编辑视图和只读视图的好模式?

在asp.net-mvc站点上,是否有处理可编辑视图和只读视图的好模式?,asp.net-mvc,forms,readonly,entitlements,Asp.net Mvc,Forms,Readonly,Entitlements,我有一个asp.net-mvc网站,到目前为止还没有任何权利,因为它已经向所有人开放。许多页面都是带有文本框、选择下拉列表等的详细表单 我现在需要改变这一点,使许多现有的网页“标题”,所以只有某些人有编辑能力,其他人看到的是只读页面。我在想我是否应该 为每个人创建一个单独的视图—我现有的视图中的一个,表单在页面上是只读html,并根据服务器端的权限重定向,例如 public ActionResult OrderView() { var isEntitled = Model.IsEnti

我有一个asp.net-mvc网站,到目前为止还没有任何权利,因为它已经向所有人开放。许多页面都是带有文本框、选择下拉列表等的详细表单

我现在需要改变这一点,使许多现有的网页“标题”,所以只有某些人有编辑能力,其他人看到的是只读页面。我在想我是否应该

  • 为每个人创建一个单独的视图—我现有的视图中的一个,表单在页面上是只读html,并根据服务器端的权限重定向,例如

    public ActionResult OrderView()
    {
         var isEntitled = Model.IsEntitled()
         if (isEntitled)
         { 
              return("OrderEditableView", GetViewModel()); 
         }
         else 
         {
             return("OrderReadOnlyView", GetViewModel());  
         }
    
    }

  • 重复使用同一视图,只需禁用或隐藏屏幕上的“保存”按钮 依我看,我有

         <% if (Model.IsEntitled) { %>
               <button id="saveButton">Save Changes</button>
         <% } %>
    
    
    保存更改
    
    第二个选项实现起来要快得多,但会有点奇怪,因为它看起来像是你可以编辑所有的字段,但只是看不到表单上的保存按钮

    第一个选项看起来更简洁,但我必须为我的每个屏幕创建一个新的视图,这似乎需要做很多工作(目前有100多个视图)


    这似乎是一种常见的情况,所以我想看看是否有处理这种情况的最佳实践。很明显,我正在寻找一个解决方案,考虑到我目前的处境,但如果我从头开始,我也会对是否存在被视为最佳实践或推荐的模式或解决方案感兴趣。

    一个选项是在视图中进行切换

    <% if (Model.IsEntitled) 
    { 
        Html.Partial("OrderEditablePartialView", Model)
    }
    else 
    {
        Html.Partial("OrderReadOnlyPartialView", Model)
    }
    %>
    
    
    
    另一个选项是创建自定义Html帮助程序,将元素呈现为可编辑或只读,这将为您处理每个元素提供一些灵活性

    粗略的例子:

    public static MvcHtmlString FormTextBox(this HtmlHelper helper, string name, string text, bool editable)
            {
                return
                    new MvcHtmlString(
                        String.Format(
                            editable
                                ? "<input type='text' id='{0}' name='{0}' value='{1}'>"
                                : "<label for='{0}'>{1}</label>",
                                name, text));
            }
    
    public static MvcHtmlString FormTextBox(此HtmlHelper帮助程序,字符串名称,字符串文本,bool可编辑)
    {
    返回
    新MvcHtmlString(
    字符串格式(
    可编辑
    ? ""
    : "{1}",
    名称,文字);;
    }
    
    最快的解决方案是一些javascript,它禁用用户无权访问的页面上的所有输入元素。如何实现这一点取决于您,它取决于视图和模型的结构

    通过这种方式,您可以重用编辑视图,而无需对其进行编辑,但根据您的用户类型,当表单显示为禁用状态时,您可能会收到“站点不工作”调用

    模式或解决方案,如果我从零开始,这些模式或解决方案将被视为最佳实践或推荐

    正确的方法是,但是从你的“为我的每个屏幕创建一个新的视图,这似乎是很多工作”的评论中,我想你对此不感兴趣


    所以我选择前者。请确保检查
    [HttpPost]
    操作方法中的权限,因为恶意用户很容易重新启用表单并发布它。

    我会为这两种方法创建单独的部分/完整视图

    原因:
    易于更换和维护
    仅可编辑零件中的验证代码
    明确区分关注点
    更干净的代码
    也许我们可以通过将类似的代码抽象/分离为可重用的部分视图来重用一些代码
    轻松控制访问权限


    而且,在现实世界中,我们在预算、时间和努力之间取得平衡。因此,考虑到我可能会根据具体情况混合使用这些选项。

    我会选择第二个选项,该选项具有可写和只读表单的单一视图

    在视觉方面,除了隐藏保存按钮外,我还实现了一些功能:

    • 将输入字段设置为只读。您可以使用客户端Javascript轻松实现这一点

    • 更改输入字段的颜色(可能还有其他属性),以强调它们是只读的(例如,删除边框)。这可以通过样式表和表单标记中的单个附加类名轻松实现

    服务器端的授权也很简单。只需相应地注释操作

    它可能看起来像这样(使用Razor和jQuery简化):

    查看:

    @using (Html.BeginForm("AddressController", "SaveChanges", FormMethod.Post,
            new { @class = Model.IsEntitled ? "regular" : "readonly"}))
    {
       <p>
         @Html.TextboxFor(model => model.Name)
       </p>
       <p>
         @Html.TextboxFor(model => model.Address)
       </p>
       @if (Model.IsEntitled) {
         <p>
           <button id="saveButton">Save Changes</button>
         </p>
       }
    }
    
    <script type="text/javascript">
      $( document ).ready(function() {
         $('form.readonly input').attr("readonly", true);
      });
    </script>
    
    public class AddressController : Controller {
    
        [Authorize(Roles = "xyz")]
        [HttpPost]
        public ActionResult SaveChanges(Address address) {
            ...
        }
    }
    
    .readonly input {
        border: none;
    }
    
    CSS:

    @using (Html.BeginForm("AddressController", "SaveChanges", FormMethod.Post,
            new { @class = Model.IsEntitled ? "regular" : "readonly"}))
    {
       <p>
         @Html.TextboxFor(model => model.Name)
       </p>
       <p>
         @Html.TextboxFor(model => model.Address)
       </p>
       @if (Model.IsEntitled) {
         <p>
           <button id="saveButton">Save Changes</button>
         </p>
       }
    }
    
    <script type="text/javascript">
      $( document ).ready(function() {
         $('form.readonly input').attr("readonly", true);
      });
    </script>
    
    public class AddressController : Controller {
    
        [Authorize(Roles = "xyz")]
        [HttpPost]
        public ActionResult SaveChanges(Address address) {
            ...
        }
    }
    
    .readonly input {
        border: none;
    }
    

    听起来您需要建立一个服务器会话类,在这个类中可以放置MyWeb.session.IsEntited等内容。@Irb-我在计算和确定某人是否有资格时没有问题。根据我的问题,我更关注如何管理视图。您可以根据可编辑的要求创建一个局部视图。@Irb-这不是我上面列出的第一个选项吗?有许多模式可以满足您的需要。但是:是否使用editorforhelpers来呈现所有要转换为被动控件的输入控件?非管理员用户是否可以看到停用的输入(或者您是否要求他们看到简单文本)?进行“调整”或使用您想要改变其行为的自定义助手是否太麻烦?您是否同意从JS库(如Angular)添加一些功能?将OP的建议从控制器移动到视图并没有太大变化,OP说“但我必须为我的每个屏幕创建一个新视图,这似乎需要做很多工作(目前有100多个视图)”这并不能解决这个问题。对于扩展方法+1。这样,你只写一次视图,它就知道它的个性了。但是,我将使用内置的EditorFor和DisplayFor模板:
    public static MvcHtmlString EditOrDisplayFor(此HtmlHelper html,表达式表达式,bool isEditable){return(isEditable)→html.EditorFor(表达式):html.DisplayFor(表达式);}
    我认为这是一个很好的解决方案。在th中使用客户端javascript