I've recently had quite a problem with a certain web method I'm using:
void CheckGfiHelpdesks(string ticket, GfiCheck[] newHelpdeskChecks, GfiCheck[] otherChecks)
I've been calling that method with this code:
List<GfiCheck> newFailedChecks = new List<GfiCheck>();
List<GfiCheck> otherFailedChecks = new List<GfiCheck>();
//do some work, create new GfiCheck items, fill the lists
Webclient.CheckGfiHelpdesks(Ticket, newFailedChecks.ToArray(), otherFailedChecks.ToArray());
newFailedChecks and otherFailedChecks are List. This has been working fine when the method was running on IIS as a SOAP service.
However, after I copied the exact same method into a WCF service, the call produced a "400 bad request" exception.
Eventually I figured out that .ToArray() was indeed the problem. This:
Webclient.CheckGfiHelpdesks(Ticket, newFailedChecks.ToArray<GfiCheck>(), otherFailedChecks.ToArray<GfiCheck>());
i.e. using the System.Linq.Enumerable.ToArray<T>()
instead of System.Collections.Generic.List<T>.ToArray()
finally solved the problem and the exception went away.
What is the explanation for this difference? An Array is an Array, but apparently not?
The exact Exception is:
System.ServiceModel.ProtocolException
The remote server returned an unexpected response: (400) Bad Request.
StackTrace:
Server stack trace:
at System.ServiceModel.Channels.HttpChannelUtilities.ValidateRequestReplyResponse(HttpWebRequest request, HttpWebResponse response, HttpChannelFactory factory, WebException responseException, ChannelBinding channelBinding)
at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
>
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at MonitoringService.BL.CentronService.ICentronService.CheckGfiHelpdesks(String ticket, GfiCheck[] newHelpdeskChecks, GfiCheck[] otherChecks)
at MonitoringService.BL.CentronService.CentronServiceClient.CheckGfiHelpdesks(String ticket, GfiCheck[] newHelpdeskChecks, GfiCheck[] otherChecks) in C:\Users\sohrm\documents\visual studio 2010\Projects\MonitoringService\MonitoringService.BL\Service References\CentronService\Reference.cs:Zeile 5368.
at MonitoringService.BL.ConnectorBL.CheckHelpdesks(List`1 clients) in C:\Users\sohrm\documents\visual studio 2010\Projects\MonitoringService\MonitoringService.BL\ConnectorBL.cs:Zeile 120.
at MonitoringService.WinForm.MainForm.LoadChecks() in C:\Users\sohrm\documents\visual studio 2010\Projects\MonitoringService\MonitoringService.Client\MainForm.cs:Zeile 124.
at MonitoringService.WinForm.MainForm.btnLoad_Click(Object sender, EventArgs e) in C:\Users\sohrm\documents\visual studio 2010\Projects\MonitoringService\MonitoringService.Client\MainForm.cs:Zeile 114.
at System.Windows.Forms.Control.OnClick(EventArgs e)
at DevExpress.XtraEditors.BaseButton.OnClick(EventArgs e)
at DevExpress.XtraEditors.BaseButton.OnMouseUp(MouseEventArgs e)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at DevExpress.Utils.Controls.ControlBase.WndProc(Message& m)
at DevExpress.XtraEditors.BaseControl.WndProc(Message& msg)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.Run(Form mainForm)
at MonitoringService.WinForm.Program.Main() in C:\Users\sohrm\documents\visual studio 2010\Projects\MonitoringService\MonitoringService.Client\Program.cs:Zeile 22.
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()