writing a web service with dynamically determined web methods - c#

Let's say I have a text file of basic mathematical functions.
I want to make a web service that answers these mathematical functions. Say the first one is y=x*x. If I wanted to turn this into a web service, I could simply do this:
[WebMethod]
public int A(int x)
{
return x*x;
}
However, I've extracted the function from the list by hand and coded it into a function by hand. That's not what I want to do. I want the wsdl for the service to be generated at call time directly from the text file, and I want the web method calls to the service to go to a specific method that also parses the text file at run time.
How much heavy lifting is this? I've found a sample on how to generate WSDLs dynamically at this link, but there's a lot more to do beyond that and I don't want to bark up this tree if there are parts of the project that arn't feasible. Does anyone have any links, guides, books, or positive experiences trying this kind of thing?

This related StackOverflow question post might give you a lead.
The tip here is to use the SoapExtensionReflector class.
As I see it, you might be able to use that class as follows:
Create a web service containing 1 dummy method.
Subclass the SoapExtensionReflector and configure it in web.config.
As soon as your subclass is called for the dummy method, read the file with functions and dynamically add a method to the WSDL file for each function.
As you might agree, this sounds easier than it is, and I would personally prefer not to go there at all. The resulting code will probably be a bit of a maintenance nightmare.
Good luck :)
EDIT: it might actually be easier to write a little code generator, which generates the C# web service code from your file with functions. Then, let the WSDL generation be up to the framework you are using (e.g. WCF).
Obviously, this kind of kills the whole dynamic aspect of it + you would need to redeploy after ever change in the functions file. But then again, the cycle of 'generate code - build - redeploy' could easily be automated with some MSBuild tasks.
I guess the usefulness of such a solution depends on how often your file with functions changes...

I believe it's possible to add a metadata exchange endpoint programmatically in WCF - you may want to look into that. That would allow you to dynamically return WSDL to potential service clients who could query your webservice at runtime to determine which entry points are available. But it's definetely a bit of work - and not for the faint of heart.

Is a dynamic WSDL an absolute requirement? Not having a static WSDL also means you can't have a static (auto-generated) proxy class, which is a real PITA. Instead, you could expose the function signatures as plain old data, rather than as WSDL metadata:
[ServiceContract]
public interface IMathFunctions
{
[OperationContract]
FunctionDescription[] GetFunctionList();
[OperationContract]
object RunFunction(string funcName, object[] args);
}
public class FunctionDescription
{
string Name { get; set; }
Argument[] Arguments { get; set; }
TypeCode ReturnType { get; set; }
}
Public class Argument
{
String Name { get; set; }
TypeCode Type { get; set; }
}
You will need to use the [DataContract] and [DataMember] attributes on the FunctionDescription and Argument classes when using a version of .NET earlier than 3.5 SP1.

Related

Reusable Class Library Implementation

I've built a reusable Class Library to encapsulate my Authentication logic. I want to be able to reuse the compiled *.dll across multiple projects.
What I've got works. But, something about how I'm making the reference, or how my Class Library is structured isn't quite right. And I need your help to figure out what I'm doing-wrong/not-understanding...
I've got a Class Library (Authentication.dll) which is structured like this:
namespace AUTHENTICATION
{
public static class authentication
{
public static Boolean Authenticate(long UserID, long AppID) {...}
//...More Static Methods...//
}
}
In my dependent project I've added a reference to Authentication.dll, and I've added a using directive...
using AUTHENTICATION;
With this structure I can call my Authenticate method, from my dependent project, like so...
authentication.Authenticate(1,1)
I'd like to be able to not have to include that "authentication." before all calls to methods from this Class Library. Is that possible? If so, what changes do I need to make to my Class Library, or how I'm implementing it in my dependent project?
In C# a function cannot exist without a class. So you always need to define something for it, being a class for a static method or an object for an object method.
The only option to achieve that would be to declare a base class in the Authentication assembly from which you inherit in the dependent projects.
You could expose Authenticate as a protected method (or public works too), and call it without specifying the class name.
public class MyClassInDependentProject : authentication
{
public void DoSomething(int userId, long appId)
{
var success = Authenticate(userId, appId);
…
}
}
That said, you'll quickly find this to be a bad design. It conflates a cross-cutting concern with all sorts of other classes, and those classes are now precluded from inheriting from any other class.
Composition is a core principle of object-oriented programming, and we have the idiom "Favor composition over inheritance." This simply means that we break down complexity into manageable chunks (classes, which become instantiated as objects), and then compose those objects together to handle complex processing. So, you have encapsulated some aspect of authentication in your class, and you provide that to other classes compositionally so they can use it for authentication. Thinking about it as an object with which you can do something helps, conceptually.
As an analogy, think about needing to drill a hole in the top of your desk. You bring a drill (object) into your office (class). At that point, it wouldn't make sense to simply say "On," because "On" could be handled by your fan, your lamp, your PC, etc. (other objects in your class). You need to specify, "Drill On."
If you are making a class library in C# you should learn to use the naming conventions that exists: Design Guidelines for Developing Class Libraries
Here is how you should name namespaces: https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/interface
C# is also an object oriented language, hence the need of classes (using Authentication as you should name your class).
It also seems like the data source is hard coded. Your class library users (even if it's just you) might want to configure the data source.
Google about singleton and why it's considered to be an anti pattern today (in most cases).
You are obliged to use Class in order to invoke your method, just
When is static class just NameClass.Method
When is not static, you must create instance, ClassName ob = new ClassName(); ob.Method();
The format of a call like this is class.method, and you really can't escape using the "class" moniker even with the "using" designation. Something has to "host" the function.
I don't think what you are asking for is possible without using the base class method Jay mentioned. If all you want is to simplify the syntax whenever you call Authenticate() however, this silly solution (adding an extra method in each class that needs to do authentication) may be just what you want:
private static void DoAuth(long UserID, long AppID){
authentication.Authenticate(UserID, AppID)
}
If the ID's are always the same within some context, you could also overload it:
private static void DoAuth(){
DoAuth(1,1)
}
Yes, this does mean you have to add more code wherever you want to do the authentication (that's why it's silly! ;) ). It does also however, also reduce this:
authentication.Authenticate(1,1);
...into this:
DoAuth();
I leave the cost / benefit analysis of this up to you..
I know I am some 3 years late but here goes nothing.
To keep your code cleaner and more readable you should create a new namespace for all the re-usable code that you want to have. Then in that namespace have the Authentication Class and Authenticate Function.
To use this you can easily set a using on your namespace and use the function as you are doing like
Authentication.Authenticate()
But to use
Authenticate()
by itself you can always do
using MyNamespace.Authentication;
and in your code use Authenticate Function directly.

Good formats for storing configuration information like stored procedure names

In our application data tier we completely rely on stored procedures and web services for Data exchange. We use code like below in loads of pages to execute stored procedures
switch(requesttype)
{
case "GetEmployees":
switch (crud_type)
{
case "read":
Execute Stored Procedure 'A'
break;
}
break;
}
we are looking for ways to remove above code(which is inside class files) to some form of configuration file
We are looking for file storage format that are extremely fast to retrieve(read,parse etc) and save(write,modify etc)
We could implement a security layer above it
Achieve this without much fuss and major changes to existing code.
I think I got ahead of myself. You can't replace code with configuration because the code will do something while a configuration would simply tell the code what or how to do something (unless the configuration itself contains code in which case you've got a paradox). If you want to apply configurability to your code, you'll first need to make it more general/generic (your switch statements indicate that it is not general now). My approach to doing this is described in my original answer (below). It doesn't provide configurability on its own, but could be made to do so (I've done it fairly simply). The code is based on your original question so please readjust your eyes to read it correctly.
The option I've opted for in the past has been to use a factory (whether housed in a Singleton or passed to the function owning your code sample in the form of an IoC container.
Very high level implementation of my approach is basically to define a custom attribute which contains a property that indicates when your type is useful. Something like:
public class DbOperationAttribute : Attribute
{
public string Operation { get; set; }
}
And a common interface to provide the API needed for your code to be run. Something like:
public interface IDoSomethingSpecial
{
bool Execute(SomeExecutionContext context);
}
And then you decorate specific classes with the attribute and implement the interface to indicate that they are appropriate for each action:
[DbOperation(Operation = "Read")]
public class DBReadOperation : IDoSomethingUseful
{
// Our implementation of the `IDoSomethingUseful` interface
public bool Execute(SomeExecutionContext context)
{
// Do something useful in here
}
}
At some point in your program you will need to be able to discover which types are appropriate for which actions. I do this with reflection, though it could just as easily be done with configuration (which would defeat the point of the attribute). Several IoC containers provide similar discoverability attributes, though using someone else's you'll be left doing things their way (typically).
Once you've discovered which types are appropriate for which actions, you can use something like:
IDoSomethingUseful someAction = myCollectionOfUsefulThings(requesttype);
someAction.Execute(someInstanceOfOurContextType);
Based on this design I would lean towards just using the App.Config/Web.Config to store your configuration. It'll generally be there anyway; may as well use it for your purposes as well.

Implementing a DSL in C# for generating domain specific XML

I have a legacy HTTP/XML service that I need to interact with for various features in my application.
I have to create a wide range of request messages for the service, so to avoid a lot of magic strings littered around the code, I've decided to create xml XElement fragments to create a rudimentary DSL.
For example.
Instead of...
new XElement("root",
new XElement("request",
new XElement("messageData", ...)));
I'm intended to use:
Root( Request( MessageData(...) ) );
With Root, Request and MessageData (of course, these are for illustrative purposes) defined as static methods which all do something similar to:
private static XElement Root(params object[] content)
{
return new XElement("root", content);
}
This gives me a pseudo functional composition style, which I like for this sort of task.
My ultimate question is really one of sanity / best practices, so it's probably too subjective, however I'd appreciate the opportunity to get some feedback regardless.
I'm intending to move these private methods over to public static class, so that they are easily accessible for any class that wants to compose a message for the service.
I'm also intending to have different features of the service have their messages created by specific message building classes, for improved maintainability.
Is this a good way to implement this simple DSL, or am I missing some special sauce that will let me do this better?
The thing that leads me to doubt, is the fact that as soon as I move these methods to another class I increase the length of these method calls (of course I do still retain the initial goal of removing the large volume magic strings.) Should I be more concerned about the size (loc) of the DSL language class, than I am about syntax brevity?
Caveats
Note that in this instance the remote service poorly implemented, and doesn't conform to any general messaging standards, e.g. WSDL, SOAP, XML/RPC, WCF etc.
In those cases, it would obviously not be wise to create hand built messages.
In the rare cases where you do have to deal with a service like the one in question here, and it cannot be re-engineered for whatever reason, the answers below provide some possible ways of dealing with the situation.
Have you noticed that all the System.Linq.Xml classes are not sealed?
public class Root : XElement
{
public Request Request { get { return this.Element("Request") as Request; } }
public Response Response { get { return this.Element("Response") as Response; } }
public bool IsRequest { get { return Request != null; } }
/// <summary>
/// Initializes a new instance of the <see cref="Root"/> class.
/// </summary>
public Root(RootChild child) : base("Root", child) { }
}
public abstract class RootChild : XElement { }
public class Request : RootChild { }
public class Response : RootChild { }
var doc = new Root(new Request());
Remember this won't work for 'reading' scenarios, you will only have the strong-typed graph from the XML that your application creates via code.
Hand-cranking xml is one of the things which should be automated if possible.
One of the ways of doing this is to grab the messaging XSD definitions off your endpoint and use them to generate C# types using the xsd.exe tool.
Then you can create a type and serialize it using the XmlSerializer, which will pump out your xml message for you.
I noticed this article for constructing arbitrary XML with C#4.0 which is great.
The source for the library is here - https://github.com/mmonteleone/DynamicBuilder/tree/master/src/DynamicBuilder
At this time, there is a notable deficiency, no xml namespace support. Hopefully that will get fixed though.
As a quick example, here's how it's done.
dynamic x = new Xml();
x.hello("world");
Which yields:
<hello>world</hello>
Here's another quick example yanked from the article.
dynamic x = new Xml();
// passing an anonymous delegate creates a nested context
x.user(Xml.Fragment(u => {
u.firstname("John");
u.lastname("Doe");
u.email("jdoe#example.org");
u.phone(new { type="cell" }, "(985) 555-1234");
}));
Which yields:
<user>
<firstname>John</firstname>
<lastname>Doe</lastname>
<email>jdoe#example.org</email>
<phone type="cell">(985) 555-1234</phone>
</user>
Having used the Ruby library Builder this method of creating arbitrary XML is similarly terse, to the point that it verges on "fun"!
I've marked this as the answer, because, even though it doesn't directly speak to "using a DSL to create arbitrary XML" it tends to remove the need due to the extremely terse and dynamic nature of the syntax.
Personally I think this is the best way to create arbitrary XML in C# if you have the v4.0 compiler and have to crank it by hand, there are of course much better ways to generate XML automatically with serialization. Reserve this for XML which must be in a specific form for legacy systems only.
Writing this in C# seems an awful lot of work. Design your DSL as an XML vocabulary, and then compile it into XSLT, writing the compiler (translator) in XSLT. I've done this many times.

What is right way to code input parameters with complex types for a C# .net 2.0 WebService?

I am currently building a new version of webservice that my company already provides. The current webservice has an input parameter of type string. In that string an entire xml doc is passed. We then validate that string against an xsd (the same xsd given to the consumer). It looks something like this:
[WebMethod]
public bool Upload(string xml)
{
if (ValidateXML(xml))
{
//Do something
}
}
I am building the next version of this service. I was under the impression that passing an XML doc as a string is not the correct way to do this. I was thinking that my service would look something like this:
[WebMethod]
public bool Upload(int referenceID, string referenceName, //etc...)
{
//Do something
}
This issue that I am having is that in actuality there are a large amount of input parameters and some of them are complex types. For example, the Upload Method needs to take in a complex object called an Allocation. This object is actually made up of several integers, decimal values, strings, and other complex objects. Should I build the webservice like so:
[WebMethod]
public bool Upload(int referenceID, string referenceName, Allocation referenceAllocation)
{
//Do something
}
Or is there a different way to do this?
Note: this Allocation object has a hierarchy in the xsd that was provided for the old service.
Could it be that the original service only took in xml to combat this problem? Is there a better way to take in complex types to a webservice?
Note: This is a C# 2.0 webservice.
I would probably use the XSD with "xsd.exe" tool to create a XML Serializable object. Then you can deal with objects instead of string parameters. It also gives you the ability to not change the signatures of the WebService.
If you change the XSD to add another parameter all you will need to do is recreate the class again using XSD.exe tool. Make good use of partial classes here. Separate your auto generated class from your business logic. This way you can recreate the the class definition if the XSD changes as many times as you want, but not touch your business logic.
XML Serialization in the .NET Framework
If you were using 3.5, you could also use LINQ to XML to quickly parse out your XML parameters.
Jon, to answer your follow-up question first: If your clients are on multiple platforms (or at least, not all on .NET), the best approach is the so-called "WSDL-first". Define the service interface in WSDL - that's where services and methods will be defined - WSDL will reference a set of XSDs defining the data-holding objects passed to and returned from those methods. You can generate C# or Java code from WSDL/XSDs.
Back to your original question. For the same of maintainability, the best practice is to defined Request and Response classes for each web methods and never pass strings, bools, integers directly. For example,
// in your Web service class
[WebMethod]
public UploadResponse Upload( UploadRequest request ) {
...
}
...
[Serializable]
public class UploadResponse {
public bool IsSuccessful {
get { ... }
set { ... }
}
}
[Serializable]
public class UploadRequest {
public Allocation ReferenceAllocation {
get { ... }
set { ... }
}
// define other request properties
// ...
}
If you defined SOAP bindings in your WSDL file, UploadRequest object is extracted from the SOAP message and deserialized. By the time the control reaches your WebMethod implementation, you have a deserialized UploadRequest object in memory with all of its properties set.
To have a method like this: public bool Upload(string xml) in a [WebService] class and parse XML inside the method implementation is definitely something you should consider moving away from.
As long as your complex types are in some way XmlSerializable, then you shouldn't have any problems just using those complex types. Let the framework do the heavy lifting for you. It will generate an appropriate WSDL and the data will get serialized all by itself rather than you having to worry about validation and serialization.
[Serializable] is your friend.

What is best-practice when designing SOA WCF web-services?

Given an operation contract such as:
[OperationContract]
void Operation(string param1, string param2, int param3);
This could be redesigned to:
[MessageContract]
public class OperationRequest
{
[MessageBodyMember]
public string Param1 { get; set; }
[MessageBodyMember]
public string Param2 { get; set; }
[MessageBodyMember]
public int Param3 { get; set; }
}
[MessageContract]
public class OperationResponse
{
}
[OperationContract]
OperationResponse Operation(OperationRequest request);
One thing I like about the MessageContract is that I get a little more explicit control over the format of the SOAP message.
Similarly, I could write nearly the same code, but use a DataContract:
[DataContract]
public class OperationRequest
{
[DataMember]
public string Param1 { get; set; }
[DataMember]
public string Param2 { get; set; }
[DataMember]
public int Param3 { get; set; }
}
[DataContract]
public class OperationResponse
{
}
[OperationContract]
OperationResponse Operation(OperationRequest request);
One thing I like about the DataContract is that I can define IsRequired, Order, and Name.
Today I expect the only consumer will be a WCF client. However, I want to design contract first and adhere to SOA practices as much as possible. Rather than have WCF dictate my SOAP, WSDL, and XSD, I want the XML to define the WCF layer, but use WCF to generate this so as not to add any custom message processing to WCF. I want to follow the most common SOA XML conventions which I believe is probably all tags beginning in lowercase - am I right? And I want to be as version tolerant as possible.
Is it wise to always create Request and Response messages like this? Which of the three formats promotes the best SOA practices? Should I go one step further and define both a DataContract and a MessageContract whereby the MessageContract only contains the DataContract? Or should I only ever use DataContracts if I am truly exposing a new type (i.e. do not create message types as containers)?
A loaded set of questions I know, but I am trying to get to the heart of it, and I am not sure separating the questions provides sufficient context to get the answer I am looking for.
its always a best practice not to have multiple parameter in a operation contract, always have a type that wraps all the required parameters, this will help out in the long run. Your existing clients won't break when you add a new optional parameter.
I work in a business integration team where we integrate with other companies fairly regularly, (AT&T, Cox, Exxon ...) and have never seen a web service call that took more than a single parameter.
XML usually tends to be camelCased. WSDL and XML Schema use camelCasing for both elements and attributes, for example check out the syntax and schema.
Why SOAP was defined differently, I do not know, but it uses PascalCasing for elements and camelCasing for attributes, check here.
Similary, most of the WS* specs (maybe all) use PascalCasing for elements and attributes, see here. XML Schema is agnostic about the conventions of the types it defines for XML.
Thomas Erl writes many important books on SOA including "Service-Oriented Architecture". In Chapters 13 and 15 he provides a number of examples of the XML of the various parts of typical transactions. It defines types and object members in XML Schema using PascalCasing which nicely matches the normal patterns of C# for class and property naming. Thus WCF defaults already closely match the standards.
Regarding actual message naming, some conventions use camelCasing and others use PascalCasing, so my preference is to match the primary language needs, which in the WCF case is PascalCasing. And WCF defaults match some examples of how the request and response message should be written, some examples here.
So the only outstanding question is now the basic question of how much to standardize around the use of OperationContract, DataContract, and/or MessageContract.
Defining DataContract only when a you have a complex type (in XSD parlance) makes sense, and I tend to think YAGNI (You Ain't Gonna Need It) as pointed out by Terry is the correct choice, but Erl seems to suggest a much more process intensive version so I am still not sure the best approach to use as my default choice (the main part of the question).
I think it honestly depends on the scenario. If you're just exchanging simple types [i.e. string], OperationContract is certainly acceptable.
You should use MessageContract when you want to modify the message format and DataContract should be leveraged when you want to express a Complex Type, such as an address.
YAGNI comes to mind here.
I say don't over do it on getting too fancy looking to the future. WCF is already nicely SOA friendly. I say, in general, stick to the defaults and be careful about coupling until you have a specific need to do something elaborate.

Categories