asp.net mvc - 完全脱离数据库中的自定义字段构建视图

Posted

技术标签:

【中文标题】asp.net mvc - 完全脱离数据库中的自定义字段构建视图【英文标题】:asp.net mvc - constructing views completely off custom fields in DB 【发布时间】:2009-10-02 13:21:06 【问题描述】:

我正在设计一个 asp.net mvc 网络应用程序。该应用程序将有六个(可能更多)不同的用户组,他们都使用相似但经过调整的 UI,每个都有一些自定义字段,但都使用相同的对象。

创建 UI 的一个想法是,将 Control 信息与每个字段值一起存储在数据库中,并在我们查询数据库时完整地构建每个视图。

这听起来像是一种创建视图的灵活方式,无需为每个用户组定义一组单独的视图,因为每个屏幕可能有不同的字段,具体取决于用户组。

听起来布局也很难控制。

我的问题:这是正确的方法吗?在创建拖放布局和将整个 UI 从 DB 字段中移除之间的中间立场在哪里?

谢谢!!

【问题讨论】:

你能使用 ASP.Net MVC 的 MVC 2 Preview 2 版本吗? 是的,这仍处于早期设计阶段,对使用的技术没有限制 【参考方案1】:

就个人而言,我会选择单独定义的视图。当然,我这样说是在不知道个人观点有多复杂的情况下说的。我的理由主要与使布局工作有关,您说得对,使用生成的视图会更难。

如果视图之间有很多共同点(为什么不存在,因为它们使用的是同一个应用程序),您应该能够将这些项目分解为部分视图并将自定义留给增量每个用户组。

【讨论】:

【参考方案2】:

如果您的视图很简单(平面,没有嵌套的子控件),这可能是有意义的。 MVC v2 通过 html.InputFor() 支持类似的东西,在 MvcContrib 的 InputBuilder 中为 MVC v1 实现了类似的东西。它们都使用反射遍历模型属性并创建适当的控件(即字符串的文本框、布尔值的复选框等)。

但是我想说,对于更复杂的视图,这将失败。例如,当前 MVC v2 在为 IList 执行此 InputFor 时存在问题。但是,如果您可以接受这个想法(并且 MVC 源代码以及 InputBuilder 源代码可用)并根据您的项目的需要对其进行调整。我认为只有您可以决定自动生成是否适合您。

【讨论】:

【参考方案3】:

如果您能够使用 MVC 2 的 Preview 2,那么您可以通过从 DataAnnotationsModelMetadataProvider 或 ModelMetadata 继承来完成此操作,如果您根本不想要基于属性的东西。

然后你会想要覆盖 CreateMetadata 方法,如:

public class MyMetadataProvider : DataAnnotationsModelMetadataProvider

    protected override ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName)
    
        ModelMetadata metadata = base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName);
        bool show = true;
        /* Code to check if the fields should show */

        metadata.ShowForDisplay = show;
        metadata.ShowForEdit = show;
        return metadata;
    

然后在您的通用视图中调用 .DisplayFor 或 .EditorFor 就像这里显示的 http://weblogs.asp.net/scottgu/archive/2009/07/31/asp-net-mvc-v2-preview-1-released.aspx。

更新:

您还需要设置ModelMetadataProviders.Current = new MyMetadataProvider();

【讨论】:

【参考方案4】:

MVC 更加关注语义 HTML 代码,而 HTML 是为流动的布局而构建的。精心设计和风格化的控件不应该造成问题,尤其是在数据驱动的设计中。

例如看这个网站,主要内容是对一个问题的任意数量的答案(有无 cmets)、问题本身、广告、按钮等。

还可以考虑让您动态布局页面的 iGoogle 之类的网站(实际上您是在流式布局中切换元素的顺序和容器)。

Future Drag and Drop 和其他 Eye candy 可以使用 CSS、javascript 和 JQuery 或其他 Web2.0/Ajax UI/UX 框架实现。

简单地说,ASP.net MVC 就是为了满足这种需求而设计的;动态的、数据驱动的 Web 应用程序,不能从在 Web 上复制 WinForms 中受益。

【讨论】:

【参考方案5】:

通常我会倾向于单独的视图,但在这种情况下,我认为一个视图可能更容易。我会这样做:

public class YourClass

    public string Property1  get; set; 

    public int Property2  get; set; 

    public DateTime Property3  get; set; 


// ViewData for YourClass
public class YourClassViewData

    public YourClass YourClass  get; set; 

    public bool Property1Visible  get; set; 

    public bool Property2Visible  get; set; 

    public bool Property3Visible  get; set; 


// Use this inside your controller to
// build appropriate View data based on group or user
public classYourClassViewDataBuilder

    // not sure on what your using for user stuff but you can
    // change that. You should get the idea though...
    public static YourClassViewData BuildYourClassViewData(string user, YourClass yourClass)
    
        YourClassViewData result = new YourClassViewData();
        result.YourClass = yourClass;

        if (user == "ViewOnly")
        
            result.Property1Visible == false;
            result.Property2Visible == true;
            // etc.
        
        else if (user == "Admin")
        
            reslut.Poperty1Visible == true;
            // etc.
        

        return result;
    


// Then inside your view your would just do it like this...
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<YourClassViewData>" %>

<% if (Model.Property1Visible)
 %>
    <label for="Property1">
    Property1:</label>
    <% Html.RenderYourControl("Property1", Model.YourClass.Property1) %>
<%  %>

<!-- continue for each property... -->

【讨论】:

以上是关于asp.net mvc - 完全脱离数据库中的自定义字段构建视图的主要内容,如果未能解决你的问题,请参考以下文章

如何在 ASP.NET MVC 4 中的两个完全不同的视图之间保留数据?

如何在 Visual Studio 2017 的 ASP.NET MVC 中创建自定义生成/脚手架模板(Razor)?

如何使用 asp.net mvc Html.DropDownList 帮助器将自定义项添加到下拉列表的顶部?

Asp.net mvc + Redis

csharp ASP.net MVC:完全禁用缓存

ASP.NET MVC 中的 RSS 源