开发者

MVC Custom Model - Where is a simple example?

开发者 https://www.devze.com 2022-12-19 18:48 出处:网络
I need to make a web application and I want to use MVC.However, my Model can\'t be one of the standard Models -- the data is not stored in a database but instead in an external application accessible

I need to make a web application and I want to use MVC. However, my Model can't be one of the standard Models -- the data is not stored in a database but instead in an external application accessible only via a API. Since this is the first MVC application I've implemented I'm relying on examples to understand how to go about it. I can't find any examples of a non-DB based Model. An example of a custom Model would be fine too. Can anyone point 开发者_如何学编程me to such a beast? Maybe MVC is just to new and none exist.

It seems like I might be able to get away with the DataSet Model, however I've not seen any examples of how to use this object. I expect an example of DataSet could help me also. (Maybe it is the same thing?)

Please note: I've seen countless examples of custom bindings. This is NOT what I want. I need an example of a custom Model which is not tied to a specific database/table.

UPDATE

I found a good example from MS located here:

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

While this is the "answer" to my question, I don't really like it because it ties me to MS's view of the world. @Aaronaught, @jeroenh, and @tvanfosson give much better answers from a meta perspective of moving my understanding (and yours?) forward with respect to using MVC.

I'm giving the check to @Aaronaught because he actually has example code (which I asked for.) Thanks all and feel free to add even better answers if you have one.


In most cases it shouldn't matter what the backing source is for the actual application data; the model should be exactly the same. In fact, one of the main reasons for using something like a repository is so that you can easily change the underlying storage.

For example, I have an MVC app that uses a lot of web services - rarely does it have access to a local database, except for simple things like authentication and user profiles. A typical model class might look like this:

[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; }
}

Then I will have a repository interface that looks like this:

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

The "API" is all encapsulated within the concrete repository:

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

Then I'll also probably have a local testing repository with just a few customers that reads from something like an XML file:

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.
}

The point I'm trying to make here is, well, this isn't tied to any particular database. One possible source in this case is a WCF service; another is a file on disk. Neither one necessarily has a compatible "model". In this case I've assumed that the WCF service exposes a model that I can map to directly with DataContract attributes, but the Linq-to-XML version is pure API; there is no model, it's all custom mapping.

A really good domain model should actually be completely independent of the true data source. I'm always a bit skeptical when people tell me that a Linq to SQL or Entity Framework model is good enough to use throughout the entire application/site. Very often these simply don't match the "human" model and simply creating a bunch of ViewModel classes isn't necessarily the answer.

In a sense, it's actually better if you're not handed an existing relational model. It forces you to really think about the best domain model for your application, and not necessarily the easiest one to map to some database. So if you don't already have a model from a database - build one! Just use POCO classes and decorate with attributes if necessary, then create repositories or services that map this domain model to/from the API.


I think what you are looking for is really a non-DB service layer. Models, typically, are relatively simple containers for data, though they may also contain business logic. It really sounds like what you have is a service to communicate with and need a layer to mediate between the service and your application, producing the appropriate model classes from the data returned by the service.

This tutorial may be helpful, but you'd need to replace the repository with your class that interacts with the service (instead of the DB).


There is no fixed prescription of what a "Model" in MVC should be, just that it should contain the data that needs to be shown on screen, and probably also manipulated.

In a well-designed MVC application, data access is abstracted away somehow anyway, typically using some form of the Repository pattern: you define an abstraction layer (say, an IRepository interface) that defines the contract needed to get and persist data. The actual implementation will usually call a database, but in your case should call your 'service API'.

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

0

精彩评论

暂无评论...
验证码 换一张
取 消