How to solve this InvalidCastException while applying ClientCertificate to WCF DataService Client?

一个人想着一个人 提交于 2019-12-11 12:11:12

问题


I have used the examples in this article to add client certificate authentication to my WCF Data Service. I had to change the example slightly because I am using WCF DataService 5.6 in which the SendingRequest event has been deprecated and replaced by SendingRequest2.

Basically this meant changing the following event handler:

private void OnSendingRequest_AddCertificate(object sender, SendingRequestEventArgs args)
{
    if (null != ClientCertificate)
    {
        ((HttpWebRequest)args.Request).ClientCertificates.Add(ClientCertificate);
    }
}

To:

private void OnSendingRequest_AddCertificate(object sender, SendingRequest2EventArgs args)
{
    if (null != ClientCertificate)
    {
        ((HttpWebRequestMessage)args.RequestMessage).HttpWebRequest.ClientCertificates.Add(ClientCertificate);
    }
}

This seems to work. However now I get the following InvalidCastException on some actions:

System.InvalidCastException: Unable to cast object of type 'System.Data.Services.Client.InternalODataRequestMessage' to type 'System.Data.Services.Client.HttpWebRequestMessage'.

I haven't been able to identify with 100% accuracy which actions these are, but it seems consistently on the SaveChanges method (see stacktrace below:)

at MyNamespace.MyContainer.OnSendingRequest_AddCertificate(Object sender, SendingRequest2EventArgs args)
at System.Data.Services.Client.ODataRequestMessageWrapper.FireSendingRequest2(Descriptor descriptor)
at System.Data.Services.Client.BatchSaveResult.GenerateBatchRequest()
at System.Data.Services.Client.BatchSaveResult.BatchRequest()
at System.Data.Services.Client.DataServiceContext.SaveChanges(SaveChangesOptions options)

I came to the modification from SendingRequest to SendingRequest2 by trial and error, so I wonder if I overlooked something there. Or is this completely unrelated and should I just add an && args.RequestMessage is HttpWebRequestMessage to the if statement in the handler?


回答1:


Seems that you are sending a batch request. A batch request contains several internal requests which are InternalODataRequestMessage. SendingRequest2 will apply the OnSendingRequest action into both the $batch request and it's internal requests.

You can try following code

private void OnSendingRequest_AddCertificate(object sender, SendingRequest2EventArgs args)
{
    if (null != ClientCertificate && !args.IsBatchPart)
    {
        ((HttpWebRequestMessage)args.RequestMessage).HttpWebRequest.ClientCertificates.Add(ClientCertificate);
    }
}

args.IsBatchPart returns true if this event is fired for request within a batch, otherwise returns false.




回答2:


It seems the problem occurs when I perform a batch operation.

I tried to dig through the InternalODataRequestMessage to see if I could add client certificates to that somehow using reflection and the DataServices source. I found the instance of InternalODataRequestMessage has a private member requestMessage of type ODataBatchOperationRequestMessage. By looking at the source code I couldn't any way to add a certificate.

What I did notice is that I can actually still use the deprecated SendingRequest event just like before. So that's what I did and everything seems fine.

I feel like there should be a way to use a client certificate without using deprecated methods. So if someone has an answer that shows that, I'll accept that.



来源:https://stackoverflow.com/questions/21237052/how-to-solve-this-invalidcastexception-while-applying-clientcertificate-to-wcf-d

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!