Saturday, February 27, 2010

Thanks for participating in survey

@YaronNaveh

I just wanted to thank everyone who participated in my blog survey.
I promise to take your comments seriously.

If you have not voted yet - please take one minute and participate.

Go to survey

@YaronNaveh

What's next? get this blog rss updates or register for mail updates!

.Net / Wcf bug: Cannot convert type 'System.DateTime[]' to 'System.DateTime'

@YaronNaveh

A common bug in .Net 2.0 may cause the following exception when compiling a proxy:

Unable to generate a temporary class (result=1).

error CS0030: Cannot convert type 'System.DateTime[]' to 'System.DateTime'

error CS0030: Cannot convert type 'System.DateTime[]' to 'System.DateTime'

error CS0029: Cannot implicitly convert type 'System.DateTime' to 'System.DateTime[]'

Microsoft did not fix this bug for Wcf so it also gives a similar exception:

There was an error in serializing body of message myRequest: 'Unable to generate a temporary class (result=1).
error CS0030: Cannot convert type 'System.DateTime[]' to 'System.DateTime'
error CS0030: Cannot convert type 'System.DateTime[]' to 'System.DateTime'
error CS0029: Cannot implicitly convert type 'System.DateTime' to 'System.DateTime[]'
error CS0029: Cannot implicitly convert type 'System.DateTime' to 'System.DateTime[]'
'.  Please see InnerException for more details.

Is this error limited to DateTime?

Not at all. You may also get any of these:

Cannot convert type 'System.String[]' to 'System.String'

Cannot convert type 'System.Int32[]' to 'System.Int32'

Cannot convert type 'System.Decimal[]' to 'System.Decimal'

Or with your custom types.

What does this error mean?

For you – nothing. This is a .Net/Wcf bug.

When does this happen?

When the following conditions apply:

1. The wsdl (schema) declares a complex type C.
2. C contains a single element with maxOccures>1 (an array).
3. The wsdl declares an element e of type X with maxOccures>1.

Example:

  <xsd:complexType name="C">
    <xsd:sequence>
      <xsd:element maxOccurs="unbounded" minOccurs="0" name="someDate" type="xsd:date"/>    
    </xsd:sequence>
  </xsd:complexType>

...

<xsd:element maxOccurs="unbounded" minOccurs="0" name="e" type="tns:C"/> 

What is the .Net bug?

The proxy will generate something like this:

        [XmlArrayAttribute]
        [XmlArrayItemAttribute("someDate", typeof(DateTime))]
        public DateTime[][] C {
        ...
        }

This line declares an array of type DateTime[][], but also specifies that each item of the array is of type DateTime. Which is clearly an error since the array items are of type DateTime[] (this is a multidimentional array).

This is the reason why the proxy does not compile.

Workaround #1

Manually edit the proxy and change “typeof(DateTime)” to “typeof(DateTime[])”. This workaround is also described here.

Limitation: This change will be overridden every time you regenerate the proxy (update web/service reference).

Workaround #2

We mentioned that the bug only happens when the type C has one child element. Why not add it some friend so it would not be alone? This means we need to manually edit the wsdl. For example:

<xsd:complexType name="C">
    <xsd:sequence>
      <xsd:element maxOccurs="unbounded" minOccurs="0" name="someDate" type="xsd:date"/>          
<xsd:element minOccurs="0" name="dummyFriend" type="xsd:string"/>     
    </xsd:sequence>
  </xsd:complexType>

Now you may say this changes the schema and makes our proxy not valid. But note we have added an optional field only (minOccurs=0) so as long as we do not assign any value to it in our client this change is non-breaking.

Now let’s see how the proxy generated from the updated wsdl looks like:

public partial class C {
        [XmlElementAttribute("dateValue", DataType="date")]
        public DateTime[] dateValue {
            ...
        }

    [XmlElementAttribute]
        public string dummyFriend {
            ...
        }
    }

Now .Net does not generate the multidimensional array in one shot, but declares the mediating type C.  The proxy will in turn use this type as an array:

public C[] e {…}

which gives us the multidimensional effect.

This compiles immediately so we’re free to go.

@YaronNaveh

What's next? get this blog rss updates or register for mail updates!

Thursday, February 18, 2010

Vista security exploit: X.509 certificates

@YaronNaveh

When we install an X.509 certificate in a windows store, it is valid only if we can build from it some valid certificates chain. For example, if its issuer's certificate is in the trusted root store.

However it seems there is a meaningful change between XP and Vista. In XP, when we install a certificate in the "trusted people" store it is not valid unless such chain exist:



In Vista, once we put the certificate in the TrustedPeople store it is automatically valid even if no chain exist:



This change makes sense: If we trust someone then we do not need to trust its issuer also. However there is a backward compatibility risk: non valid certificates on XP become implicitly valid on Vista which is a potential security hole.

@YaronNaveh

What's next? get this blog rss updates or register for mail updates!

Saturday, February 13, 2010

Please participate - one minute survey

@YaronNaveh

I want to know my readers better. I would appreciate your participation in a short survey. The survey is about this blog and (optionally) your usage in web services. It should take 1-2 minutes to complete.

Go to survey

@YaronNaveh

What's next? get this blog rss updates or register for mail updates!

Friday, February 12, 2010

Quiz #1 - the answer

@YaronNaveh

Quiz #1 is over. Pablo and Dmitry were right, the XmlWriter uses the builder design pattern. A common algorithm traverses over the xml nodes, while a concrete builder (derived from XmlWriter) builds the resulting object (the stream) in a concrete way. This allows multiple builders (xml text writer, xml binary writer) to be used.

@YaronNaveh

What's next? get this blog rss updates or register for mail updates!

Thursday, February 11, 2010

The security token could not be authenticated or authorized

@YaronNaveh

When we use X.509 certificates with web services we might get this exception:


System.Exception: Soap error:Message:The security token could not be authenticated or authorized


This mostly means the certificate that was used by the server/client for encryption/signature is not valid on our machine. One solution would be to add it or its issuer cert to our trusted store.

An interesting case where we may get this error is after we have added the certificate to the store. This is usually a result of caching made by the windows store. Such caching is used in order to prevent DOS attacks. Wait a few minutes until changes take effect...

@YaronNaveh

What's next? get this blog rss updates or register for mail updates!

Wednesday, February 10, 2010

Visual Studio: Adding an existing folder to a project

@YaronNaveh

When I read this in the Nitriq blog I felt they took the words out of my mouth. I have always looked for a way to add an existing folder (with its files) to a VS project. The "manual" way is to create the root folder and then multiple select the files in the "add existing files..." context menu. But this is not practical in case there are multiple nested folders with many files in each.

The Nitriq blog gives a partial solution:


1. Copy the destination folder into the project folder (via windows explorer).
2. Click the "show all files" button.
3. Right click the folder --> "Include In Project".


However this has the disadvantage of not working in a "web site" project but only in a regular one. Amazingly enough I have found the trivial way to do the whole thing:


1. Drag the folder to the solution!




How stupid of me to not see it before... The annoying part is that VS should really have an "add existing folder..." context menu item.

@YaronNaveh

What's next? get this blog rss updates or register for mail updates!

Tuesday, February 9, 2010

An error was discovered processing the <Security> header

@YaronNaveh

This week's error can happen when Wse2 processes a secured message.

When Wse receives a message which has expired according to its producer policy we will see this exception:


Message Expired


Pretty much self explained. However in other cases we might see this error:


An error was discovered processing the header


This error means that the message timestamp is not valid according to the server policy (e.g. message was sent in the future).

The answer for these ills is to either sync the client & server clocks or to configure a larger skew.

@YaronNaveh

What's next? get this blog rss updates or register for mail updates!

Monday, February 8, 2010

Question #1 for the readers: Which design pattern is used here?

@YaronNaveh

There's an interesting design patterns riddle for you readers in the end of this post.

Jesse wrote an interesting post about xml and the .Net framework. He reminds us that xml is actually an abstraction and that Angle brackets are just one (inefficient) way of representing it.

For this reason this code:


...
xmlWriter.WriteStartElement("rawBytes");
xmlWriter.WriteBase64(arr);
xmlWriter.WriteEndElement();
...
xmlWriter.WriteStartElement("blog");
xmlWriter.WriteString("yaron's blog");
xmlWriter.WriteEndElement();
...


can actually generate both "regular" xml and optimized binary one, depending on the implementation of XmlWriter handed to it.

This is actually a great example of a design pattern implemented in the .Net framework BCL.

Can you guess which design pattern is it? Here's the DP list. Give your best shot at the comments bellow!

@YaronNaveh

What's next? get this blog rss updates or register for mail updates!

Friday, February 5, 2010

New layout for the blog

@YaronNaveh

After getting some feedback I have finally decided to change the blog layout.

Old layout:



New layout:



I saw that due to size changes some code snippets in several posts have been trnucated. If you happen to find any let me know.

@YaronNaveh

What's next? get this blog rss updates or register for mail updates!

Wednesday, February 3, 2010

Test-free features?

@YaronNaveh

At some mature stage of a system development we replace all of these messages:


throw new Exception("should never see this")


with something more customer oriented:


throw new Exception("An error has occur while loading the document. Please verify it is in the correct format. ")


Or even better - doing globalization:


throw new Exception(Resources.UnknownLoginError)


These changes are not expected to cause any non-UI regressions, right?

Consider the case where we originally had this


String.Format("Cannot download url");


And now the documentation guys kindly asked to change to this:


String.Format("Cannot download url {0}", url);


or this:


String.Format("Cannot download url {0} using credentials {1}:{2}", url, user, pass);


A mismatch between the number of tokens in the string to the actual provided parameters may result in this error:


Index (zero based) must be greater than or equal to zero and less than the size of the argument list.


Conclusion: Proofing/Localizing always require running all your tests and doing a regression cycle.

@YaronNaveh

What's next? get this blog rss updates or register for mail updates!