MVC自定义模型 - 一个简单的例子在哪里?

时间:2010-02-11 21:58:34

标签: asp.net-mvc

我需要创建一个Web应用程序,我想使用MVC。但是,我的模型不能是标准模型之一 - 数据不存储在数据库中,而是存储在只能通过API访问的外部应用程序中。由于这是我实现的第一个MVC应用程序,我依靠示例来了解如何实现它。我找不到任何非基于数据库的模型的例子。自定义模型的一个例子也可以。谁能指点我这样的野兽?也许MVC只是新的而且不存在。

似乎我可以逃脱DataSet模型,但是我没有看到任何关于如何使用这个对象的例子。我希望DataSet的一个例子也可以帮助我。 (也许是同样的事情?)

请注意:我见过无数个自定义绑定的例子。这不是我想要的。我需要一个自定义模型的示例,它不依赖于特定的数据库/表。

更新

我在MS找到了一个很好的例子:

http://msdn.microsoft.com/en-us/library/dd405231.aspx

虽然这是我的问题的“答案”,但我并不喜欢它,因为它将我与MS的世界观联系在一起。 @Aaronaught,@ jerenh和@tvanfosson从元视角给出了更好的答案,即在使用MVC方面向前推进我的理解(以及你的理解?)。

我正在给@Aaronaught支票,因为他实际上有一些示例代码(我要求的。)谢谢大家,如果有的话,可以随意添加更好的答案。

3 个答案:

答案 0 :(得分:5)

在大多数情况下,对于实际应用程序数据而言,支持源应该是什么并不重要;模型应该完全一样。事实上,使用类似存储库之类的主要原因之一是您可以轻松更改底层存储。

例如,我有一个使用大量Web服务的MVC应用程序 - 除了身份验证和用户配置文件等简单的东西之外,它很少能访问本地数据库。典型的模型类可能如下所示:

[DataContract(Namespace = "http://services.acme.com")]
public class Customer
{
    [DataMember(Name = "CustomerID")]
    public Guid ID { get; set; }

    [DataMember(Name = "CustomerName")]
    public string Name { get; set; }
}

然后我将有一个如下所示的存储库界面:

public interface ICustomerRepository
{
    Customer GetCustomerByID(Guid id);
    IList<Customer> List();
}

“API”全部封装在具体的存储库中:

public class AcmeWSCustomerRepository : ICustomerRepository, IDisposable
{
    private Acme.Services.CrmServiceSoapClient client;

    public AcmeWSCustomerRepository()
        : this(new Acme.Services.CrmServiceSoapClient())

    public AcmeWSCustomerRepository(Acme.Services.CrmServiceSoapClient client)
    {
        if (client == null)
            throw new ArgumentNullException("client");
        this.client = client;
    }

    public void Dispose()
    {
        client.SafeClose();    // Extension method to close WCF proxies
    }

    public Customer GetCustomerByID(Guid id)
    {
        return client.GetCustomerByID(id);
    }

    public IList<Customer> List()
    {
        return client.GetAllCustomers();
    }
}

然后我也可能有一个本地测试存储库,只有少数客户可以读取类似XML文件的内容:

public class LocalCustomerRepository : ICustomerRepository, IDisposable
{
    private XDocument doc;

    public LocalCustomerRepository(string fileName)
    {
        doc = XDocument.Load(fileName);
    }

    public void Dispose()
    {
    }

    public Customer GetCustomerByID(Guid id)
    {
        return
            (from c in doc.Descendants("Customer")
             select new Customer(c.Element("ID").Value, c.Element("Name").Value))
            .FirstOrDefault();
    }

    // etc.
}

我想在这里提出的观点是,这与任何特定数据库无关。在这种情况下,一个可能的来源是WCF服务;另一个是磁盘上的文件。两者都不一定具有兼容的“模型”。在这种情况下,我假设WCF服务公开了一个模型,我可以使用DataContract属性直接映射到该模型,但Linq-to-XML版本是纯API;没有模型,它都是自定义映射。

一个真正好的域模型实际上应该完全独立于真正的数据源。当人们告诉我Linq to SQL或Entity Framework模型足以在整个应用程序/站点中使用时,我总是有点怀疑。通常这些与“人”模型不匹配,只是创建一堆ViewModel类不一定是答案。

从某种意义上说,如果你没有交给现有的关系模型,它实际上是更好。它迫使您真正考虑应用程序的最佳域模型 ,而不一定是映射到某个数据库的最简单的模型。因此,如果您还没有来自数据库的模型 - 构建一个!只需使用POCO类并在必要时使用属性进行装饰,然后创建将此域模型映射到API或从API映射的存储库或服务。

答案 1 :(得分:4)

我认为您所寻找的实际上是非DB服务层。模型通常是相对简单的数据容器,尽管它们也可能包含业务逻辑。听起来你所拥有的是与服务进行通信的服务,并且需要一个层来在服务和应用程序之间进行调解,从服务返回的数据中生成适当的模型类。

This tutorial可能会有所帮助,但您需要将存储库替换为与服务交互的类(而不是数据库)。

答案 2 :(得分:1)

MVC中的“模型”应该没有固定的处方,只是它应该包含需要在屏幕上显示的数据,并且可能还会被操纵。

在设计良好的MVC应用程序中,无论如何都会以某种方式抽象出数据访问,通常使用某种形式的Repository模式:您定义了一个抽象层(例如,一个IRepository接口),它定义了获取和持久化数据所需的合同。实际实现通常会调用数据库,但在您的情况下应调用您的“服务API”。

Here is an example of an MVC application that calls out to a WCF service.