|
|
|
|
|
Home
»
WCF
»
Developing Reliable Web Services using Indigo and WASP
|
|
|
|
Total page views :
5876
|
|
Total downloads :
13
|
|
|
|
|
Download
Files:
|
|
|
|
|
|
|
|
|
|
|
|
|
Similar ArticlesMost ReadTop RatedLatest
|
|
|
|
|
|
|
|
|
|
Source code: ReliableWS.zip 184 KB
Abstract
In just a few years Web Services has become the first option in distributed programming environments. The Web Services complexity requirements have been increased in the past years. In Enterprise applications is a common requirement to perform reliable messaging between the service provider and the service consumer. WS-ReliableMessaging (WS_RM) is a protocol that offers a solutions to this problem. In this article we explain the WS-RM basics and shows how to use develop reliable messaging applications in Longhorn using Indigo and in J2EE using WASP.
Introduction
Nowadays Web Services are adopted as a solution in a great number of distributed applications even in new domains such as mobile devices. Web Services are a relative new technology however a series of WSI protocols like WS-Transaction, WS-Discovery, WS-MetaDataExchange, etc, permit to develop robust Web Services with a variety of complex requirements.
The reliable messaging is a typical requirement of message-based applications. The Web Services aren't the exception. Without reliable messaging the service producer-consumer does not have any guaranteed that SOAP messages arrive to its destination in the correct order. Prevent and deal with this type of failure in a Web Service scenario is very difficult. Some of the most important Web Services technology providers offer reliable messaging solutions using Web Services. BEA Systems, for example, provides reliability in the Web Services developed in the WebLogic environments as part of a series of creative extensions to the Web Services capabilities. The reliable messaging proposal of BEA adds powerful features to Web Service however is very limited and non Standard.
The Web services Reliable Messaging is a standard specification that addresses the need for reliable message exchange in a Service Oriented Architecture. WS-RM provides the necessary elements to develop reliable messaging between the service provider and the service consumer. WS-RM is completely SOAP based with brings together a series of benefits like interoperability and transport independence. Mixing WS-RM with other WSI specifications like WS-Security, WS-Policy and WS-Atomic Transaction makes possible to develop robust reliable and secure Web Service solutions.
WS-ReliableMessaging
WS-RM provides the mechanisms to exchange messages in a reliable manner between source and destination. WS-RM deals with potentials errors in the message exchange such as messages lost, reordered, duplicated, etc. Also transports all the information necessary to implement important aspects like error-recovery and persistence mechanisms.
The main feature of WS-RM is guaranteed the delivery of message interchanged between the service provider and the service consumer. The guarantee that WS-RM infrastructure provides on the delivery of a message is expressed using delivery assurances. We can use different types of delivery assurances depending of the service's requirements.
AtMostOnce: Messages will be delivered at most once without duplication or an error will be raised on at least one endpoint. It is possible that some messages in a sequence may not be delivered. AtLeastOnce: Every message sent will be delivered or an error will be raised on at least one endpoint. ExactlyOnce: Every message sent will be delivered without duplication or an error will be raised on at least one endpoint. InOrder: Messages will be delivered in the order that they were sent. This delivery assurance may be combined with any of the above delivery assurances.
Using these assurances we can gain more control about the message exchange between the two endpoints. The following figure shows a simple WS-RM scenario.

Figure 1. Simple WS-RM scenario.
In this simple example the source application sends a SOAP message to the destination application the reliable messaging infrastructure in the source takes the message and sends it. On the other endpoint the reliable messaging infrastructure accepts the message and acknowledges based on the assurance and then pass the message to the application destination.
Until now WS-RM seems fantastic but as in programming nothing is magic we can explore some of the elements of the WS-RM protocol that makes possible develop a scenario like the explained above.
WS-RM elements
The main component of WS-RM is the sequence. Sequences serves as scope to the message sent from the source to the destination. Each sequence is identified using a unique identifier and each message within a sequence has a message number that is an increasing integer and serves as identifier. The use of the message number simplifies the detection of duplicate or missing messages.
The next example shows a simple sequence.
<wsrm:Sequence>
< wsu:Identifier>http://gsus.com/firstservice</wsu:Identifier>
< wsrm:MessageNumber>1</wsrm:MessageNumber>
< wsrm:LastMessage/>
</ wsrm:Sequence>
In some scenarios the message exchange protocol used requires the creation of new sequences. Sequences are created using a CreateSequence message. In response to CreateSequence message to the RM Destination can responds either with a CreateSequenceResponse or a CreateSequenceRefused fault. On the other hand, when you need to terminate a sequence use a TerminateSequence message which indicates that the sequence is completed and no further messages will send in this the Sequence.
Another important component of WS-RM is the Acknowledgements. An acknowledgement indicates that a range of messages are successfully transferred to the destination. The use of ranges decreases considerably the message's complexity. For example acknowledging 1 through 5 indicates that the messages 1, 2...5 are received successfully which are no the same that processed successfully. To acknowledges a sequence use the SequenceAcknowledgement message. The next message shows an acknowledgement message.
<wsrm:SequenceAcknowledgement>
< wsu:Identifier>http://gsus.com/firstservice</wsu:Identifier>
< wsrm:AcknowledgementRange Upper="2" Lower="1"/>
< wsrm:AcknowledgementRange Upper="6" Lower="4"/>
< wsrm:AcknowledgementRange Upper="10" Lower="8"/>
</ wsrm:SequenceAcknowledgement>
In some cases the RM Source may want to request an acknowledgement for some message. To perform this operation you use the AckRequested element.
< wsrm:AckRequested ...>
< wsu:Identifier> [URI] </wsu:Identifier>
< wsrm:MessageNumber> [unsignedLong] </wsrm:MessageNumber> ?
...
</ wsrm:AckRequested>
We have been explored some the most important elements of WS-RM. There are more, of course, such as fault messages among others. However in a reliable messaging scenario should exist some mechanism to expose the reliability requirements because these requirements can be very heterogeneous. We can define the reliable messaging requirements using a set of policy assertions based WS-Policy based standards: WS-Policy, WS-PolicyAttachment and WS-PolicyAssertions. The set of policy assertions is explained below.
-
Spec Version: The assertion that will be used to identify the protocol (and version).
-
Sequence Creation: Used by RM Destination to declare that it be responsible for creating new Sequences.
-
Sequence Expiration: Establishes the lifetime of a sequence.
-
Inactivity Timeout: This assertion specifies (in milliseconds) a period of inactivity for a Sequence. If during this duration an endpoint has received no application or control messages, the endpoint MAY consider the Sequence to have been terminated due to inactivity.
-
Retransmission Interval: An RM Source may optionally specify a base retransmission interval for a sequence. If no acknowledgement has been received for a given message within the interval, the RM Source will retransmit the message. The retransmission interval may be modified at the source's discretion during the lifetime of the sequence.
-
Acknowledgement Interval: Acknowledgements can be sent on return messages or sent stand-alone. In the case that a return message is not available to send an acknowledgement an RM Destination may wait for up to the acknowledgement interval before sending a stand-alone acknowledgement.
Until now we have been explored some of the most important concepts of WS-RM. Mixing these concepts we can develop robust applications that take advantages of reliable messaging potentialities. In the next section of this article we take a look to reliable messaging capabilities in two technologies leaders in the Web Services environments: Indigo and WASP.
Indigo
The communications infrastructure in Longhorn, code-named "Indigo," embodies a series of technologies that permit develop robust service-oriented applications. Indigo brings together powerful aspects of technologies like ASP.NET Web services, Web Services Enhancements, .NET Remoting, COM+, MSMQ, Enterprise Services and also adds other interesting features. Using Indigo we can build robust Web Services and Remote Objects uses potentialities like that transactions, security, asynchronous messaging, routing and -surprise, surprise- reliable messaging. It is not objective in this article to cover the Indigo concepts and architecture. To understand the Indigo basics you can check the Longhorn SDK and the Don Box's MSDN Magazine article, A Guide to Developing and Running Connected Systems with Indigo. However we can take an overivew to the Indigo architecture.
Overview
Basically Indigo is divided into two layers: the lower-level messaging layer that permits you to gain control over the messaging aspects of the applications, and the service-layer that makes possible to build high-level applications without the need to deal with lower level aspects of the implementation.
The messaging-layer is composed by a set of object that addresses important aspects in the message-based distributed applications. Understand the message-based layer means understand the main concepts in Indigo that makes possible extend the service-layer with lower level aspects like XML custom serialization, transports, etc.
The service-layer offers the possibility to build high-level service-based applications. You use the service layer to build distributed applications when you do not need to know anything about the infrastructure that sends them.
Reliable Messaging in Indigo
As we explained above Indigo offers a set of potentialities to develop advanced Web Services features. One of these features is the Reliable Messaging support which is provided by the means of Dialogs. When develop services using Dialogs we can also take advantage of other features that Dialogs provides like:
- Callbacks
- Persistence of service instances
- Sharing sessions
- Durability
The Web Services that uses Dialogs as part of their definition are inherently stateful. This means that the server maintain the object state in memory the Dialog are explicit ended. A Dialog must be initiated by only one endpoint but either endpoint can end it. As part of the message interchange Dialogs provides assurances determined by its reliable messaging configuration. In the Dialog is interrupted the state can also be preserved.
We can develop reliable messaging systems using Dialogs in the service-layer or in the low level messaging-layer.
Reliable messaging using DialogPortsType attribute.
Develop high-level reliable services in Indigo is as simple as put the DialogPortTypeAttribute as part of the service' class definition. In the following example we can see a simple service that uses Dialogs.
[DialogPortType(Name = "AddService", Namespace = "uri:IndigoServer")]
public class AddService
{
[ServiceMethod]
public int Add(int param1, int param2)
{
return param1 + param2;
}
[ServiceMethod]
public int Sub(int param1, int param2)
{
return param1 - param2;
}
}
Well, is amazingly simple. The only thing that we need to do to provides reliability is to add the DialogPortType attribute specifying a name and a namespace. The next step is to develop the service's host using the same code that in other Indigo applications (you can see it in the examples). Next we obtain the service' proxy that will be used in the client side using the wsdlgen utility passing the URL of the hosted server as parameter.
The client is as simple as any client application in Indigo. The next code shows a client's part that calls the two service's methods.
class MainClient
{
private IAddServiceChannel proxy;
public void MathTest()
{
int Result = proxy.Add(10, 5);
Console.Out.WriteLine(Result);
Result = proxy.Sub(10, 5);
Console.Out.WriteLine(Result);
}
public MainClient()
{
ServiceEnvironment se = ServiceEnvironment.Load();
ServiceManager manager = se[ typeof(ServiceManager)] as ServiceManager;
se.Open();
Uri uri = new Uri("soap.tcp://localhost:46000/IndigoServer/");
proxy = (IAddServiceChannel)manager.CreateChannel( typeof(IAddServiceChannel), uri);
}
Now we have a reliable messaging application in the service-layer. If we want to see the WS-RM messages in the Dialog we can use the MBSpy.exe utility that comes as part of the Indigo infrastructure. The whole log is provided as part of the Indigo samples included in this article. The following message' part shows a sequence acknowledgment.
------------------------------Header 0------------------------------
< wsa:Action xmlns:wsa="http://schemas.xmlsoap.org/ws/2002/12/addressing">
http://schemas.xmlsoap.org/ws/2003/02/RM#SequenceAcknowledgement
</ wsa:Action>
------------------------------Header 1------------------------------
< wsrm:SequenceAcknowledgement env:mustUnderstand="true" xmlns:env="http://www.w3.org/2001/12/soap-envelope" xmlns:wsrm="http://schemas.xmlsoap.org/ws/2003/02/RM">
< u:Identifier xmlns:u="http://schemas.xmlsoap.org/ws/2002/07/Utility">
http://schemas.microsoft.com/mb/2003/XX/SequenceId/d5d8bd40-a64c-41ed-9525-05f62de8e3bb
</ u:Identifier>
< wsrm:Range Upper="1" Lower="1" />
</ wsrm:SequenceAcknowledgement>
Reliable messaging using DialogChannel
In the messaging-layer we can also develop reliable messaging systems using DialogChannels. Indigo's DialogChannel provides reliable delivery guarantees, including "exactly once" ordered delivery.
To use DialogChannels in a service you must first create a DialogManager and associated with a port that identifies the endpoint in the dialog. The DialogManager class creates dialogs and also monitors incoming Dialogs using DialogRequested event. When a dialog is requested you can use the AcceptDialog method to accept the request and begin a new dialog with the remote initiator. The next step is to wire up handlers to the events in which you are interesting. For instance you can program handlers to events like: MessageAvailable, DoneReceiving, Done among others. The Run method in the following code performs the basic steps to create a DialogManager, and then the dialogManager_DialogRequested event handler exposes the logic to Accept an incoming Dialog.
private void dialogManager_DialogRequested(object sender, DialogRequestedEventArgs e)
{
try
{
dialogChannel = dgmanager.AcceptDialog(e.InitialMessage);
Session session = new Session(dialogChannel);
lock (activesessions)
{
activesessions.Add(session);
}
Console.WriteLine("Dialog Accepted" );
}
catch (Exception ex)
{
Console.WriteLine("ERROR: Could not accept incoming dialog:" );
return;
}
}
public void Run()
{
try
{
Uri myPortIdentity = new Uri(ConfigurationSettings.AppSettings["MyPortIdentityUri"]);
_port = new Port(myPortIdentity);
dgmanager = new DialogManager(_port);
dgmanager.DialogRequested += new DialogRequestedEventHandler(dialogManager_DialogRequested);
_port.Open();
}
catch (PortIOException e)
{
}
}
The code above makes reference to the Session class. This class precisely defines the handlers for the DialogChannel's events. In the following code listing we assign a handler for the MessageAvailable event and receive a message using Receive method. you can also see how to send a reply message using the Send method.
public class Session
{
private DialogChannel dialogChannel;
public Session(DialogChannel channel)
{
this.dialogChannel = channel;
dialogChannel.MessageAvailable += new EventHandler(dialogChannel_MessageAvailable);
}
private void GetEmail()
{
Uri ReplyAction = new System.Uri("http://tempuri.org/channels/GetEmailReply");
string response = "gsusmrv@fastmail.fm";
Message reply = new Message(ReplyAction, response);
dialogChannel.Send(reply);
}
private void dialogChannel_MessageAvailable(object sender, EventArgs e)
{
Message ActualMsg = dialogChannel.Receive();
if (ActualMsg != null)
{
string action = ActualMsg.Action.ToString();
if (action == "uri://getemail/")
GetEmail();
}
}
}
Finally we create a client that sends some messages to the service. Is very simple, the first thing that you need to do is to create a DialogManager and later a DialogChannel.
port = new Port(myUri);
DialogManager dlgMgr = new DialogManager(port);
channel = dlgMgr.CreateDialog(destination, DialogAssurances.Full);
channel.MessageAvailable += new EventHandler(channel_MessageAvailable);
port.Open();
Next all we need to do is to send messages using the Send method and receive messages providing a MessageAvailable event handler. The DialogAssurances class makes possible to set the reliable messaging assurances.
Uri act = new Uri("uri://getname");
Message requestMessage = new Message(act);
channel.Send(requestMessage);
In the Indigo's examples attached to this article we can explore the complete client's code.
Other features
Indigo provides additional features to the reliable messaging infrastructure. Two of the most remarkable are the failure recovery and the security support.
The state of the dialog is stored in a dialog store at each endpoint. The Dialog store can be a memory representation by default or a durable store. If the store is durable Indigo provides all the mechanism to recover the dialog's states for system's failures.
Using reliable messaging brings together the transmission of a set of additional messages that increases the security risks. Indigo provides a powerful security features that can be mixed to increase the security level of the Dialogs.
Say "good bye" to Indigo.
In the past section we explore the Indigo mechanisms to provide support to reliable messaging. Maybe Indigo is the most complete technology to build service oriented applications and reliability support is one of its key aspects. Now we can move away of Indigo and comes into the J2EE world. Exists a lot of Web Service's technology provides to the J2EE environments; however the support for WSI protocols are still in earlier stages (IBM is doing a great work in this aspect). As part of the recent release of "WASP Server for Java, 5.0" Systinet provides support for several We Service's advanced aspects included, of course, WS-ReliableMessaging.
WASP
WASP is a robust platform that provides the mechanisms to develop advanced Web Services applications. It can run as a stand-alone service, but is typically deployed onto one of the major J2EE application servers, such as BEA WebLogic, IBM WebSphere, and Sun ONE Application Server. It may be deployed onto a Java servlet engine, alternatively. WASP also implements some of the protocols of WSI and is interoperable with Microsoft.NET.
Overview
In same way as Indigo WASP segments the service types based in how they handle the incoming calls. Basically in WASP exists three types of services: · Java Services: Represents the higher-level services that delegate the processing of SOAP messages in the WASP infrastructure. · XML-SOAP Services: Represents a lower-level services that deal directly with the SOAP messages using JAXM and implements a predefined message exchange pattern. · Raw Services: Represents a still lower-level services that also deals directly with the SOAP messages.
Reliable Messaging in WASP.
In WASP the support to WS-ReliableMessaging is provided by the Sequence API. This API provides a homogeneous way to develop reliable messaging application either using Java Services or JAXM listener. WASP also provides other benefits like asynchronous calls and persistence mechanisms.
Similarly to the past section we now begin to explore some of the most relevant aspects of reliable messaging in WASP. To develop reliable messaging applications over WASP we use the Sequence API. Using this API we can gain control over the messaging process. Adding reliable capabilities to the services using WASP isn't as transparent as in Indigo, since the developer must work with the sequence API itself instead of delegating this work in the platform, but is also very simple. To begin a reliable message exchange the client may create an output sequence and start to send messages. The following code fragment shows this part of the process.
ServiceClient sc= ServiceClient.create("http://laura:6060/MainService/wsdl");
Sequence sq= Sequence.createOutputSequence(sc) ;
sq.setActive( true);
if(proxy != null)
{
int Result = proxy.Add(10, 5);
sq.setLastMessage();
}
You find the complete code as part of the WASP's examples attached to this article. The service receives and acknowledges reliable requests automatically. You can send reliable responses in the form of one message per sequence. The next code shows this part in the server side.
public int Add(int param1, int param2)
{
ServiceEndpoint testservice= Registry.getServiceEndpoint("/MainService");
Sequence sq= Sequence.createOutputSequence(testservice);
// SequenceCorrelationHelper.setupCorrelatedResponseSequence();
return param1 + param2;
}
We can use the SOAPSpy utility provided as part of the WASP tools to trace the SOAP messages. The following fragment shows the acknowledgment message produced when the Add method was invoked.
< wsrm:SequenceAcknowledgement e:mustUnderstand="1">
< wsu:Identifier>f19ee5e0-a704-11d8-b485-cdf4a621b485</wsu:Identifier>
< wsrm:AcknowledgementRange Lower="1" Upper="1"/>
</ wsrm:SequenceAcknowledgement>
The sequence may be an output sequence, like the used in the code above, or an input sequence that contains input messages. On the service side we can obtain the current sequence and query its data.
Sequence sequence = Sequence.getActiveInputSequence();
if (sequence != null)
{
System. out.println(sequence.getCurrentMessageNumber() + "; "" + sequence.getID());
}
The sequence in WASP may have different states as part of the message exchange process.
- OPEN: Some messages have not yet been sent and acknowledged (in output sequence) or acknowledged (in input sequence).
DELIVERED: In an output sequence, all messages sent up to this moment have been acknowledged (in output sequence). In an input sequence, all messages received up to this moment have been confirmed. The last message has not yet been sent or received.
COMPLETE: The sequence has been completed without errors. In an output sequence, all messages including the last message have been sent and acknowledged. In an input sequence, all messages including the last message have been confirmed. No more messages can be sent or received within this sequence.
BROKEN: The sequence was not able to fulfill the required delivery assurances or was aborted by the application. No more messages can be sent or received within this sequence.
DESTROYED: State of destroyed sequences. Such a sequence should no longer be used since it will be neither updated nor used by the active Sequence provider. No more messages can be sent or received within this sequence.
If you can gain control over the sequence's state you can register some events handler that are raised when the sequence acquire a determined state. This is one of the most powerful capabilities of WASP. Using this feature we can have full control over the reliable messaging process and can develop our message exchange pattern over WS-RM. To begin to listen for sequence's state changes you first implement a class that inherit for GenericSequenceListener. The next code defines a class that provides event handlers for when the sequence acquires the Complete or Broken states.
public static class OutSequencesListener extends GenericSequenceListener
{
public void onComplete(Sequence sequence, Sequence.State previous)
{
System. out.println("Sequence " + sequence.getID() + " is complete and was delivered");
}
public void onBroken(SequenceException exception, Sequence.State previousState)
{
System. out.println("Sequence " + exception.getSequence().getID() + " error:");
exception.printStackTrace();
}
}
The final step is associated a listener with a particular sequence.
Sequence seq = Sequence.createOutputSequence(sequencePrefix, true, client);
seq.addSequenceListener(listener);
seq.setLength(sequenceLength);
Using the Sequence-Listener is an interesting way to allow higher-level services to gain control over some WS-RM aspects. In the WASP's examples provided with this article you can find a typical Request-Reply application that uses some of the most powerful facilities of the sequence's model in WASP.
Other features
WASP brings together a set of additional capabilities that enlarge the horizon to the reliable messaging SOAP-based applications in J2EE. Among the most interesting features are the persistent sequences and explicit message confirmation.
In a similar way as Indigo WASP have mechanisms to persist the conversation's state in this particular case the sequence's state. A persistent sequence has the capacity to store its state and its undelivered messages to a store. Later, of course, the state can be recovered and the messages can be transmitted.
Another interesting feature of WASP is that allows the developers to perform explicit message's confirmation. Using this feature you turn off the implicit default message confirmation mechanism and take you the control of the message acknowledgements. Implicit and explicit confirmation may be combined in some scenarios to build powerful solutions.
Where are we?
This article has provided a glimpse into the WS-ReliableMessaging concepts. We also explored the WS-RM how to develop WS-RM based applications in .NET and J2EE environments using Indigo and WASP technologies respectively. Indigo and WASP provides different models in the their WS-RM implementations but both respects the WS-RM concepts and offers additional capabilities that make possible build powerful reliable messaging applications.
|
|
|
Login
to add your contents and source code to this article
|
|
|
|
|
|
|
|
|
|
|
|
C# Consulting is founded in 2002 by the founders of C# Corner. Unlike a traditional
consulting company, our consultants are well-known experts in .NET and many of them
are MVPs, authors, and trainers. We specialize in Microsoft .NET development and
utilize Agile Development and Extreme Programming practices to provide fast pace
quick turnaround results. Our software development model is a mix of Agile Development,
traditional SDLC, and Waterfall models.
|
|
Click here to learn more about C# Consulting. |
|
|
|
|
|
|
|
Introducing MaxV - one click. infinite control. Hyper-V Hosting from MaximumASP.
Finally – a virtual platform that delivers next-generation Windows Server 2008 Hyper-V virtualization technology from a managed hosting partner you can truly depend on. Visit www.maximumasp.com/max for a FREE 30 day trial. Hurry offer ends soon.
Climb aboard the MaxV platform and take advantage of High Availability, Intelligent Monitoring, Recurrent Backups, and Scalability – with no hassle or hidden fees.
As a managed hosting partner focused solely on Microsoft technologies since 2000, MaximumASP is uniquely qualified to provide the superior support that our business is built on. Unparalleled expertise with Microsoft technologies lead to working directly with Microsoft as first to offer IIS 7 and SQL 2008 betas in a hosted environment; partnering in the Go Live Program for Hyper-V; and product co-launches built on WS 2008 with Hyper-V technology.
|
Dynamic PDF
ceTE software specializes in components for dynamic PDF generation and manipulation. The DynamicPDF™ product line allows you to dynamically generate PDF documents, merge PDF documents and new content to existing PDF documents from within your applications.
|
NEW! ANTS Performance Profiler 6.0 out now!
Attach to running process... SQL profiling... I/O profiling... Command-line profiling... Silverlight profiling... Zero overhead mode... Line-Level Timings... Find out more
|
Go.NET
Build custom interactive diagrams, network, workflow editors, flowcharts, or software design tools. Includes many predefined kinds of nodes, links, and basic shapes. Supports layers, scrolling, zooming, selection, drag-and-drop, clipboard, in-place editing, tooltips, grids, printing, overview window, palette. 100% implemented in C# as a managed .NET Control. Document/View/Tool architecture with many properties&events. Optional automatic layout.
|
Dundas Software
Dundas Chart for .NET is the most advanced .NET charting package available today. With an extremely complete feature set, elegant architecture and easy implementation, Dundas Chart can quickly add advanced Charting functionality to enhance and transform ASP.NET and Windows Forms applications. Whether you are implementing charting into internal projects, or building applications for clients, Dundas Chart offers advanced technology and advanced results to get the most out of data.
|
60 FREE UI Controls from DevExpress
Register for your FREE copy on over 60 free presentation controls from
DevExpress - Absolutely Free-of-Charge without any royalties or distribution
costs. Visit Devexpress.com/60 today. Free controls include advanced lists box, dropdown calendar, rich text edit, spin
edit, tab control and so much more!
DevExpress engineers feature rich presentation controls and reporting tools for WinForms, ASP.NET, WPF, and Silverlight. Our technologies help you build your best, see complex software with greater clarity and deliver compelling business solutions for Windows and the web in the shortest possible time.
|
Microsoft Visual Studio 2010
Visualize your workspace with new multiple monitor support, powerful Web development, new SharePoint support with tons of templates and Web parts, and more accurate targeting of any version of the .NET Framework. Get set to unleash your creativity.
|
Nevron Chart for .NET 2010.1 Now Available
The leading .NET charting control now features PDF, Flash and Silverlight export, visualization of large datasets and more. Deliver true charting functionality to your BI, Scorecard, Presentation or Scientific apps. Download evaluation now.
|
Developer-Ready ASP.NET 2.0 Web Hosting with 3 MONTHS FREE
Now supporting .NET 3.0 Framework with Windows Workflow Foundation, Windows Communication Foundation (WCF), Windows Presentation Foundation (WPF), windows CardSpace (WCS)! Providing more flexibility for Developers with Web Services Support and a User/Permission Manger. Also supporting MS SQL 2005/2000 with Real-Time Backups, FREE Automated Attach .MDF Tool, FREE SQL Restore and Shrink SQL DB Tools, and SQL
|
Aurigma Image Uploader
Aurigma Image Uploader is a versatile upload solution for a wide range of websites. Whether it's a social networking site, photo sharing service, or content management system, Aurigma can do a heavy lifting. Multiple file upload, pre-upload photo resize, etc – all your uploading users will praise you for that!
|
|
|
|
|
|
|
|
|
|
|
|
|