More Reasons to Not use ASMX Services in New Code

Many people continue to use ASMX web services despite my earlier post “Microsoft says: ASMX Web Services are a “Legacy Technology”” and other such warnings. This is, of course, a matter of personal preference. Here are some of the many reasons why I personally prefer not to use ASMX services for new development:

  1. ASMX web services are Microsoft’s first attempt at web services. They were a good start – they showed us why we need WCF.
  2. There are very few extensibility points.
  3. ASMX supports only SOAP 1.1 and 1.2, and can be coerced into returning JSON for JavaScript support. WCF supports those features plus everything else.
  4. ASMX can only be  hosted in IIS
  5. No support for any of the WS-* standards
  6. Again, ASMX Web Services are a “Legacy Technology”
  7. They are based on the old XML Serialization technology, which is not getting bug fixes. (see Microsoft comment on 1/11/2010)
  8. only proactively fixing the most critical customer impactful issues in XmlSerializer and xsd.exe, which are the technologies on which the SOAP support of ASMX services are based (see Microsoft comment on10/1/2008)
  9. no longer making enhancements to ASMX (see Microsoft comment on 6/29/2009 7:09 PM)

Whenever I’m asked, I recommend requiring that any new code deployed into a Production environment should be based on technology that is supported by the vendor. To me, this isn’t a simple matter of whether the code is on the vendor’s “supported” list. After all, ASMX is part of .NET 2.0, which is still supported. To me, it’s a question of, “if this technology breaks in my Production environment, can I count on the vendor fixing the bug”. In the case of ASMX web services and their underlying XML Serialization technology, the answer is, “no”.

As the links above demonstrate, we can count on Microsoft not fixing such bugs


7. Posted by Microsoft on 1/11/2010 at 11:34 PM

We have confirmed that the inherited properties do not show up in SOAP Sample on the browser and that is indeed a bug in the product.
At this point, this area is in maintainance (sic) mode, and no active work is planned.
thank you for reporting it.

8. Posted by Microsoft on 10/1/2008 at 10:10 AM

Thanks for finding this. We have investigated the issue and it is a bug. A workaround is to modify the generated schema to trick the code generation logic to not generate the multi-dimensional array. You can do this by adding a dummy attribute to the schema type. Unfortunately, we’re only proactively fixing the most critical customer impactful issues in XmlSerializer and xsd.exe. If this issue is causing business impact please contact Microsoft Product Support Services and we will be happy to explore various options.
Ed Pinto

9. Posted by Microsoft on 6/29/2009 at 7:09 PM

We’re no longer making enhancements to ASMX; we continue to support its existing functionality, but where possible, we recommend using WCF instead.

Posted in ASMX, Web Services, XML Serialization | 4 Comments

My Favorite Backup Software is Back from the Dead

I’ve been in the IT industry since the days when 6250 bpi reel to reel magnetic tape was a big deal. I’ve done a lot of backups, and one thing I’ve learned is: it’s not a backup if you can’t restore it.

After years of frustration with IOMEGA Backup (which often could not restore a backup), I found salvation in the form of a product named Dantz Retrospect. These people understood backup. Their software wasn’t the easiest to use in the world, but once set up, it pretty much just worked. I never found a situation where it couldn’t restore files correctly.

Unfortunately, it was sold to EMC back in 2004. Now, although EMC knew hardware, they proved to me that they didn’t know backup software. I pretty much stopped buying upgrades for Retrospect by version 7.5.

But today, I got an email telling me about “Retrospect 9 for Mac”. Now, I don’t have a Mac, but the idea of a new version of software named Retrospect interested me enough to browse to their site, where I read:

PLEASANTON, Calif.—November 2, 2011—Retrospect, Inc., a privately‐held company recently founded by longtime Retrospect team members, announced today the immediate availability of its first independent product offering, Retrospect 9 for the Mac. With features like data deduplication, network backup of Mac, Windows, and Linux computers, and new support for cloud‐based storage, Retrospect 9 provides critical functionality for professionals and small businesses that need more than basic data protection.

That’s some of the best news I’ve heard this year!

Posted in Technology | Leave a comment

Hypocritical Methods

I haven’t posted for a while, but I’ve just got to post about this.

I commented on a question on stackoverflow.com (“How to find the source of a request“):

My question is once the method is called (usually from a partial view) is there a way inside the method to figure out whether the call came from Assembly A or Assembly B without passing anything to it?

Why do you want to do this? It sounds like a bad idea. What if you add another assembly? What if you move functionality from one assembly to another? Perhaps you should instead add a parameter to this method, and set it differently between the calls.

This prompted Dan Abramov to give the best answer I’ve ever seen to this class of question.

The question as asked was a specific case of a very general situation I see fairly frequently. You’ve got a method or other piece of code and you want it to behave differently in different contexts. You decide you need to understand the context of the call in order to decide how to behave. You ask about looking at the stack trace, or the calling web page or something like that.

The answer, as Dan puts it so eloquently, is to pass a parameter instead (in the case of wanting a UI control or other object to behave differently, the answer may be to set a property instead).

Posted in Uncategorized | Tagged | Leave a comment

Quick Hint for Troubleshooting XML Serialization Issues

 In the thread "pregenerated xmlserializers.dll is not beeing used", Nathan Anderson of Microsoft made the following suggestion:

to be really sure you can save any generated .cs files with this in your app.config:

<system.diagnostics>
      <switches>
         <add name="XmlSerialization.Compilation" value="1" />
      </switches>
</system.diagnostics>

This will drop any generated cs files in \Users\\AppData\Local\Temp (you can use process monitor to find out exactly).

Posted in Serialization | Leave a comment

La Película más Perfecta

Ayer, he vista al “Laberinto del Fauno”, una película de Guillermo del Toro. 

¡Actualmente, lo he vista dos veces! Esta película se habla enteramente en español.

Yo nunca veo las películas en español porque yo no hablo muy bien el español (como se puede ver). Parece que el arte es más fuerte de la lengua – yo entendió a eso de ¾ de las palabras.

¡Si ya no lo ha vista, véalo!

Posted in Personal | 3 Comments

Where to Find Forums on Microsoft Development

There are many good places to ask questions about Microsoft Development technologies. In fact, there are so many that it can become confusing. This article will be my start at clearing up the confusion. This is not the final form of the article: I hope to hear from you in the comments about how you think I should change it.

The Starting Point – MSDN

The central source of information on Microsoft technologies from a Developer’s point of view is the Microsoft Developer Network (MSDN). Some of you may think that MSDN is only the magazine or the subscription service, but that’s very far from the truth. The MSDN web site at http://msdn.microsoft.com/ is the place to start when you’re looking for information. It now includes more than just information from Microsoft, and links out to blogs and other sources of information outside of Microsoft.

Part of the MSDN site is the MSDN Forums. I recommend everyone to click that link, then click the “collapse all” button and scan the list of categories – there’s a huge number of individual forums there, having to do with .NET, Visual Studio, SQL Server and SharePoint development, Office development, and even native Windows development.

Other Microsoft Forums

Some groups at Microsoft have their own “center” sites, and some of these have forums of their own:

Area Site Forums
http://www.asp.net/ http://forums.asp.net/
http://silverlight.net/ http://silverlight.net/forums/
http://www.iis.net/ http://forums.iis.net/
http://windowsclient.net/ http://windowsclient.net/Forums/

 

Stack Overflow

Of course, there are many places outside of Microsoft where you can get help and ask questions about Development issues. One of those is http://stackoverflow.com/, which is actually not a discussion forum. StackOverflow is a question and answer (Q&A) site: you can do a quick search to see if someone has already answered your question, and if not, click “Ask a Question” to get started.  StackOverflow is community-managed: community members may comment on your question, asking for clarification of your question; you should clarify it by editing the original question, not by making a new post: a new post would be an Answer, not a question. If your question, subject line or tags are not clear, someone may edit your question to make it clearer.

For this and more about how StackOverflow differs from other discussion forums, please read the faq: http://stackoverflow.com/faq.

Posted in Development | Leave a comment

Microsoft says: ASMX Web Services are a “Legacy Technology”

Microsoft is finally acknowledging in public something that I’ve been failing to convince people about for a while now. From “XML Web Services Created Using ASP.NET and XML Web Service Clients” on MSDN:

This topic is specific to a legacy technology. XML Web services and XML Web service clients should now be created using Windows Communication Foundation (WCF).

You will find this paragraph on many pages under this topic, and I hope this paragraph will be placed on every page associated with ASMX in the near future.

Also, consider: if ASMX is "legacy", then what does that make WSE, which is based on ASMX? Still obsolete.

Posted in Web Services | 2 Comments

Where’s John Been?

Some may have noticed that lately I’ve been a little slower than normal in answering questions. I’ve even beed posting answers with a few typos in them.

It’s because I’ve had a problem with Retinal Detachment.

 

BTW, see the linked site for more than you could ever want to know about the subject.

I had been warned by my optometrist, Dr. Asha K. Sherring (below) in Autumn 2008, that I should expect to develop cataracts. I noticed on Saturday, May 30, that the center of my visual field on the right was being blocked by something “like a piece of fine cloth”, so I called Dr. Sherring. She was concerned about how quickly the problem had developed, and correctly so, since it was not a cataract.

 

She got me in for an appointment the same day I called her (Tuesday, June 2). The good news was that this was not a cataract. The bad news is that she discovered a retinal elevation.

She referred me to Dr. Shalesh Kaushal, M.D., Ph.D., of UMass Memorial, who saw me on Monday, June 8, and confirmed that I did, indeed, have a retinal tear. Fluid from the eye had entered behind the tear, and raised, or detached, the retina at that point.

He scheduled me for surgery on June 10. The great people at the UMass Day Surgery center at the Hahnemann Campus made this, my first surgery, the one to beat. Any other surgical operation will have to contend for a nicer staff, and a more professional operation.

The surgery went well (what I can remember of it), and I went home that afternoon (after they tricked me into a wheelchair. Next time I’ll know better: “sit here and we’ll put your shoes on”, indeed!).  The follow-up visit today, with Dr. Kaushal and his staff, also went well. I can already see a bit out of the right eye (I can tell you that there are fingers, just not how many). I should be back to work on Monday, and I’m looking forward to that.

Fortunately, my son, Brian, travelled from Phoenix to be with me until Sunday. He’s losing a week’s work to be with me (and, since he’s paid by the hour, that’s no small thing). I thank my father, John W. Saunders, Jr. for his help in paying for Brian’s plane fare. Thanks to my mother, Joyce Gittoes, for checking up on me several times a day. And thanks to all my family for their support and good wishes.

I’d especially like to thank my old friend Chris Johnson. When I called Chris to let him know about the surgery, I found that he was quite familiar with UMass, as he had just been there the day before! Seems I need to keep better track of my friends!

Posted in Personal | Leave a comment

How to Consume a Web Service

This question comes up more than you would imagine. Although it’s a simple question, it’s hard to find a simple answer. This post will attempt to be the simple answer. Any complications will be added as other posts, referencing this one.

Creating the Test Service

I’ll just start by creating a simple WCF service for us to consume later. This will also create the Visual Studio Solution we’re going to use. Start with File->New Project:

This brings up the New Project dialog. I’ll choose the “WCF Service Application” project template, just for simplicity. In general I would have chosen “WCF Service Library” from the WCF page.

 

This results in the following solution structure:

Actually, Visual Studio has provided all we need for this example. It created a Data Contract class for our use:

[DataContract]
public class CompositeType
{
    [DataMember]
    public bool BoolValue { get; set; }

    [DataMember]
    public string StringValue { get; set; }
}

It also created a service contract that our service will implement. This contract uses the Data Contract:

[ServiceContract]
public interface IService1
{
    [OperationContract]
    string GetData(int value);

    [OperationContract]
    CompositeType GetDataUsingDataContract(CompositeType composite);
}

It also created the service as a class that implements the service contract:

public class Service1 : IService1
{
    public string GetData(int value)
    {
        return string.Format("You entered: {0}", value);
    }

    public CompositeType GetDataUsingDataContract(CompositeType composite)
    {
        if (composite.BoolValue)
        {
            composite.StringValue += "Suffix";
        }
        return composite;
    }
}

It also created the Service1.svc file that will tell IIS (or the Visual Studio Development Server) which class to create to handle calls to the server:

<%@ ServiceHost Language="C#" Debug="true" Service="WcfService1.Service1" CodeBehind="Service1.svc.cs" %>

When a request for Service1.svc arrives at the URL the service is on, IIS will create an instance of the  System.ServiceModel.ServiceHost class to host instances of the the WcfService1.Service1 class. As requests for this service arrive, they will be dispatched to instances of the WcfService1.Service1 class.

The web.config has also been created with the default configuration necessary for this service.

Creating a Simple Client

There is no real difference between consuming a web service in a Console application as opposed to an ASP.NET application or a Windows Forms application, so I’ll just use a console application:

This produces:

We start by adding a Service Reference to the project. Right-click the ConsoleApplication1 project and choose “Add Service Reference”:

The value you place into the “Namespace” text box at the bottom is important, so I often fill it out first, so I don’t forget. Note here that I have changed the default of “ServiceReference1” to “Service1Reference”, to indicate that this will be a reference to “Service1”.

The “Address” text box at the top can be used to type the URL to the Service Description, or “WSDL” file. Since the service is in the same solution as the project we’re trying to add it to, we can take advantage of the “Discover” dropdown at the right. Clicking the arrow shows “Services in this solution”:

Clicking this will populate the “Address” box with the URL to our service, and will populate the “Services” list with the “Service1” service:

Now, a service may implement more than one service contract. You should click the “+” sign next to the service to expand the service down to the service contracts and their operations. Unfortunately, doing so now will illustrate that I’ve made a common error. After attempting to launch our service, the text below the service list will change to say “An error (Details) occurred while attempting to find services at http://localhost:50730/Service1.svc” Clicking the Details link will show:

Note that this is a bunch of HTML! In fact, there’s so much of it, that there is a scroll bar to the right. if you scroll to the very bottom, you’ll see the reason for this problem, and the solution to it:

Yes, I forgot to build the service! After successfully building the service and starting over, you’ll be able to expand the service all the way to the bottom, and see that both methods are visible:

Visual Studio will add several project references to your project, and will add the service reference:

Note that it also added an app.config. This will contain the configuration details necessary for the client to communicate with the service. These will be the defaults, and can be modified as required.

It’s usually at this point where someone new to web services stops to ask: “Now, what?”

What’s In a Service Reference?

A service reference is a convenient way for you to access a web service in your code. It takes all the complexities of web services and boils them down into a single name, in this case “Service1Reference”. But in order to see “what’s in a name”, all we have to do is right-click the service reference and choose “View in Object Browser”. The first thing it shows is actually interesting, so stop and look:

You’ll see that Visual Studio has created a new namespace under the namespace for this application. Any names brought over from the service cannot interfere with names in your application, because those names are all created in a separate namespace.

Expanding the namespace shows what’s inside:

Visual Studio has created a “CompositeType” class, since the service contract uses a class with that name. It has also created an IService1 interface to represent the service contract, as well as a Service1Client class that we’ll use shortly. If you click on IService1, you’ll notice that it has the expected GetData and GetDataUsingDataContract methods. If you expand Service1Client to see the base classes, you’ll see that it implements IService1, so that it contains implementations of the GetData and GetDataUsingDataContract methods.

This all makes it sound more difficult than it is. Let’s write some code instead! First, let’s get the data we’ll send to the service:

Console.Write("Enter BoolValue: ");
var line = Console.ReadLine();
if (line == null)
{
    return;
}

var boolValue = bool.Parse(line);

Console.Write("Enter StringValue: ");
line = Console.ReadLine();
if (line == null)
{
    return;
}

This is just simple-minded logic for reading in the two values we need to construct a CompositeType.

using (var svc = new Service1Client())
{
    var request = new CompositeType
                      {
                          BoolValue = boolValue,
                          StringValue = line
                      };
    var result = svc.GetDataUsingDataContract(request);

This is straightforward. Just create an instance of the Service1Client proxy class, create an instance of CompositeType , and call the method, passing the request and receiving the response. The response can be displayed in a simple manner:

Console.WriteLine("The result is:");
Console.WriteLine(
    "BoolValue={0}, StringValue={1}", 
    result.BoolValue,
    result.StringValue);
Console.Write("ENTER to continue:");
Console.ReadLine();

After that, we’re through. This can be tested by using CTRL+F5 to run the code without debugging. The result is:

But What About…

There’s one little problem in the code above. In every case, when your code creates an instance of a class that implements IDisposable, then your class should ensure that Dispose gets called on that instance. In most cases, the way to do that is shown above: create the instance within a using statement. Unfortunately, the designers of WCF made a mistake that causes the use of WCF proxy classes to be the one case where this doesn’t work. See Indisposable – WCF Gotcha 1 (7/3/2008) for the details, but we’re going to have to change our code a little. Instead of:

using (var svc = new Service1Client())

{

    // Do something with svc

}

we have to do this:

Service1Client svc = null;
bool success = false;
try
{
     svc = new Service1Client();
     
     var request = new CompositeType
     {
         BoolValue = boolValue,
         StringValue = line
     };
     var result = svc.GetDataUsingDataContract(request);

     Console.WriteLine("The result is:");
     Console.WriteLine(
         "BoolValue={0}, StringValue={1}",
         result.BoolValue,
         result.StringValue);
     Console.Write("ENTER to continue:");
     Console.ReadLine();

    svc.Close();
    success = true;
}
finally
{
    if (!success && svc != null)
    {
        svc.Abort();
    }
}

The highlighted code is the only difference. To make a long story short, if you don’t follow this pattern, and if an exception is thrown inside of your using block, then you may lose your exception. The exception will attempt to leave the using block, the block will call Dispose for you, and then Dispose may throw an exception of it’s own, losing you any information about what really went wrong in your using block. In the code above, if Close is never called, then Abort will be called, and it’s abort that will do the cleanup.

Don’t let this keep you from the using block in every other case. It is only because the WCF designers decided to have Dispose call Close, and since Close can throw its own exception, that this is an issue. As far as I know, there is nowhere else in .NET where calling Dispose can throw an exception.

Posted in Web Services | 16 Comments

Why I’m In a Bad Mood Today (or, “Cowardly Credit Card Companies”)

This is the first thing I’ve posted here of a personal nature. It’s a pity it has to be on a subject like this.

All of us, at least all of us in the United States, have been hearing about the Banking Crisis, and the Economic Crisis, and how it’s moving from Wall Street to Main Street. Well, I guess it’s hit my street, but not in a way I would have expected.

On April 7, 2009, I received a letter in the mail from Bank of America, about my credit card. It seems that they had decided to cut my credit limit in half, to $500. The letter said this was being done not because of any problems I’d had with Bank of America, but because of problems they saw in my credit report.

I thought, “Well, Ok, it’s their card, if they want to be cautious that’s ok. This will all resolve itself in a year or so.” I had been out of work for a few months, and although I had returned to work in February, I thought they might have seen a late payment or two. No big deal.

This was an issue only because I was using that card to rent a car: my car had finally died, and I got a great rate from Enterprise Rent-A-Car, and am being paid enough to afford this. Enterprise had wanted $500 to be free on the card, and with the new limit, I paid the $25 balance I had outstanding and called to ask Bank of America if they could put in a temporary $25 credit line increase until the payment posted in a day or so.

They told me that they could not, since they were cancelling the card outright. It seems that their computer had decided to cut the credit limit, but the very nice human I spoke to on the phone decided to just close the account instead.

Note that this had nothing to do with my experience with Bank of America. I had no late payments or any other problems with them. They closed the account because my ‘”Credit Profile” (not even the full credit report) showed late payments to other creditors. .

Yes, if you’re out of work for three months, a late payment or two is not unlikely. Apparently, it is now a reason to close an entirely different credit card.

I considered this to be an isolated case, so I called Enterprise and told them we’d be switching cards to American Express. I’ve had an American Express Card for ten years and counting, and have kept that card pristine – I hardly used it, so it had almost no chance of having any problems. So, I paid $600 to American Express to get enough room on the card for Enterprise to use.

The following day, American Express closed my account, for the same reason as Bank of America. Ten years and stop counting.

As I see it, the problem is that:

  1. Due to being out of work for a while, I missed a few payments on two credit cards. Those have since been brought up to date, now that I’m working again.
  2. In both cases, my balance on the card was less than half the credit limit. This means that, even if I decided to be a deadbeat and not pay what I owed on these cards, they wouldn’t lose much money (of course, I pay what I owe, so that’s not something they’ll ever learn).
  3. I’ve never had, or needed, a high credit limit on these cards. This means that losing me as a customer isn’t a great loss for these companies.

So the bottom line is that some large companies, who would ordinarily not act like cowards, have begun to do so, at least in the case of small customers like me: they seem to be deciding that there’s more downside risk of keeping me as a customer, than there is upside potential of me being a better customer – they felt they had a better chance of losing money by keeping me as a customer, than they had of gaining money by keeping me as a customer.

So, with the equation changed, I’m back to being in the cash-only economy, at least to an extent. I’ll be taking a cab to work tomorrow, at a cost of more than half a week’s car rental; and I’ll be looking to rent a room near work, probably for a cost of more than twice what it would cost to rent a car.

I’ll be working, though, and I’ll be alive to complain about this, and to anticipate the tax refund I’ll be receiving next year: I’m going to have so much deductable commuting expense.

BTW, I have more props for Enterprise: not only do they pick you up and drop you off, but when dropping me off today (after I returned the rental car), the manager there suggested that I rent from them over the weekend for a special rate. Since it will only be a weekend rental, they will only need to use a credit card with $300 on it. That, I still have, so I’ll probably be driving one of their cars this weekend. The contrast between Enterprise on the one hand, and Bank of America and American Express on the other hand, is revealing.


EDIT: I don’t feel so bad anymore – they’re doing it to everyone, even people with good credit. See http://moneycentral.msn.com/community/message/thread.asp?board=ConsumerActionForum&threadid=1080789.

Technorati Tags: ,

Posted in Personal | 4 Comments