Currently I'm working on a project which is using WCF directly to interact with Service functionality instead of WCF RIA. The problem is I create Model for each Entity (in service) inside silverlight client application for validation, That's OK. But I should populate Server Entities with Client Models each time I want to Insert or Update an Entity in database. Is there any way to prevent these extra works?
A typical first version of an MVVM (Silverlight) Client and (WCF) Service has a lot of duplicate types, logic and mapping between types.
This is one of the reasons why WCF RIA Services has been created.
In a first version of an MVVM application the Model and ViewModel will be very similar. When new requirements appear and the Views get more and more functionality added these will diverge and the Model will become very different from the ViewModel.
The Model will be determined by the the service and the ViewModel by the Views. This will cause the mapping to be less and less trivial.
I have used T4 templates to generate ViewModels based on XML definitions. This prevented the need to write the boring, repetitive mapping code.
EDIT
See the MVMMapper project on Codeplex for the generation of ViewModels using T4
Related
I have a mvc web application which consumes web api service. If I want send complex form data represented in MyModel from mvc to the webservice, should webservice have MyModel as part of the project.
This way I would have MyModel on both projects, mvc and web service. Is this right approach?
In my opinion they should have different models and do the necessary mapping to avoid interdependent. In this case both projects ended up intact. This approach is called Data transfer object (DTO).
Benefits
You only care what you need thru mapping
No be big effect if model in different project change
Obviously you will not be tied up on other model outside of your domain
Disadvantages
You will end up many models
Expensive process
You will appreciate DTO specially if you're working in different teams working on different parts ex. One team woking on views and different team for backend. Also if your consuming external APIs. But you can apply this approach in your case.
I am doing some prototyping and have a small database (4 related tables) which I developed an Entity Framework 6 project around (DLL with models for the tables). I've added an ASP.NET MVC 4 Web App to the solution that includes Repository interfaces/implementations under the model folder. The Repositories add interfaces for CRUD operations against the EF project. The Web App has a set of controllers providing REST interface through the repositories. Standard stuff I believe.
The issue that I have is I want to create an aggregate class the wrappers types (models) defined in the EF and return that aggregate in response to a Get request. The question is where do I define this aggregate object? The EF project? (and how?). An independent class library (usable by a client)? The Web App?
Trying to keep all the model definitions in the same place that understood by a client and Web App service at the same time.
Thanks
I believe what you want here is the DTO (Data Transfer Object) pattern. See here and here for basic explanation of the pattern. The idea is that you define a set of classes distinct from your data access objects (EF classes in your case), whose purpose is to relay data between your REST interface and its clients. If you have C# clients to whom you want to make the class definitions visible for simplicity then I would suggest putting the DTO class definitions in their own class library project and have the server and client both reference that dll.
Please bear with me as I am new to MVC and WCF and may be asking the wrong question.
I am trying to write a WCF service and an MVC web application over an existing project that contains entity, data and business layers. The MVC and WCF components would then replace an older web service and WebForms application which worked very diferently and did not use modern practices.
I see the need to generate DTO objects against all Entity objects and was wondering how we can generate them. Through reflection, digging into the DbContext or some other method.
Furthermore, I also want to generate repository partial classes minimizing the need to maintain hand-written code for a large data model.
How do large development teams do this?
FYI, I'm working on my first MVC web application using MVC 3 and Razor with C#, and .NET3.5/4.0, and I'm looking for the "best pratice" approach for using existing web services in an MVC 3 application. From what I have figured out so far it looks like all I need to do is the following. Include a reference to the existing web service in the MVC project, create a Model for the data I desire to use in the application, create a Controller that makes the web service call that then fills an object created from the Model (reading about AutoMapper to see how this helps in that process), and then create a View to display the data that was translated into the MVC view model.
The part that I'm having questions about is what is the best way to retrieve and create/update the data from the web service. Maybe I'm over complicating this but it seems like I'm missing something.
Do I need to create a "Domain Model" that maps to the data retrieved from the web service and then create "View Models" that map to the domain model, and then use the View Models within the MVC 3 application?
Basically I'm looking for input on how best to use existing web services as my data access layer.
On your data access layer you would open the connection, get the raw data and then close it. Identically to how you would get data from your database. You would then convert this raw data to your business layer (domain model) via a data adapter. Then any top level applications, such as your MVC3 website, will convert this domain model into an approriate view model, along with any other data for rendering, again through a data adapter.
The main argument for doing it this way is that the service is now accessible to any top tier application that requires it. It is also makes logical sense to put any sort of data retrieval methods in your data access layer, since that's logically what the data access layer is designed to do.
There is always the temptation to simply access the service from your controller, but separation of concerns might suggest this is a bad way to structure your code. You should encapsulate the service as a domain/business layer service for your applications.
So in short, you don't need to, but best practice suggests you should. It can feel tedious sometimes when there is little or no conversion between layers, but it often helps to stay consistent.
To obey the MVC pattern and its separation of concerns, calling the database must be in the model. And if this web services calls the database somehow, it should be at the Model level.
let the UI talk to the model directly, in case later u needed a webservice to integrate with another system you can create a service which calls that model
And you may want to cache it if its read-only
I need some expert advice on strong typed data sets in ADO.NET that are generated by the Visual Studio. Here are the details. Thank you in advance.
I want to write a N-tier application where Presentation layer is in C#/windows forms, Business Layer is a Web service and Data Access Layer is SQL db.
So, I used Visual Studio 2005 for this and created 3 projects in a solution.
project 1 is the Data access layer. In this I have used visual studio data set generator to create a strong typed data set and table adapter (to test I created this on the customers table in northwind). The data set is called NorthWindDataSet and the table inside is CustomersTable.
project 2 has the web service which exposes only 1 method which is GetCustomersDataSet. This uses the project1 library's table adapter to fill the data set and return it to the caller. To be able to use the NorthWindDataSet and table adapter, I added a reference to the project 1.
project 3 is a win forms app and this uses the web service as a reference and calls that service to get the data set.
In the process of building this application, in the PL, I added a reference to the DataSet generated above in the project 1 and in form's load I call the web service and assign the received DataSet from the web service to this dataset. But I get the error:
Cannot implicitly convert type
'PL.WebServiceLayerReference.NorthwindDataSet'
to 'BL.NorthwindDataSet' e:\My
Documents\Visual Studio
2008\Projects\DataSetWebServiceExample\PL\Form1.cs
Both the data sets are same but because I added references from different locations, I am getting the above error I think.
So, what I did was I added a reference to project 1 (which defines the data set) to project 3 (the UI) and used the web service to get the DataSet and assing to the right type, now when the project 3 (which has the web form) runs, I get the below runtime exception.
System.InvalidOperationException:
There is an error in XML document (1,
5058). --->
System.Xml.Schema.XmlSchemaException:
Multiple definition of element
'http://tempuri.org/NorthwindDataSet.xsd:Customers'
causes the content model to become
ambiguous. A content model must be
formed such that during validation of
an element information item sequence,
the particle contained directly,
indirectly or implicitly therein with
which to attempt to validate each item
in the sequence in turn can be
uniquely determined without examining
the content or attributes of that
item, and without any information
about the items in the remainder of
the sequence.
I think this might be because of some cross referenceing errors.
My question is, is there a way to use the visual studio generated DataSets in such a way that I can use the same DataSet in all layers (for reuse) but separate the Table Adapter logic to the Data Access Layer so that the front end is abstracted from all this by the web service?
If I have hand write the code I loose the goodness the data set generator gives and also if there are columns added later I need to add it by hand etc so I want to use the visual studio wizard as much as possible.
I would stay away from datasets if I were you. They are very much a .NET 2.0 solution to the problem, and they weren't a very good solution, either.
I would use Entity Framework as a data layer - they do not have the issues a DataSet has, including the one you're seeing. A DataSet has to live in both worlds - both XML and relational, and they don't always fit. Entity Framework can build you entity models that need only conform to standard programming concepts like inheritance and association.
Entity Framework also has fewer issues when transferred over web services. You should use WCF for all your new web service work (Microsoft now considers ASMX web services to be "legacy technology"), but even with ASMX web services, EF entities will transfer fairly cleanly. There are some relatively minor issues in .NET 3.5, but those are addressed in .NET 4.0.
My question is, is there a way to use the visual studio generated DataSets in such a way that I can use the same DataSet in all layers (for reuse) but separate the Table Adapter logic to the Data Access Layer so that the front end is abstracted from all this by the web service
If you don't want to rewrite your app for EF or add DTOs, and you know the schemas are equal, you could set the data set schema in your presentation layer via the web service.
Project3DataSet.ReadXmlSchema(
new StringReader(Project2WebService.GetCustomersDataSetSchema()));
[WebMethod]
public string GetCustomersDataSetSchema()
{
return new Project1DataSet().GetXmlSchema();
}
Your data set schema acts as the object model. Not pretty but should do the job.
With that being said, if this is a new project, I agree with the other answers - avoid data sets.
I'd back up John here, we use EF v1.0 in N-tiered app and of course it has it's own problems but you get regular objects which you can push through service. However I'd advise ( in case you go with EF1 not EF4 which has ability to expose it's objects as POCO's) to have a separate layer of DTO objects which would me mapped to DO objects from you DAL, and use DTO for transfering through service. Also consider using .NET RIA services, they are really fantastic
#sb: on DTO, on EF, quick overlook of RIA services,
old article on DTO with datasets, what you are trying to do.