How to expose custom object (with sub objects) in web service? - asp.net

I'm kinda new to web services and want to make sure I am doing things correctly.
I have a custom object which has sub objects as well. (let's say Company object, sub object is collection of Employee objects)
I want the web service to return a collection of Company objects. Do I make the service return a Dataset and custom generate a dataset with datatables representing the different objects?
What is the best way to do this? I tried to just serialize it, but that doesn't seem to work either.
I tried this dll
http://www.codeproject.com/KB/linq/linqsqlserialization.aspx
But the output XML doesn't seem to include the sub object.

Whether you're using the 2.0 framework (with ASMX web services, which are no longer supported) or the 3.0 framework (with WCF), both will handle return of complex objects provided they are serializable. In the 2.0 framework, that means capable of marking your objects with the [Serializable] attribute. In the 3.0 framework, you're implementing serialization using the [DataContract] attribute. http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractattribute.aspx and http://msdn.microsoft.com/en-us/library/system.serializableattribute.aspx.
Both frameworks will enable the client-side WSDL in preparation for clients to consume your complex objects. Since they're non-primitives, you'll be limited to SOAP-based clients because the return payload will require complex representation.

Related

hiding method from certain layers in project

I was looking through an old project and wanted to see if anyone had a suggestion on how to hide certain methods from being called by various layers. This was a 3 tier project, webapplication -> web service -> database
In the application there is a User object for example. When a User was being updated, the webapplication would create a User object and pass it to the webservice. The webservice would use the DataAccessLayer to save the User object to the database. After looking at this I was wondering if instead I should have made a Save method in the User class. This way the service and simply call the Save on the User object which would trigger the db update.
However doing it this way would expose the Save to be called from the webapplication as well, correct? Since the webapplication also has access to the same User object.
Is there anyway around this, or is it better to avoid this altogether?
There is a separation of concerns by keepeing the User object as object that only holds data with no logic in it. you better keep it separated for the following reasons:
As you stated, it is a bad practice since the Save' functionality will be exposed to other places/classes where it is irrelevant for them (This is an important for programming generally).
Modifying the service layer - I guess you are using WCF web service as you can transfer a .NET object (c#/VB) to the service via SOAP. If you put the saving logic in the 'User' object, you can't replace it another webservice that receives a simple textual data structures like JSON or XML or simply doesn't support .NET objects.
Modifying the data storage layer - If you want, for example, to store the data inside a different place like other database such as MongoDB, RavenDB, Redis or what ever you want, you will have to reimplement each class that responsible for updating the data. This is also relevant for Unit Testing and Mocking, making them more complicated to interrogate.

ASP.NET Web API with multiple input objects

I am new to Web API and I have a Class Library I would like other applications to access via an ASP.NET Web API site.
The problem I have is that I do not know how to call methods that have multiple input objects some of which are custom entities (they all have several variables inside them and come from the Class Library which I don't have access to change).
Here is an example of one of the methods my API Controller
public bool Process(IBusinessObject businessObject, BusinessValidationObject businessValidationObject, IList<string> messages)
{
//Code to call Class Library is here that requires the 3 inputs
}
Is the above bit of code a valid API method?
I would like to call that method from another ASP.NET Web Application (an MVC application in another solution which will be installed on another server). I have had a look at the Web API Client Libraries but I can't see a way to pass in multiple objects.
Anyone have any ideas?
You can only post one complex object.
A solution might be to create an object that contains all three of the objects that you are trying to pass.

Making a Linq property optional while using in Webservice

I am using LINQ object in my webservice and consumed by iphone and android developers.
Now i have added some new fields in a table which in turn will be used linq object.
I want to know some way by which i can mark some linq properties as optional i.e. if iphone and android deve. doesnt pass that properties then no error will show up.
Thanks
Gaurav
First, it is not recommended to embed your LINQ objects directly in a web service. Create data objects specifically for the web service that captures the relevant parameters for each web service call. This will protect your service consumers from changes to the underlying data storage and allow you to more tightly control what is known to the consumers. You can then use the adapter pattern to convert objects in your web service to LINQ objects for submitting to database.
Secondly, regarding your question about optional parameters. With custom data objects, this will be easily done with nullable properties (for primitive types), or just null for object types. If you must use the LINQ objects, making the fields nullable in the database will also cause the properties to be nullable, and thus optional to service consumers.

SOA architecture for ASP.NET with Entity Framework

I am redesigning a solution's architecture to implement SOA.
After doing the design changes I have come up with:
MySolution.Client.MyProject.Web ...... //ASP.NET WebSite
MySolution.Client.MyProject.Proxy .... //Service Proxy C# Library Project *1
MySolution.Service ................... //Service.cs for Service.svc is here
MySolution.Service.DataContract ...... //IService.cs for Service.cs is here *[2]
MySolution.Service.HttpHost .......... //Service.svc is here
MySolution.Model ..................... //All custom data classes and EDMX model is here *[3]
MySolution.Repository ................ //Repository queries the DB using LINQ and ADO.NET queries
*1 MySolution.Client.MyProject.Proxy:
This project contains service proxy and contains presentation classes
*[2]MySolution.Service.DataContract:
This project contains IService and Request/Response Classes
All methods in Service.cs takes the Request classes as input and return Response classes as output
Therefore this project is referenced by the 2 Client Projects(Web and Proxy), as it contains the IService and all of the Request/Response classes that will be required to communicate with Service.cs
*[3]MySolution.Model:
This project contains the .edmx that is the Data Model of Entity Framework and some custom classes that are used in the project.
PROBLEM:
Because I only use request/response classes to communicate between service and client, the MySolution.Service.DataContract project is only used by Service.cs and Repository.cs
And due to that all responses that Repository generates I have to map them to the properties of its respective response class (which make both the original returned entity, and the response class almost identical). But I am OKAY with it...
For example:
The GetCustomer() in Repository.cs method is called by Service.cs
The GetCustomer() method in repository performs the LINQ query and returns a "Customer" object
Service.cs then maps all the properties of "Customer" object to the "CustomerResponse" object
Service.cs then returns the "CustomerResponse" to the caller.
In this case, most of the properties will repeat in both classes. If there is a solution to this, it's good, otherwise, I am fine with it.
However, when Repository.cs's method GetCustomers() (Notice it's not GetCustomer()) is called, it will return a list of Customer objects, and mapping this for return purposes would mean a "for loop" that iterates the collection and do the mapping... This is NOT OKAY...
Is there a better way of doing this, considering I do not want to return "Customer" object without "CustomerResponse" as first of all it violates the SOA architecture, and secondly I don't want my client projects to have any reference to the Model or Repository projects?
So is it just the mapping that you're having trouble with? If so, you could look at some open source mapping libraries like Mapper Extensions or AutoMapper that will automate the task.
If you don't like separate mapping between entities and DTOs expose IQueryable in your repository and use direct projections to DTOs. The disadvantage is that such solution can't be effectively unit tested. Mocking repository in such scenario doesn't make sense because query agains mock is Linq-to-objects whereas query against real repository is Linq-to-entities (different set of features where difference can be seen only at runtime).
Btw. I don't see too much SOA in your application - I see just multi tier application. It is like planting a tree in a garden and saying that you have a forest. Moreover it sounds like you are building CRUD interface (entities almost 1:1 to DTOs). I have a bad feeling that you are investing too big effort to architecture which you don't need. If your main intention is to build CRUD operations exposed as services on top of database you can expose entities directly moreover you can use tools like WCF Data services.
It sounds like your main point of grief is the tedious mapping of data objects to data transfer objects (DTOs). I haven't used this myself, but it seems like AutoMapper is made for doing automatic object-to-object mappings declaratively.
I would definitely stick to having your data objects separate from the data contracts in your services.

What are all the valid ASP.NET Webmethod return types?

Can my webmethod only return strings like I see in all the asp.net site examples?
asp.net Webmethods can return any serializable data type.
Assuming that this question is about the legacy ASMX web service technology, see Data Types Supported by XML Web Services Created Using ASP.NET.
Be sure to take note of where it says:
This topic is specific to a legacy technology. XML Web services and XML Web service clients should now be created using Windows Communication Foundation (WCF).
As far as I know, you can pretty much return any .NET class, including anonymous types. I've returned custom objects representing my business entities, including generic collections of children entities. Guids, ints, strings, etc. Anything that can be serialized into a string basically.

Resources