This document builds on the content of the previous documents, and enables the new ASP.NET MVC programmer create a substantial web app that has a data model.
This document helps the new ASP.NET MVC programmer create an interactive web app that gathers and processes user input.
This document describes the choices a new ASP.NET MVC programmer has for data persistence.
This document will help a programmer who’s new to ASP.NET MVC web development create their first simple web app.
This document will help second-year students in Seneca’s Software Development (BSD) degree program get started with ASP.NET MVC web development.
This post will teach you to add an Entity Framework data model to a WCF Service (SOAP XML Web Service).
It is the second in a two-part series. This document was most recently updated in December 2011.
In the previous post, you learned how to create a simple SOAP XML Web Service, by using the WCF Service item template. Here, you will learn how to add an Entity Framework data model to a service.
The scope of this post is modest. We will NOT be presenting a general-purpose n-tier approach. Part of the reason is that we cover this topic – SOAP XML Web Services – as a minor part of the overall course, in about three class and lab sessions.
We will, however, take advantage of the overall design and approach to modern SOAP XML Web Services development. The protocol and the standards, combined with the tooling, make it surprisingly easy to get good results with a reasonable amount of learning and effort.
Configuration of our solution
We will use a copy of the Northwind database in our solution.
For this task, we will also organize our work by using “projects”. (In past tasks, we have used the “web site” as the container.) We need a project feature – the ability to easily hard-code a port number for the ASP.NET Development Server – to simplify our learning task.
The image to the right shows the desired result for this section of the post.
To get started, create a new project, which will simply be a solution “container”:
File > New > Project…
On the left-side navigator, under Installed Templates, choose:
Visual C# > Other Project Types > Visual Studio Solutions
In the center panel, choose Blank Solution. At the bottom of the dialog, enter an appropriate name (e.g. “WebServiceSolution”), and select a location (which will be a file system location).
The solution’s folder/directory will be a container for two projects:
- A web service
- A client that will call the web service
Continue by creating the web service. In Solution Explorer, right-click the solution, then choose Add > New Project…
On the left-side navigator, under Installed Templates, choose Visual C#.
In the center panel, choose WCF Service Application. At the bottom of the dialog, enter an appropriate name (e.g. “WebService”), and make sure its location is the solution folder/directory from above.
Next, we need to configure a static port for the web service. This will ease our development process. Right-click the project, and choose Property Pages. On the Web tab, choose/select a fixed/static port. Save (Ctrl+S) your changes.
Continue by creating the client. In Solution Explorer, right-click the solution, then choose Add > New Project…
On the left-side navigator, under Installed Templates, choose Visual C# > Web.
In the center panel, choose ASP.NET Empty Web Application. At the bottom of the dialog, enter an appropriate name (e.g. “Requestor”), and make sure its location is the solution folder/directory from above.
Next, we should configure a static port for the client. As above, this will ease our development process. Right-click the project, and choose Property Pages. On the Web tab, choose/select a fixed/static port. Save (Ctrl+S) your changes.
Before continuing, compare your work to the image shown above. Build/compile, to make sure that there are no errors or warnings.
Note about build/compile:
The build/compile step is important for a “project”. If you change your markup or your code, you must do a build/compile. If you don’t, your changes will not be implemented in the exe/dll.
This is different from a “web site”, which has a build/compile-on-demand feature.
Important WCF Service principles
You have learned some basic principles of a WCF Service, and how it implements a SOAP XML Web Service:
- The “A” in “ABC”, address, is the publicly-accessible endpoint of your service.
- The “B”, binding, is (obviously) HTTP, as a SOAP XML Web Service.
- The “C”, contract is defined in the service interface, and implemented in the service class. A service contract will define the service’s operations, and a data contract will define the shape of the data that the service works with.
There are a number of other principles that affect our design and coding decisions, covered next.
For custom types (e.g. our own types, and/or the types that describe the Northwind entities, like Product, Supplier, Category, etc.), you must define a data contract. This enables the serializer, DataContractSerializer, to do its work. A data contract requires you to mark a class with attributes.
If the type defines a circular reference, then the data contract attribute must be:
However, the framework will also support unmarked types. This enables us to use POCO (Plain Old CLR Objects) types, such as those generated by the Entity Framework editor’s code generator.
To use POCO types with an Entity Framework data model, the entity names much match.
Each property must match up too (names and types). A property’s POCO type must be concrete (i.e. it cannot be an Interface). A property cannot use the “virtual” modifier.
Incidentally, for your information, the support for unmarked types is an example of “coding by convention“. This software design paradigm is present in other areas of WCF Service development.
For best results, you must configure the context to disable (i.e. set to false) proxy generation, and lazy loading. (If you need eager loading, then use Include() in the query.)
In a client, when a Service Reference is created, the client has a definition of the web service class, and all of its operations. From the client’s perspective, return types can include:
- Scalar / primitive types
- Generic dictionary
- Entity types (more on this in the next section)
- Collections, which are materialized as arrays (of… whatever type the web service sends)
Implementing these principles
Now that the principles have been established, we can begin our implementation. Here is a preview of our work:
In the web service project, we will create an Entity Framework data model.
Next, we will generate entity classes. These classes must be edited, to follow the “unmarked types” principles above.
Then, we will define and implement service operations (i.e. methods).
In the client project, we will add a Service Reference. This will create a proxy of the web service. What’s interesting is that the client will have a definition for the web service class, and all of its operations, and it will have definitions for the entity types.
We emphasize here again: As a result of the Service Reference creation, the client will have definitions for the entity types. This will enable the client to work with instances (and collections) of entity types. Put another way, the client will be able to (for example) fetch a specific “Product” or “Employee”, enable the browser user to edit it, and return/save the changes, all while knowing the object’s properties and structure.
Scope of our in-class efforts
As noted above, we will work with a copy of the Northwind sample database. The Entity Framework data model will include three entities: Product, Category, Supplier.
The web service will include these operations:
- Return the number of products in the data store (as an integer)
- Return a list of supplier names (as strings)
- Return a collection of categories
- Return a specific category
- Accept and save an edited/changed category
Data model and generated classes
In the web service project, create an Entity Framework data model. Include only these database tables in the data model:
Build/compile your work before continuing. Note that you may have to use the NuGet Package Manager to get the EntityFramework package.
Next, generate entity classes. Use the DbContext generator. Note that you may have to download this generator template.
Then, edit the entity classes. Follow the “unmarked types” principles above:
- Properties must be concrete types (not interfaces)
- Properties cannot be virtual
Suggestion: The Category class includes a Picture property. In our example today, we will not need it. Therefore, mark that property with the [IgnoreDataMember] attribute.
(You can delete/remove the text templates – the .tt files – if you wish. If you need to re-generate your classes later, you can always do so.)
Work on the web service
As the comment suggests, you may want to re-factor your code, to change “Service1” to “Service” (i.e. without the digit “1”).
In your web service interface, define the service operations (methods).
Next, implement the methods in the web service class. Pay attention to the return types. Use the general approach and technique you used while working on your WCF Web API services.
Build/compile your work before continuing, and ensure that the results are clean (no errors or warnings). Run the service, to ensure that you see the service start page.
Work on the client
Add a Service Reference to the project. A suggested name is “RemoteService”. The process will create a namespace – RemoteService – and classes for the web service itself (ServiceClient), as well as the entity classes.
Add an ASP.NET Web Form (Default.aspx) to the project. You will use this page to show the results of web service requests, and/or as a launcher to other pages that do the work.
Build/compile your work before continuing, and ensure that the results are clean (no errors or warnings). View the page in a browser after you do this.
Summary and wrap-up
The .NET Framework, and Visual Studio, work together to enhance your productivity when creating a SOAP XML Web Service.
Get more practice by completing Lab 5.
This post will introduce you to SOAP XML Web Services on WCF.
It is the first in a two-part series. This post uses an in-memory (per-instance) data store. The next post will use a persistent data store, accessed through the Entity Framework.
This document was most recently updated in November 2011.
At this point in the semester, you have some experience with one of the two styles of web services, RESTful. SOAP XML Web Services is the other style that you’ll encounter. Here are some key ideas that will help you get oriented with SOAP XML Web Services:
- The plain-text data interchange format is XML
- The XML conforms to SOAP
- Often, a SOAP XML Web Service is published on a single (URL) endpoint
- The service includes one or more methods; each method may accept parameters, and may return data
- Service discovery is built in to the specification/standard
- Requestors use GET or POST requests to interact with the web service
- Requestors can use the service discovery feature to create a proxy class that models the web service (in fact, this is typical with most programming platforms)
On the Microsoft Web Platform, WCF technology is used to create SOAP XML Web Services. Version 4 of the .NET Framework improved the design and coding experience, and we will use version 4 in this two-part series. Scan the following article, and read about the WCF and web services topics:
What’s new in WCF 4 article
FYI – legacy versions of the Microsoft Web Platform used “asmx” item types to host SOAP XML Web Services. They were easy to create, but they were a solution for a very limited set of use cases. Do not use “asmx” item types for new web services. Scan the following article to read about the differences:
Legacy info on the difference between asmx and wcf web services
What is a WCF Service?
In Visual Studio 2010, a SOAP XML Web Service is created as a WCF Service. The following will introduce WCF Service concepts and topics.
A WCF Service is a program that exposes one or more endpoints, each of which exposes one or more service operations.
An endpoint specifies:
- An address where the service can be found (e.g. http://host.domain.com/contacts.svc)
- A binding that tells the client how to communicate with the service (e.g. HTTP)
- A contract that defines the service’s functionality (e.g. it will do “this task” and “that task”)
Creating a WCF Service
You create a WCF Service in Visual Studio 2010. It is an (item type) that you can add to a Project or a Web Site.
A Web Site is software and resources that you create in a specific folder/directory. A Web Site must be hosted on a web server (e.g. either the ASP.NET Development Server, or a Microsoft Web Platform server). You can deploy a Web Site using a simple copy operation. The web server will compile and execute an endpoint upon request.
A Project is software and resources that you create in a specific folder/directory. A Project can be hosted on a web server, or on another kind of host (e.g. an executable, or a Windows Service). You must compile (build) the project (which creates an executable, either a dll or an exe) before you deploy it.
The default WCF Service item type (that you create with Visual Studio 2010) will create three software objects:
1. A publicly-accessible endpoint
2. A C# code-behind for the (above) publicly-accessible endpoint, which implements…
3. A C# interface that describes the “service contract” and “service operations”
The following sections include important information about each object.
You pick the name (e.g. “Contacts”), it adds a “svc” extension (e.g. “Contacts.svc”).
You don’t add code to this endpoint.
C# code-behind for the (above) publicly-accessible endpoint
This code file is located in the App_Code folder/directory.
For example, continuing to use the name above, it will be called “Contacts.cs”.
C# interface that describes the “service contract” and “service operations”
A “service contract” is an agreement to define and provide a number of “service operations”. An interface is used as the code container for both. By convention in the .NET Framework, an interface name begins with an upper-case letter “I”. The second letter is also upper-case.
For example, continuing to use the name above, the interface will be called “IContacts.cs”.
Each “service operation” is a method. The method will have a return value, and a parameter list.
Although not required, it is a best practice to use an interface to declare the “service contract” and “service operations”.
What is the relationship between the interface and the (class) implementation?
- The interface defines the service’s methods.
- The implementation contains code for these methods.
Method return values and parameters
As noted earlier, a method will have a return value, and a parameter list.
The types must be serializable (obviously).
Primitive types are serializable by default. Many other types in the .NET Framework are also serializable by default.
If you create your own types (e.g. Product, Supplier, Contact, Address, Customer, etc.), then you typically “mark” your types (with “attributes”) to define a “data contract”.
A “data contract” is an agreement to define and provide a number of “data members”. The default WCF Service item type adds the “data contract” to the interface code container.
For example, continuing to use the name above, it will be added to “IContacts.cs”.
Each type is a class (as it always is). You typically add the [DataContract] attribute to the class.
Public properties are used to define the publicly-accessible data members.
Each serializable property gets the [DataMember] attribute.
Creating a client requestor
When working on RESTful web services earlier in the semester, you learned that you could interact with your web service by using a browser, or an HTTP requestor like your Lab 1, Fiddler, or your service’s HTTP Test Client.
With SOAP XML Web Services, some of the same techniques can be used. However, the message packaging format is SOAP XML, which can be inconvenient to manually enter into a request.
Another approach is to create a client requestor. Conceptually, it will be similar to your Lab 1, because it will be able to make a request to the web service, and receive (and process) the response. That’s what we’ll do here, by creating an ASP.NET Web Forms client requestor.
The key concept is to create a proxy, which will “model” the web service. Visual Studio has built-in tooling for this. Right-click the (web site) root, and select “Add Service Reference”. This will enable you to connect to the web service, discover its functionality, and have Visual Studio create a local proxy of your web service’s classes.
Then, in your web form code-behind, you simply 1) create an instance of the proxy, and 2) call its methods.
On your own – create a web service, and a client requestor
In a new empty web site, create a service with two methods.
Method 1 will simply return your name (firstname last name) as a string.
Method 2 will return a collection (of strings) of your current-semester Seneca course codes (e.g. WSA500, SYS566, etc.).
In another new empty web site, create a (Default.aspx) web form that will call and display the data from the web service. Use Label web server controls for the data.
Preview of the topics we’ll cover in the next lecture
A blogger’s two-part series:
Another blogger’s article, some ideas are OK
Another blogger’s article on “what is an interface”
WCF and EF on StackOverflow – data contracts
Learn C# page
Interfaces – C# Programming Guide
Inheritance – C# Programming Guide