Adding REST methods to WCF Data Services? - wcf

I need to extend my WCF Data Service to include additional methods, not only the database tables..
But it doesn't seem to be working correctly.
Firstly i want to ask if this is legal? or frowned upon?
The reason i need to do it is i need add additional REST methods that will make a call to ASP.NET Membership services (the tables are in the db) to validate a login i.e.
public bool IsValidLogin(string username, string password)
{
return System.Web.Security.Membership.ValidateUser(username, password);
}
Here is what i have (i have simplied the IsValidLogin for testing).
[WebGet(UriTemplate = "TestMe")]
public bool IsValidLogin()
{
return true;
}
// This method is called only once to initialize service-wide policies.
public static void InitializeService(DataServiceConfiguration config)
{
// TODO: set rules to indicate which entity sets and service operations are visible, updatable, etc.
// Examples:
config.SetEntitySetAccessRule("*", EntitySetRights.AllRead);
config.SetServiceOperationAccessRule("IsValidLogin", ServiceOperationRights.All);
Now when i go to
http://localhost/MyDataAccess/MyService.svc/IsValidLogin
It seems to work i get an true back in the form of XML. But i have set a URI so i thought i could do this
http://localhost/MyDataAccess/MyService.svc/TestMe
But it fails? I am really confused, any ideas?
Also for it to work I needed to add this line, but a little but confused here
config.SetServiceOperationAccessRule("IsValidLogin", ServiceOperationRights.All);
Any help really appreciated

Not commenting on the REST dicsussion above, just posting a link on documentation on how to do so called "service operations": http://msdn.microsoft.com/en-us/library/cc668788.aspx

The ServiceOperation notion is a tacked on capability to provide exactly the escape you needed when you wanted to do something other than read data from a table.
Unfortunately, the default path in WCF REST has lead you to misunderstand how RESTful systems are supposed to work. REST is not just about exposing some data at URLs.
You really have two choices, either stick with RPC style of distributed computing that WS-*/SOAP based WCF provides or spend some time learning what REST is really all about. There are some links here to get you started.
I can't tell you what is the right approach for your scenario. What I can tell you is that you are not going to learn how to do REST from using the current WCF REST implementation. I'm not saying it is impossible to do, you just will be doing a lot of swimming upstream.

Related

In AspNetCore, what is this currently called and can I encapsulate it?

I'm currently making a library that interacts with a particular API that requires an oAuth OIDC connection/token and I'd like to make something that makes that particular part easier for users of this library so they don't need all this custom code.
What is this currently called and is there an example of code?
I ask because from trying to get this work, the documentation is ALL OVER THE PLACE. It looks like this particular process has undergone significant changes multiple times as things went on from before netcore to netcore2 and now netcore31.
Both AddAuthentication and AddOpenIdConnect are extension methods.
An extension method allows you to "add" methods to a type without having to modify the type directly - the methods aren't actually added to the type, but we can call them as if they had been. This is useful in situations where you'd like to extend the behaviour of a class created by a third party but don't have access to the source code.
As for what the particular pattern in question is, whilst there is no canonical name, it's merely a way of encapsulating the configuration of services and dependencies for your application.
AddAuthentication is an extension method of IServiceCollection, which is services type. AddAuthentication has a return type of AuthenticationBuilder, and AddOpenIdConnect is an extension method for AuthenticationBuilder. This is the implementation of AddOpenIdConnect, but as you're looking to encapsulate the configuration, you could probably do something like this:
public static class OpenIdConnectExtensions
{
public static AuthenticationBuilder ConfigureOpendIdConnect(
this AuthenticationBuilder builder)
{
return builder.AddOpenIdConnect(options =>
{
options.SignInScheme = IdentityConstants.ExternalScheme;
// Do whatever else you need.
});
}
}
And call it as follows:
services
.AddAuthentication()
.ConfigureOpendIdConnect()
Middleware, on the other hand, is code that executes as part of a pipeline in order to process requests and responses. The middleware sits in the middle of receiving requests and sending responses, hence the name. This allows you do things such as always adding certain headers to responses without that logic being split across your application. As you correctly mentioned, you see these being applied via calls such as app.UseXyz().

Need some advice for a web service API?

My company has a product that will I feel can benefit from a web service API. We are using MSMQ to route messages back and forth through the backend system. Currently we are building an ASP.Net application that communicates with a web service (WCF) that, in turn, talks to MSMQ for us. Later on down the road, we may have other client applications (not necessarily written in .Net). The message going into MSMQ is an object that has a property made up of an array of strings. There is also a property that contains the command (a string) that will be routed through the system. Personally, I am not a huge fan of this, but I was told it is for scalability and every system can use strings.
My thought, regarding the web services was to model some objects based on our data that can be passed into and out of the web services so they are easily consumed by the client. Initially, I was passing the message object, mentioned above, with the array of strings in it. I was finding that I was creating objects on the client to represent that data, making the client responsible for creating those objects. I feel the web service layer should really be handling this. That is how I have always worked with services. I did this so it was easier for me to move data around the client.
It was recommended to our group we should maintain the “single entry point” into the system by offering an object that contains commands and have one web service to take care of everything. So, the web service would have one method in it, Let’s call it MakeRequest and it would return an object (either serialized XML or JSON). The suggestion was to have a base object that may contain some sort of list of commands that other objects can inherit from. Any other object may have its own command structure, but still inherit base commands. What is passed back from the service is not clear right now, but it could be that “message object” with an object attached to it representing the data. I don’t know.
My recommendation was to model our objects after our actual data and create services for the types of data we are working with. We would create a base service interface that would house any common methods used for all services. So for example, GetById, GetByName, GetAll, Save, etc. Anything specific to a given service would be implemented for that specific implementation. So a User service may have a method GetUserByUsernameAndPassword, but since it implements the base interface it would also contain the “base” methods. We would have several methods in a service that would return the type of object expected, based on the service being called. We could house everything in one service, but I still would like to get something back that is more usable. I feel this approach leaves the client out of making decisions about what commands to be passed. When I connect to a User service and call the method GetById(int id) I would expect to get back a User object.
I had the luxury of working with MS when I started developing WCF services. So, I have a good foundation and understanding of the technology, but I am not the one designing it this time.
So, I am not opposed to the “single entry point” idea, but any thoughts about why either approach is more scalable than the other would be appreciated. I have never worked with such a systematic approach to a service layer before. Maybe I need to get over that?
I think there are merits to both approaches.
Typically, if you are writing an API that is going to be consumed by a completely separate group of developers (perhaps in another company), then you want the API to be as self-explanative and discoverable as possible. Having specific web service methods that return specific objects is much easier to work with from the consumer's perspective.
However, many companies use web services as one of many layers to their applications. In this case, it may reduce maintenance to have a generic API. I've seen some clever mechanisms that require no changes whatsoever to the service in order to add another column to a table that is returned from the database.
My personal preference is for the specific API. I think that the specific methods are much easier to work with - and are largely self-documenting. The specific operation needs to be executed at some point, so why not expose it for what it is? You'd get laughed at if you wrote:
public void MyApiMethod(string operationToPerform, params object[] args)
{
switch(operationToPerform)
{
case "InsertCustomer":
InsertCustomer(args);
break;
case "UpdateCustomer":
UpdateCustomer(args);
break;
...
case "Juggle5BallsAtOnce":
Juggle5BallsAtOnce(args);
break;
}
}
So why do that with a Web Service? It'd be much better to have:
public void InsertCustomer(Customer customer)
{
...
}
public void UpdateCustomer(Customer customer)
{
...
}
...
public void Juggle5BallsAtOnce(bool useApplesAndEatThemConcurrently)
{
...
}

How to handle multiple storage backends transparently

I'm working with an application right now that uses a third-party API for handling some batch email-related tasks, and in order for that to work, we need to store some information in this service. Unfortunately, this information (first/last name, email address) is also something we want to use from our application. My normal inclination is to pick one canonical data source and stick with it, but round-tripping to a web service every time I want to look up these fields isn't really a viable option (we use some of them quite a bit), and the service's API requires the records to be stored there, so the duplication is sadly necessary.
But I have no interest in peppering every method throughout our business classes with code to synchronize data to the web service any time they might be updated, and I also don't think my entity should be aware of the service to update itself in a property setter (or whatever else is updating the "truth").
We use NHibernate for all of our DAL needs, and to my mind, this data replication is really a persistence issue - so I've whipped up a PoC implementation using an EventListener (both PostInsert and PostUpdate) that checks, if the entity is of type X, and any of fields [Y..Z] have been changed, update the web service with the new state.
I feel like this is striking a good balance between ensuring that our data is the canonical source and making sure that it gets replicated transparently and minimizing the chances for changes to fall through the cracks and get us into a mismatch situation (not the end of the world if eg. the service is unreachable, we just do a manual batch update later, but for everybody's sanity in the general case, the goal is that we never have to think about it), but my colleagues and I still have a degree of uncomfortableness with this way forward.
Is this a horrid idea that will invite raptors into my database at inopportune times? Is it a totally reasonable thing to do with an EventListener? Is it a serviceable solution to a less-than-ideal situation that we can just make do with and move on forever tainted? If we soldier on down this road, are there any gotchas I should be wary of in the Events pipeline?
In case of unreliable data stores (web service in your case), I would introduce a concept of transactions (operations) and store them in local database, then periodically pull them from DB and execute against the Web Service (other data store).
Something like this:
public class OperationContainer
{
public Operation Operation; //what ever operations you need CRUD, or some specific
public object Data; //your entity, business object or whatever
}
public class MyMailService
{
public SendMail (MailBusinessObject data)
{
DataAcceessLair<MailBusinessObject>.Persist(data);
OperationContainer operation = new OperationContainer(){Operation=insert, Data=data};
DataAcceessLair<OperationContainer>.Persist(operation);
}
}
public class Updater
{
Timer EverySec;
public void OnEverySec()
{
var data = DataAcceessLair<OperationContainer>.GetFirstIn(); //FIFO
var webServiceData = WebServiceData.Converr(data); // do the logic to prepare data for WebService
try
{
new WebService().DoSomething(data);
DataAcceessLair<OperationContainer>.Remove(data);
}
}
}
This is actually pretty close to the concept of smart client - technically not logicaly. Take a look at book: .NET Domain-Driven Design with C#: Problem-Design-Solution, chapter 10. Or take a look at source code from the book, it's pretty close to your situation: http://dddpds.codeplex.com/

Request/Response pattern in SOA implementation

In some enterprise-like project (.NET, WCF) i saw that all service contracts accept a single Request parameter and always return Response:
[DataContract]
public class CustomerRequest : RequestBase {
[DataMember]
public long Id { get; set; }
}
[DataContract]
public class CustomerResponse : ResponseBase {
[DataMember]
public CustomerInfo Customer { get; set; }
}
where RequestBase/ResponseBase contain common stuff like ErrorCode, Context, etc. Bodies of both service methods and proxies are wrapped in try/catch, so the only way to check for errors is looking at ResponseBase.ErrorCode (which is enumeration).
I want to know how this technique is called and why it's better compared to passing what's needed as method parameters and using standard WCF context passing/faults mechanisms?
The pattern you are talking about is based on Contract First development. It is, however not necessary that you use the Error block pattern in WCF, you can still throw faultexceptions back to the client, instead of using the Error Xml block. The Error block has been used for a very long time and therefore, a lot of people are accustom to its use. Also, other platform developers (java for example) are not as familiar with faultExceptions, even though it is an industry standard.
http://docs.oasis-open.org/wsrf/wsrf-ws_base_faults-1.2-spec-os.pdf
The Request / Response pattern is very valuable in SOA (Service Oriented Architecture), and I would recommend using it rather than creating methods that take in parameters and pass back a value or object. You will see the benefits when you start creating your messages. As stated previously, they evolved from Contract First Development, where one would create the messages first using XSDs and generate your classes based on the XSDs. This process was used in classic web services to ensure all of your datatypes would serialize properly in SOAP. With the advent of WCF, the datacontractserializer is more intelligent and knows how to serialize types that would previously not serialize properly(e.g., ArrayLists, List, and so on).
The benefits of Request-Response Pattern are:
You can inherit all of your request and responses from base objects where you can maintain consistency for common properties (error block for example).
Web Services should by nature require as little documentation as possible. This pattern allows just that. Take for instance a method like public BusScheduleResponse GetBusScheduleByDateRange(BusDateRangeRequest request); The client will know by default what to pass in and what they are getting back, as well, when they build the request, they can see what is required and what is optional. Say this request has properties like Carriers [Flag Enum] (Required), StartDate(Required), EndDate(Required), PriceRange (optional), MinSeatsAvailable(Option), etc... you get the point.
When the user received the response, it can contain a lot more data than just the usual return object. Error block, Tracking information, whatever, use your imagination.
In the BusScheduleResponse Example, This could return Multiple Arrays of bus schedule information for multiple Carriers.
Hope this helps.
One word of caution. Don't get confused and think I am talking about generating your own [MessageContract]s. Your Requests and Responses are DataContracts. I just want to make sure I am not confusing you. No one should create their own MessageContracts in WCF, unless they have a really good reason to do so.

WCF Service Client Lifetime

I have a WPF appliction that uses WCF services to make calls to the server.
I use this property in my code to access the service
private static IProjectWcfService ProjectService
{
get
{
_projectServiceFactory = new ProjectWcfServiceFactory();
return _projectServiceFactory.Create();
}
}
The Create on the factory looks like this
public IProjectWcfService Create()
{
_serviceClient = new ProjectWcfServiceClient();
//ToDo: Need some way of saving username and password
_serviceClient.ClientCredentials.UserName.UserName = "MyUsername";
_serviceClient.ClientCredentials.UserName.Password = "MyPassword";
return _serviceClient;
}
To access the service methods I use somethingn like the following.
ProjectService.Save(dto);
Is this a good approach for what I am trying to do? I am getting an errorthat I can't track down that I think may be realted to having too many service client connections open (is this possible?) notice I never close the service client or reuse it.
What would the best practice for WCF service client's be for WPF calling?
Thanks in advance...
You're on the right track, I'd say ;-)
Basically, creating the WCF client proxy is a two-step process:
create the channel factory
from the channel factory, create the actual channel
Step #1 is quite "expensive" in terms of time and effort needed - so it's definitely a good idea to do that once and then cache the instance of ProjectWcfServiceFactory somewhere in your code.
Step #2 is actually pretty lightweight, and since a channel between a client and a service can fall into a "faulted state" when an exception happens on the server (and then needs to be re-created from scratch), caching the actual channel per se is less desirable.
So the commonly accepted best practice would be:
create the ChannelFactory<T> (in your case: ProjectWcfServiceFactory) once and cache it for as long as possible; do that heavy lifting only once
create the actual Channel (here: IProjectWcfService) as needed, before every call. That way, you don't have to worry about checking its state and recreating it as needed
UPDATE: "what about closing the channel?" asks Burt ;-) Good point!!
The acccepted best practice for this is to wrap your service call in a try....catch....finally block. The tricky part is: upon disposing of the channel, things can do wrong, too, so you could get an exception - that's why wrapping it in a using(....) block isn't sufficient.
So basically you have:
IProjectWcfService client = ChannelFactory.CreateChannel();
try
{
client.MakeYourCall();
}
catch(CommunicationException ce)
{
// do any exception handling of your own
}
finally
{
ICommunicationObject comObj = ((ICommunicationObject)client);
if(comObj.State == CommunicationState.Faulted)
{
comObj.Abort();
}
else
{
comObj.Close();
}
}
And of course, you could definitely nicely wrap this into a method or an extension method or something in order not to have to type this out every time you make a service call.
UPDATE:
The book I always recommend to get up and running in WCF quickly is Learning WCF by Michele Leroux Bustamante. She covers all the necessary topics, and in a very understandable and approachable way. This will teach you everything - basics, intermediate topics, security, transaction control and so forth - that you need to know to write high quality, useful WCF services.
Learning WCF http://ecx.images-amazon.com/images/I/41wYa%2BNiPML._BO2,204,203,200_PIsitb-sticker-arrow-click,TopRight,35,-76_AA240_SH20_OU01_.jpg
The more advanced topics and more in-depth look at WCF will be covered by Programming WCF Services by Juval Lowy. He really dives into all technical details and topics and presents "the bible" for WCF programming.