我已使用this article中的示例将客户端证书身份验证添加到我的WCF数据服务。我不得不稍微更改示例,因为我正在使用WCF DataService 5.6,其中SendingRequest
事件已被弃用并被SendingRequest2
替换。
基本上这意味着更改以下事件处理程序:
private void OnSendingRequest_AddCertificate(object sender, SendingRequestEventArgs args)
{
if (null != ClientCertificate)
{
((HttpWebRequest)args.Request).ClientCertificates.Add(ClientCertificate);
}
}
要:
private void OnSendingRequest_AddCertificate(object sender, SendingRequest2EventArgs args)
{
if (null != ClientCertificate)
{
((HttpWebRequestMessage)args.RequestMessage).HttpWebRequest.ClientCertificates.Add(ClientCertificate);
}
}
这似乎有效。但是现在我在某些操作上得到以下InvalidCastException
:
System.InvalidCastException:无法转换类型的对象 键入'System.Data.Services.Client.InternalODataRequestMessage' 'System.Data.Services.Client.HttpWebRequestMessage'。
我无法100%准确地确定这些行为是什么,但似乎在SaveChanges方法上始终如一(请参阅下面的stacktrace :)
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)
我通过反复试验从SendingRequest
到SendingRequest2
进行了修改,所以我想知道我是否忽略了那里的某些内容。或者这是完全不相关的,我应该在处理程序中的if语句中添加&& args.RequestMessage is HttpWebRequestMessage
吗?
答案 0 :(得分:2)
似乎您正在发送批量请求。批处理请求包含几个内部请求,即InternalODataRequestMessage。 SendingRequest2会将OnSendingRequest操作应用于$ batch请求及其内部请求。
您可以尝试以下代码
private void OnSendingRequest_AddCertificate(object sender, SendingRequest2EventArgs args)
{
if (null != ClientCertificate && !args.IsBatchPart)
{
((HttpWebRequestMessage)args.RequestMessage).HttpWebRequest.ClientCertificates.Add(ClientCertificate);
}
}
如果在批处理中为请求触发此事件,则args.IsBatchPart返回true,否则返回false。
答案 1 :(得分:0)
执行批处理操作时似乎出现问题。
我试图挖掘InternalODataRequestMessage
以查看是否可以使用反射和DataServices源以某种方式添加客户端证书。我发现InternalODataRequestMessage
的实例有一个requestMessage
类型的私有成员ODataBatchOperationRequestMessage
。通过查看source code我无法添加证书。
我注意到的是,我实际上仍然可以像以前一样使用已弃用的SendingRequest
事件。这就是我做的,一切似乎都很好。
我觉得应该有一种方法来使用客户端证书而不使用弃用的方法。因此,如果某人有答案显示,我会接受。