structuring of web services - asp.net

Consider 3 modules/classes in an ASP.NET Webforms application.
I need a web service for each of them, where each web service contains only one function.
Should I group them into one web service class, or should I keep the one web service for each class?

If they are related and need to be exposed for consumtion by a single client you could create one webservice and call this an API. This means you and your client maintain/consume a single webservice.
If they are clearly unrelated, separate them.

Group them in one class (the base webservice class). If it's needed you can branch from here and instantiate more complicated classes, or even call external libraries (for example if you have a data layer to call)

Related

Architectural Issue in ASP.Net application with Web API

We have an 3 layer architecture of ASP.Net application which builds with SQL back end and running in Production for last 2 years.
Now we plan to start develop Version 2 of that application by expose data through Web-API. So, we are busy creating the POC for that architectural implementation.
Problem is, we have an existing solution with 3 projects(ASP.NET+BAL+DAL). So, I planned to replace DAL with Web-API because it itself contains Models to interact with back end Database.
I have created a separate solution for Web-API. In my POC, Web-API runs in separate port(ex:localhost:122) & My ASP.NET application runs in with default port(ex:localhost:80). From my ASP.NET application, while I call the Web-API controllers its not returning results. But while checking the Web-API like "http://localhost:122/api/Products" i'm getting the responses.
While seeing the sample Architectures from google, People introduce "Service Layer" in the main(ASP.NET+BAL+ServiceLayer) solution and keep calling that service layer will internally call the original(withich connects with DB) Web-API. Is that only way of doing it ?
Please correct me if my assumptions are wrong.
When exposing a Web API, it is best to think of it like an alternate UI. It just so happens that it is a very ugly UI (proabably JSON or XML). And it isn't very usable by average users because they would have to construct requests by hand etc.
A 3 Tier architecture is about preserving the BAL and DAL for multiple front ends. Web API is an alternate front end. So, it would seem best to reference BAL and DAL inside a new process (the Web API) and then expose it.
I'm not sure if this is the same concept as a "Service Layer" or not. That term is overloaded with many different meanings to different people.
So, I would not replace the DAL with the Web API (because it has models etc). Instead, use the Web API models (or view models) to define the alternate front end structure and map to these from existing BAL services and entities.
Hope this helps.

Web Services Model

I have 1 Site (MySite.com) / 1 Web Service (WebService.MySite.Com) and one Common Library (LibCommon)
The common Library Contains a Model e.g. UserModel = LibCommon.UserModel
The web service has a method 'Void CheckUser(LibCommon.UserModel model)'
However when I add the 'WebService' reference to 'MySite.com' the method changes so that it looks like 'Void CheckUser(WebService.MySite.Com.UserModel model)'
So I think fair enough I can just cast one object to the other as they are identical however .NET Says I cannot do this?
Is there a work around for this?
Cheers,
Note this is for WCF, and not ASMX web services:
You can't directly cast the original data class to the proxied class generated by the WCF service reference wizard. However, you can reuse the original data class in the client:
Add the library reference containing the transfer objects (i.e. LibCommon) as a reference to both the Service (WebService) and the Client (Mysite.com). When adding the service reference on the client, choose the advanced tab and then select Reuse types in referenced assemblies. This will then reuse the common data transfer classes, instead of duplicating the types with proxies.
Note however that by eliminating the proxied data class, you are introducing direct coupling between client and server - you should do this only if you have control over both client and server w.r.t. version control issues etc (e.g. able to deploy new versions of both client and server simultaneously)
As an aside, it is also possible to eliminate the shared service interface as well, by moving the server side Service contract interface into a separate, common assembly and then using a technique such as this or this.

Creating/Exposing WCF services from an existing ASP.NET application

We need to expose some services (i.e. AddressValidatorService, CustomerFinderService) that currently reside in an ASP.NET application to other applications within our organization. Exposing these services via WCF seems like a natural fit, but I don't see any best-practices for how to pull these common services into a WCF wrapper in such a way that my existing ASP.NET application can continue to use them with minimal code changes and/or awareness that the service they are consuming is no longer in-process.
I'm especially looking for recommendations on how to structure the existing ASP.NET solution and whether to host our new WCF in the same solution or in some new shared WCF solution referenced by both our ASP.NET application and external callers.
Also, is it bad practice to simply promote the DTOs currently only consumed in-process via ASP.NET to full fledged data contracts or is it preferable to create duplicate DTOs that are explicitly decorated with [DataContract]? The latter seems like a maintenance nightmare.
To answer your second question:
Also, is it bad practice to simply promote the DTOs currently only consumed in-process via ASP.NET to full fledged data contracts or is it preferable to create duplicate DTOs that are explicitly decorated with [DataContract]? The latter seems like a maintenance nightmare.
It is considered a bad practice to expose your business model as WCF contracts. So if your DTOs are replicas of your domain model then it would be a strict no-no, because
1. any change in the model would directly effect the contracts and hence all the clients using it
2. you would be exposing your business "know-how" to the outside world.
The latter can tend to get difficult for any evolving system, but then you have various open source tools (like AutoMapper) that ease your mapping nighmares.
You can convert an existing project to WCF, then continue to use it in-process by using a project reference. It can then be consumed by an eternal source using the WCF client. A WCF client converts the class name from ClassName to ClassNameClient when consumed over WCF, but the class will function pretty much the same.
For example:
MyClass obj = new MyClass();
obj.DoSomething(withData);
Would become:
MyClassClient obj = new MyClassClient();
obj.DoSomething(withData);
You would publish the WCF project to some endpoint, like address.example.com, then use a service reference to the endpoint to reference the code, like a project reference, in your other projects.
Note that while the externally referencing projects would not be impacted by the change or know that the data is going over the network, if you have chatty calls to the project in question, it will definitely take a performance hit. You may want to consolidate related methods into single methods to save on round-tripping.
If these are exposed as static page services, there's no magic wrapper -- you're going to need to move code to a standalone service implementation class and put a .svc file in front of it. (Or use WCF4 fileless activation, or a service factory, but that's getting a bit away from the core question here.)
If these are exposed as ASMX, you can actually put an ASMX facade in front of a WCF service class and get basic HTTP/XML/ASMX responses as you would from your legacy ASMX webservices. You an expose that same WCF service class through standard WCF configuration for non-legacy consumers.
Finally, you can expose any WCF service as basicHTTP with serviceMetadata + httpGetEnabled, and you'll get a service endpoint usable by legacy consumers of an ASMX service.
http://msdn.microsoft.com/en-us/library/ms751433.aspx

Avoiding having to map WCF's generated complex types

I have an ASP.NET MVC web app whose controllers use WCF to call into the domain model on a different server. The domain code needs to talk to a database and access to the database server isn't always possible from web servers (depends on the customer site) hence the use of WCF to get to a place where my code is allowed to connect to the database server.
This is configurable so if the controllers are able to access the database server directly then I use local instances of the domain objects rather than use WCF.
Lets say I have a page asking for person details like age, name etc. This is a complex type that is a parameter on my WCF operation like this :
[OperationContract]
string SayHello( Person oPerson);
When I generate the client code (eg; by adding a service reference in my client) I get a separate Person class that fulfills the wcf contract. The client, an MVC web app, can use this client Person class as the view model and all is well. I pass that straight into the WCF client methods and it all works brilliantly.
If my mvc client app is configured to NOT use WCF I have a problem. If I am calling my domain objects directly from the controller (assume I have a domain access factory/provider setup) then I need the original Person class and not the wcf generated Person class. This results in my problem which is that I will have to perform mapping from one object to another if I don't use WCF
The main problem with this is that there are many domain objects that will need to be mapped and errors may be introduced such as new properties forgotten about in future changes
I'm learning and experimenting with WCF and MVC can you help me know what my options are in this scenario? I'm sure there will be an easy way out of this given the extensibility of WCF and MVC
Thanks
It appears that you are not actually trying to use a service-oriented architecture. In this case, you can place the domain objects into a single assembly, and share it between the WCF service and the clients. When creating the clients, use "Add Service Reference", and on the "Advanced" tab, choose "Share Types". Either choose to share all types, or choose the list of assemblies whose types you want to share.
Sound service-oriented-architecture dictates that you use message based communication regardless of whether your service is on another machine, in another process, in another appdomain, or in your appdomain. You can use different endpoints with different bindings to take advantage of the speed of the link (http, tcp, named pipes) based on the location of your service, but the code using that service would remain the same.
This may not be the easiest or least time-consuming answer, but one thing you can do is avoid using the "add service reference" option, and then copy your contract interfaces to your MVC application and initiate the connection to WCF manually without automatically creating a service proxy. This will allow you to use one set of classes for your model objects and you can control explicitly when to use WCF or not.
There's a good series of webcasts on WCF by Michele Leroux Bustamante, and I think in episode 2, she explains how to do exactly this. Check it out here: http://www.dasblonde.net/WCFWebcastSeries.aspx
Hope this helps!
One sound option is that you always use WCF, even if client and server are in the same process, as Aviad points out.
Another option is to define the service contracts on interfaces, and to put these, together with the data contracts into an assembly that is shared between client and server. In the client, don't use svcutil or a service reference; instead, use ClientFactory<T>.
This way, your client code will use the same interfaces and classes as the server.

Using a webservice as an interface for a data access layer in .NET

I am currently doing a CRUD project for school and basically they want us to have this kind of structure (3 projects):
Class Library
Contains all the data access logic (retrieving the data from the database with either LINQ of standard ADO.NET).
Web Service
Having a reference to the class library and offering [WebMethod]s that access the methods from the class library
ASP.NET Website
Having a service reference to the web service and using the WebMethods to retrieve the data
Which basically means that we cannot access the class library directly from the website:
Website
\
\
Web Service
\
\
Class Library
Now of course there are multiple solutions to choose from as to provide abstraction in the web service to separate for example methods that retrieve the articles and methods to retrieve the categories (which are two different entiries and have two seperate classes in the class libary):
I can either do one web service which will have all the methods (GetAllArticles, GetAllCategories, GetArticleByID, etc.) and the website only makes a reference to this one web service. But of course this will result in having all the methods in a single class (that is, a single web service)
Or I can create multiple web services (Articles.asmx, Categories.asmx etc...) and reference all of them from the website and then call the one I need depending on what data I need to retrieve.
But I mean for me, the above solutions are not really ideal because if I have the first solution, I will have a ton of methods all in one class (no abstraction whatsoever) and in the second solution, I will have to reference about 10 different web services from the website (one for articles, one for categories, etc.)
At school they told us to use the web service (or web services) to access the class library, and then retrieve the data from the class library using the Webmethods, but both solutions I mentioned earlier on seem a bit dodgy.
Is there a better way of how I might go about in implementing this structure?
In your example you suggested one service for Articles and one service for Categories. That may of course be just an example, but in that case it would not make sense to separate them, because it would be quite likely and common to have queries and/or routines which make use of both Category data and Article data.
With that in mind, it usually makes the most sense to group routines by the degree to which they are related to one another. If you can separate all your possible routines into, say, three clean groups with little to no overlap, then it makes sense to have three services. If you cannot cleanly separate any of your routines, you should limit yourself to one web service.
But regarding your statement "No abstraction" being a downside of one web service - that isn't necessarily true. You can always create layers of abstraction behind the web service, so that the service class itself is simply a facade with many thin method calls that reach into bulkier logic elsewhere.
In the end, the only approach which truly matters because it's the only approach which works is this: take the simplest approach possible, only build what you need to build in as few layers as you can; only add complexity when you reach a problem which cannot be solved in a better way than by adding that complexity. It is always easier to add complexity than to take it away.
I would put all the webmethods into the same class. The webmethods should only be wrappers around you business classes plus whatever input validation and authorisation you need.
Since web services are generally used by mahcines and not humans there is no pressing need for a hierarchy. It can become a burden to manage the URLs and web server if you create a webmethod class per business class.
If you are planning on using the HTML page that browsers automatically generate to call your web services as your main user interface you need to be a little bit careful. For example you won't be able to rely on SOAP headers if you need to authenticate requests.
Why not use ADO.Net Data Service?

Resources