【问题标题】:On an asp.net-mvc site, Is there a good pattern for dealing with both editable and read only views?在 asp.net-mvc 站点上,是否有处理可编辑和只读视图的好模式?
【发布时间】:2014-06-20 13:51:05
【问题描述】:

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

我现在需要对此进行更改,以使许多现有页面“授权”,以便只有某些人具有编辑能力,而其他人只能看到只读页面。我想知道我是否应该这样做

  1. 为我现有的视图中的每个人创建一个单独的视图,其中的表单只是页面上的只读 html 并根据服务器端的权利进行重定向,例如

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

    }

  1. 重复使用相同的视图并简单地禁用或隐藏屏幕上的“保存”按钮。

在我看来有

     <% if (Model.IsEntitled) { %>
           <button id="saveButton">Save Changes</button>
     <% } %>

第二个选项实施起来会更快,但会有点奇怪,因为看起来您可以编辑所有字段,但只是看不到(或看到禁用的)表单上的保存按钮。

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

这似乎是一种常见情况,所以我想看看是否有处理这种情况的最佳做法。显然,鉴于我目前所处的情况,我正在寻找一种解决方案,但如果我从头开始,是否存在被认为是最佳实践或推荐的模式或解决方案,我也会感兴趣。

【问题讨论】:

  • 听起来你需要建立一个服务器会话类,你可以在其中放置 MyWeb.Session.isEntitled 之类的东西。
  • @Irb - 我在计算和确定某人是否有资格时没有问题。根据我的问题,我更专注于如何管理视图
  • 您可以根据可编辑的要求将视图创建为局部视图..
  • @Irb - 这不是我上面列出的第一个选项吗?
  • 有很多模式可以做你想做的事。但是:您是否使用 EditorFor 帮助器来渲染所有要转换为被动控件的输入控件?非管理员用户是否可以看到停用的输入(或者您是否要求他们看到简单的文本)?进行“调整”或使用要更改其行为的自定义助手是否太麻烦?您是否同意从 Angular 等 JS 库中添加一些功能?

标签: asp.net-mvc forms readonly entitlements


【解决方案1】:

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

<% 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));
        }

【讨论】:

  • 将 OP 的建议从控制器移动到视图并没有太大变化,OP 说 “但我必须去为我的每个屏幕创建一个新视图,这似乎像很多工作(目前超过 100 个视图)” 这并没有解决。
  • +1 表示扩展方法。这样,您只需编写一次视图,它就知道它的个性。但是,我会使用内置的 EditorFor 和 DisplayFor 模板:public static MvcHtmlString EditOrDisplayFor&lt;TModel, TValue&gt;( this HtmlHelper&lt;TModel&gt; html, Expression&lt;Func&lt;TModel, TValue&gt;&gt; expression, bool isEditable) { return (isEditable) ? html.EditorFor(expression):html.DisplayFor(expression); }
【解决方案2】:

我会选择第二个选项,为可写和只读表单提供单一视图。

对于视觉方面,除了隐藏 Save 按钮之外,我还会实现一些东西:

  • 将输入字段设置为只读。您可以使用客户端 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) {
        ...
    }
}

CSS:

.readonly input {
    border: none;
}

【讨论】:

  • 我认为这是一个很好的解决方案。以这种方式使用客户端 JavaScript 可能并不理想,但它是一个很好的折衷方案,因为它避免了必须手动对每个输入元素进行更改。
【解决方案3】:

我会为两者创建单独的部分/完整视图。

原因:
易于更改和维护
验证码仅在可编辑部分
清晰的关注点分离
更简洁的代码
也许我们可以通过将相似代码抽象/分离为可重用的部分视图来重用一些代码
轻松控制访问

此外,在现实世界中,我们在预算、时间和精力之间取得平衡。所以考虑到我可能会根据情况混合使用这些。

【讨论】:

    【解决方案4】:

    最快的解决方案是使用一些 javascript 来禁用用户无权页面上的所有输入元素。如何实现这取决于您,这取决于您的视图和模型的结构。

    通过这种方式,您可以重复使用编辑视图,甚至无需对其进行编辑,但根据您拥有的用户类型,当您的表单显示为禁用时,您可能会收到“站点无法正常工作”的调用。

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

    正确的方法是 DisplayTemplates and EditorTemplates with proper viewmodels,但是从你的 “为我的屏幕上的每个人创建一个新视图,这似乎需要很多工作” 评论我猜你不是对此感兴趣。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-01-29
      • 2016-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多