I have an index that looks like this
public class FeedAnnouncementByOneLabel : Raven.Client.Indexes.AbstractIndexCreationTask<FeedPost, FeedAnnouncementByOneLabel.Result>
{
public class Result
{
public long SequentialId { get; set; }
public string AnnouncementId { get; set; }
public string Label1 { get; set; }
public string FeedOwner { get; set; }
public DateTimeOffset CreationDate { get; set; }
}
public FeedAnnouncementByOneLabel()
{
Map = announcements => from doc in announcements
from docLabelsItem1 in ((IEnumerable<Label>)doc.Labels).DefaultIfEmpty()
select new Result
{
SequentialId = doc.SequentialId,
AnnouncementId = doc.AnnouncementId,
CreationDate = doc.CreationDate,
FeedOwner = doc.FeedOwner,
Label1 = docLabelsItem1.Text
};
}
}
And I query it like this (simplified version, which STILL fails):
from c in _session.Query<FeedAnnouncementByOneLabel.Result, FeedAnnouncementByOneLabel>()
select c;
I get an exception EVERY TIME I query it. The really odd thing is that this used to work. Im not sure if its broken since I updated Raven to the latest version - or because of something else I changed.
Im pretty sure the only thing thats changes is that I moved "FeedPost" into its own DLL (with various DataContract attributes on it).
Any takers??
Thanks
<Exception xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<ExceptionType>System.InvalidCastException</ExceptionType>
<Message>
Unable to cast object of type 'FeedPost' to type 'Result'.
</Message>
<StackTrace>
at Raven.Client.Document.InMemoryDocumentSessionOperations.ConvertToEntity[T](String id, RavenJObject documentFound, RavenJObject metadata) in c:\Builds\RavenDB-Stable\Raven.Client.Lightweight\Document\InMemoryDocumentSessionOperations.cs:line 416
at Raven.Client.Document.InMemoryDocumentSessionOperations.TrackEntity[T](String key, RavenJObject document, RavenJObject metadata) in c:\Builds\RavenDB-Stable\Raven.Client.Lightweight\Document\InMemoryDocumentSessionOperations.cs:line 340
at Raven.Client.Document.SessionOperations.QueryOperation.Deserialize[T](RavenJObject result) in c:\Builds\RavenDB-Stable\Raven.Client.Lightweight\Document\SessionOperations\QueryOperation.cs:line 130
at System.Linq.Enumerable.WhereSelectListIterator`2.MoveNext()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at Raven.Client.Document.SessionOperations.QueryOperation.Complete[T]() in c:\Builds\RavenDB-Stable\Raven.Client.Lightweight\Document\SessionOperations\QueryOperation.cs:line 114
at Raven.Client.Document.AbstractDocumentQuery`2.GetEnumerator() in c:\Builds\RavenDB-Stable\Raven.Client.Lightweight\Document\AbstractDocumentQuery.cs:line 603
at Raven.Client.Linq.RavenQueryInspector`1.GetEnumerator() in c:\Builds\RavenDB-Stable\Raven.Client.Lightweight\Linq\RavenQueryInspector.cs:line 98
at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
at FeedPostsController.Get(String labels, Int32 sincePostId) in FeedPostsController.cs:line 211
at lambda_method(Closure , Object , Object[] )
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.Execute(Object instance, Object[] arguments)
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.Execute(HttpControllerContext controllerContext, IDictionary`2 arguments)
at System.Web.Http.Controllers.ApiControllerActionInvoker.<>c__DisplayClass2.<InvokeActionAsync>b__0()
at System.Threading.Tasks.TaskHelpers.RunSynchronously[TResult](Func`1 func, CancellationToken cancellationToken)
</StackTrace>
</Exception>
[UPDATE]
Ok - I moved the FeedPost definition back into the same DLL that had the indices... still fail.
Just tried this (https://gist.github.com/2780374) and I m not getting that error (ie the query runs without errors) tho no results
It seems like you are trying to get all the feed annoucement by labels then maybe this could work?
I removed the annoucementId and the other id because it would get in the way of the aggregation (by label) but maybe I got your domain wrong.
public class FeedAnnouncementByOneLabel : AbstractIndexCreationTask<FeedPost, FeedAnnouncementByOneLabel.Result>
{
public class Result
{
public string Label1 { get; set; }
public string FeedOwner { get; set; }
public DateTimeOffset CreationDate { get; set; }
}
public FeedAnnouncementByOneLabel()
{
Map = announcements => from doc in announcements
from label in doc.Labels.DefaultIfEmpty()
select new
{
CreationDate = (DateTimeOffset)doc.CreationDate,
FeedOwner = doc.FeedOwner,
Label1 = label.Text
};
Reduce = results => from result in results
group result by result.Label1
into r
select new
{
CreationDate = (DateTimeOffset)r.Max(x => x.CreationDate),
FeedOwner = r.Select(x=> x.FeedOwner).First(),
Label1 = r.Key,
};
}
}
Related
Im trying to create dotnet 7 webapi endpoint with streaming file upload but I always get an error that I cant overcome. I'm Trying to use a library called UploadStream, Github page: https://github.com/ma1f/uploadstream
Error:
System.IO.IOException: Unexpected end of Stream, the content may have already been read by another component.
at Microsoft.AspNetCore.WebUtilities.MultipartReaderStream.ReadAsync(Memory1 buffer, CancellationToken cancellationToken) at Microsoft.AspNetCore.WebUtilities.StreamHelperExtensions.DrainAsync(Stream stream, ArrayPool1 bytePool, Nullable1 limit, CancellationToken cancellationToken) at Microsoft.AspNetCore.WebUtilities.MultipartReader.ReadNextSectionAsync(CancellationToken cancellationToken) at Microsoft.AspNetCore.Http.Features.FormFeature.InnerReadFormAsync(CancellationToken cancellationToken) at Microsoft.AspNetCore.Mvc.ModelBinding.Binders.FormFileModelBinder.GetFormFilesAsync(String modelName, ModelBindingContext bindingContext, ICollection1 postedFiles)
at Microsoft.AspNetCore.Mvc.ModelBinding.Binders.FormFileModelBinder.BindModelAsync(ModelBindingContext bindingContext)
at Microsoft.AspNetCore.Mvc.ModelBinding.Binders.ComplexObjectModelBinder.BindPropertyAsync(ModelBindingContext bindingContext, ModelMetadata property, IModelBinder propertyBinder, String fieldName, String modelName)
at Microsoft.AspNetCore.Mvc.ModelBinding.Binders.ComplexObjectModelBinder.BindPropertiesAsync(ModelBindingContext bindingContext, Int32 propertyData, IReadOnlyList`1 boundProperties)
at Microsoft.AspNetCore.Mvc.ModelBinding.Binders.ComplexObjectModelBinder.BindModelCoreAsync(ModelBindingContext bindingContext, Int32 propertyData)
It happens on line 31 in ControllerExtensions.cs with the method controller.TryUpdateModelAsync<T>(model, prefix: "", valueProvider : form);
Controller Code:
[HttpPost]
[DisableFormValueModelBinding]
public async Task<IActionResult> UploadPresentationV1()
{
byte[] buffer = new byte[1024 * 100];
List<IFormFile> files = new List<IFormFile>();
var model = await this.StreamFiles<UploadPresentationCommand>(async x =>
{
using (var stream = x.OpenReadStream())
while (await stream.ReadAsync(buffer, 0, buffer.Length) > 0) ;
files.Add(x);
});
return Ok("");
}
Model UploadPresentationCommand:
public class UploadPresentationCommand
{
[Required]
public string Name { get; set; }
[Required]
public string PresentationContent { get; set; }
public List<IFormFile> Images { get; set; }
}
I tried to use a disable form model binding attribute what I found in the microsoft documentation:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class DisableFormValueModelBindingAttribute : Attribute, IResourceFilter
{
public void OnResourceExecuting(ResourceExecutingContext context)
{
var factories = context.ValueProviderFactories;
factories.RemoveType<FormValueProviderFactory>();
factories.RemoveType<FormFileValueProviderFactory>();
factories.RemoveType<JQueryFormValueProviderFactory>();
}
public void OnResourceExecuted(ResourceExecutedContext context)
{
}
}
What I found out, somehow even with this attribute the List<IFormFile> Images gets binded from the request to the model (For example if I specify it in the endpoint parameter like that [FromForm] UploadPresentationCommand uploadPresentationCommand, The files are binded, but the other two properties are not, so I assume that this is the root of the problem and I dont know how to disable this type of binding entirely, also im not sure if it could help.
I post some data to the remote server. When the data run succeeded, it returns:
{"access_token":"sd234sd234sdf324","expires_in":7200}
When it failed, it returns:
{"errcode":40013,"errmsg":"invalid appid"}
Here is my code:
HttpClient HC = new HttpClient();
HttpResponseMessage HRM = await HC.PostAsync("https://www.microsoft/callback/aaa/), null);
string Content = await HRM.Content.ReadAsStringAsync();
Models.SuccessModel SM=(Models.SuccessModel)JsonSerializer.Deserialize(Content, typeof(Models.SuccessModel));
The last part for converting JSON to the class, I used the SuccessModel yet but if returns the failed JSON it will throw an error which Type is wrong.
I know what the error is. But how can I deal with this?
I want to get whether it is succeeded or failed and get the value of it.
Thank you.
Make another model for error as follows:
public class ErrorModel
{
public string errcode {get;set;}
public string errmsg {get;set;}
}
Then do as follows:
string response = await HRM.Content.ReadAsStringAsync();
if (response.Contains("access_token", StringComparison.OrdinalIgnoreCase))
{
Models.SuccessModel successModel =(Models.SuccessModel)JsonSerializer.Deserialize(response, typeof(Models.SuccessModel));
} else
{
ErrorModel erroModel = (Models.ErrorModel)JsonSerializer.Deserialize(response,typeof(Models.ErrorModel));
}
However, you can work this way
public class Model
{
public string access_token { get; set;}
public long expires_in { get; set;}
public int errcode { get; set;}
public string errmsg { get; set;}
}
So just get the response and check errcode when use it, no need to check when Deserialize
I'm trying to build a map/reduce that counts the number of documents in a given hour.
The code I'm trying is this
public class Syslog_DocumentCountByHour : AbstractMultiMapIndexCreationTask<Syslog_DocumentCountByHour.ReduceResult> {
public class ReduceResult {
public string Source { get; set; }
public DateTime Day { get; set; }
public DateTime Hour { get; set; }
public int Count { get; set; }
}
public Syslog_DocumentCountByHour() {
AddMap<SysLog>(docs => from doc in docs
select new {
Source = "CountByHour",
Day = doc.UtcDateTime.Day.ToString(),
Hour = doc.UtcDateTime.Hour.ToString(),
Count = 1
});
Reduce = results => from result in results
group result by new { result.Hour }
into g
select new {g.Key.Hour, Count = g.Sum(x => x.Count) };
}
}
But Raven is throwing an error
System.InvalidOperationException: Could not understand query
"$type": "System.InvalidOperationException, mscorlib",
"ClassName": "System.InvalidOperationException",
"Message": "Url: \"/indexes/Syslog/DocumentCountByHour\"\r\n\r\nSystem.InvalidOperationException: Could not understand query: \r\ndocs.SysLogs.Select(doc => new {\r\n Source = \"CountByHour\",\r\n Day = doc.UTC Date / Time.Day.ToString(),\r\n Hour = doc.UTC Date / Time.Hour.ToString(),\r\n Count = 1\r\n}) ---> System.InvalidOperationException: Could not understand query: \r\n[DomRegion FileName=, Begin=(3, 18), End=(-1, -1)]: Error - Unexpected symbol `Date'\r\n[DomRegion FileName=, Begin=(4, 19), End=(-1, -1)]: Error - Unexpected symbol `Date'\r\n at Raven.Database.Linq.QueryParsingUtils.GetVariableDeclarationForLinqMethods(String query, Boolean requiresSelectNewAnonymousType) in c:\\Builds\\RavenDB-Stable\\Raven.Database\\Linq\\QueryParsingUtils.cs:line 152\r\n --- End of inner exception stack trace ---\r\n at Raven.Database.Linq.QueryParsingUtils.GetVariableDeclarationForLinqMethods(String query, Boolean requiresSelectNewAnonymousType) in c:\\Builds\\RavenDB-Stable\\Raven.Database\\Linq\\QueryParsingUtils.cs:line 196\r\n at Raven.Database.Linq.DynamicViewCompiler.TransformMapDefinitionFromLinqMethodSyntax(String query, String& entityName) in c:\\Builds\\RavenDB-Stable\\Raven.Database\\Linq\\DynamicViewCompiler.cs:line 404\r\n at Raven.Database.Linq.DynamicViewCompiler.HandleMapFunction(ConstructorDeclaration ctor, String map) in c:\\Builds\\RavenDB-Stable\\Raven.Database\\Linq\\DynamicViewCompiler.cs:line 169\r\n at Raven.Database.Linq.DynamicViewCompiler.TransformQueryToClass() in c:\\Builds\\RavenDB-Stable\\Raven.Database\\Linq\\DynamicViewCompiler.cs:line 132\r\n at Raven.Database.Linq.DynamicViewCompiler.GenerateInstance() in c:\\Builds\\RavenDB-Stable\\Raven.Database\\Linq\\DynamicViewCompiler.cs:line 556\r\n at Raven.Database.Storage.IndexDefinitionStorage.AddAndCompileIndex(IndexDefinition indexDefinition) in c:\\Builds\\RavenDB-Stable\\Raven.Database\\Storage\\IndexDefinitionStorage.cs:line 153\r\n at Raven.Database.Storage.IndexDefinitionStorage.CreateAndPersistIndex(IndexDefinition indexDefinition) in c:\\Builds\\RavenDB-Stable\\Raven.Database\\Storage\\IndexDefinitionStorage.cs:line 138\r\n at Raven.Database.DocumentDatabase.PutIndex(String name, IndexDefinition definition) in c:\\Builds\\RavenDB-Stable\\Raven.Database\\DocumentDatabase.cs:line 1070\r\n at Raven.Database.Server.Responders.Index.Put(IHttpContext context, String index) in c:\\Builds\\RavenDB-Stable\\Raven.Database\\Server\\Responders\\Index.cs:line 83\r\n at Raven.Database.Server.HttpServer.DispatchRequest(IHttpContext ctx) in c:\\Builds\\RavenDB-Stable\\Raven.Database\\Server\\HttpServer.cs:line 856\r\n at Raven.Database.Server.HttpServer.HandleActualRequest(IHttpContext ctx) in c:\\Builds\\RavenDB-Stable\\Raven.Database\\Server\\HttpServer.cs:line 601\r\n",
Any help would be greatly appreciated.
I can confirm that the failure here was the PropertyName set using the JsonPropertyAttribute
Changing
[JsonProperty(PropertyName = "UTC Date/Time")]
public DateTime UtcDateTime { get; set; }
to
public DateTime UtcDateTime { get; set; }
Has stopped the error from being thrown. Evidently RavenDB doesn't like spaces.
I have written a WCF service using LINQ to SQL (using the following article at codeporject). I am facing the invalid cast exception when i invoke the .ToList() method of an object after i have already made a wcf function call of the same service against the same database.
The exception is:
System.InvalidCastException was unhandled by user code
Message=Specified cast is not valid.
Source=System.Data
StackTrace:
at System.Data.SqlClient.SqlBuffer.get_Int64()
at System.Data.SqlClient.SqlDataReader.GetInt64(Int32 i)
at Read_Command(ObjectMaterializer`1 )
at System.Data.Linq.SqlClient.ObjectReaderCompiler.ObjectReader`2.MoveNext()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at SystemsManager.ACS.GetCommands(Int64 agentId) in E:\Projects\SystemsManager\AgentControlService\ACS.svc.cs:line 167
at SyncInvokeGetCommands(Object , Object[] , Object[] )
at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
InnerException:
The specific line i am having issue is with the ToList() method
public List<Command> GetCommands(long agentId)
{
var cmd = from command in db.Command where (command.AgentId == agentId) select command;
return cmd.ToList();
}
When debugging, the return statment throws exception. When view the value of cmd.ToList() in Quick Watch of VS 2010, the exception is shown.
Now the strangest thing is: Pressing "Re-Evaluate" button a couple of times changes the exception to required object list in Quick watch. Infact i have to press "Re-evaluate" at least three times.
I have generated client using svcutil tool after my most recent changes to the service/database.
I am calling the method using the following code from a windows service:
var agent = client.GetAgentByIpAddress(myIPAddress);
client.Close();
if (agent != null)
{
if (agent.AgentId != -1)
{
client = new ACSClient();
var command = client.GetCommands(agent.AgentId);
.....
Here is the model of Command in the interface of the wcf service.
[DataContract]
[Table(Name = "Command")]
public class Command
{
[DataMember, Column(IsPrimaryKey = true, Name = "Command_Id", AutoSync = AutoSync.OnInsert, IsDbGenerated = true, DbType = "Bigint NOT null identity")]
public long CommandId { get; set; }
[DataMember, Column(Name = "Agent_Id")]
public long AgentId { get; set; }
[DataMember, Column(Name = "Name")]
public string CommandName { get; set; }
[DataMember, Column(Name = "Paramters")]
public string CommandParamters { get; set; }
[DataMember, Column(Name = "Is_Fetched")]
public bool IsFectched { get; set; }
[DataMember, Column(Name = "Status")]
public long Status { get; set; }
[DataMember, Column(Name = "Response")]
public string Response { get; set; }
[DataMember, Column(Name = "Created")]
public DateTime Created { get; set; }
[DataMember, Column(Name = "Last_Modified")]
public DateTime LastModified { get; set; }
[DataMember, Column(Name = "Is_Enabled")]
public bool IsEnabled { get; set; }
}
Important thing is: My database file is located in AppData folder of the WCF service. I am using only one instance of db object (refer to 1st code block above) throughout my wcf service and i am wondering if this could be cause of the problem???
Also, i have called a couple of similar method of this very same wcf service from a desktop application but i have not faced any such issue.
Please help. if more details are needed, please state so.. The only thing that can come to mind is that perhaps the database is in use and when another connection is made to the database by the service, it fails. and retrying it a couple of times using the Quick Watch > Re-evaluate button displays the required values in the watch window without throwing any error.
Kindly help on this one. Quick responses are highly appreciated.
Thanks.
Steve
Never mind guys. I solved it.
For anyone else who is getting invalid cast exception, here is the solution.
The error only occurs when actual class model is different that the database.
If you have created the class model by hand coding it, the you must match each column name of the table to your corresponding class. LINQ to sql encounters error when it cannot convert a database type to .Net type and throws invalid cast exception.
So in most cases, either fixing the error manually in the model class or regenerating the class will solve the problem.
I have a simple WCF service that returns the time from the server. I've confirmed that data is being sent by checking with Fiddler. Here's the result object xml that my service sends.
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<GetTimeResponse xmlns="http://tempuri.org/">
<GetTimeResult xmlns:a="http://schemas.datacontract.org/2004/07/TestService.DataObjects" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<a:theTime>2010-03-26T09:14:38.066372-06:00</a:theTime>
</GetTimeResult>
</GetTimeResponse>
</s:Body>
</s:Envelope>
So, as far as I can tell, there's nothing wrong on the server end. It's receiving requests and returning results.
But on my silverlight client, all the members of the returned object are either null, blank or a default vaule. As you can see the server returns the current date and time. But in silverlight, theTime property on my object is set to 1/1/0001 12:00 AM (default value).
Sooo methinks that the DataContracts do not match up between the server and the silverlight client. Here's the DataContract for the server
[DataContract]
public class Time
{
[DataMember]
public DateTime theTime { get; set; }
}
Incredibly simple. And here's the datacontract on my silverlight client.
[DataContract]
public class Time
{
[DataMember]
public DateTime theTime { get; set; }
}
Literally the only difference is the namespaces within the application. But still the values being returned are null, empty or a .NET default.
Thanks for you help!
UPDATE
Here is the ClientBase that all my services run through. I read an excellent article here to construct it.
public class ClientBase<T> where T :class
{
private T Channel { get; set; }
private Type ContractType { get; set; }
private ClientBase()
{
ContractType = typeof( T );
}
public ClientBase(string endPointConfiguration) :this()
{
Channel = new ChannelFactory<T>( endPointConfiguration ).CreateChannel();
}
public ClientBase( EndpointAddress address, Binding binding ):this()
{
Channel = new ChannelFactory<T>( binding, address ).CreateChannel();
}
public void Begin(string methodName, object state, params object[] parameterArray)
{
Begin( methodName, null, state, parameterArray );
}
public void Begin(string methodName, EventHandler<ClientEventArgs> callBack, object state, params object[] parameterArray)
{
if(parameterArray != null)
{
Array.Resize(ref parameterArray, parameterArray.Length + 2);
}
else
{
parameterArray = new object[2];
}
parameterArray[ parameterArray.Length - 1 ] = new ObjectClientState {CallBack = callBack, MethodName = methodName, UserState = state};
parameterArray[ parameterArray.Length - 2 ] = new AsyncCallback( OnCallBack );
ContractType.InvokeMember( "Begin" + methodName,
System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.InvokeMethod |
System.Reflection.BindingFlags.Public, null, Channel, parameterArray );
}
private void OnCallBack(IAsyncResult result)
{
ObjectClientState state = result.AsyncState as ObjectClientState;
if(state == null)
return;
Object obj = ContractType.InvokeMember( "End" + state.MethodName,
System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.InvokeMethod |
System.Reflection.BindingFlags.Public, null, Channel, new object[] {result} );
if(state.CallBack != null)
{
state.CallBack( this, new ClientEventArgs {Object = obj, UserState = state.UserState} );
}
}
public class ClientEventArgs : EventArgs
{
public object Object { get; set; }
public object UserState { get; set; }
public T LoadResult<T>()
{
if( Object is T )
return ( T ) Object;
return default( T );
}
}
private class ObjectClientState
{
public EventHandler<ClientEventArgs> CallBack { get; set; }
public string MethodName { get; set; }
public object UserState { get; set; }
}
}
Here is my interface
[ServiceContract]
public interface ITestService
{
[OperationContract( AsyncPattern = true )]
IAsyncResult BeginGetTime( AsyncCallback callback, object state );
Time EndGetTime( IAsyncResult result );
}
Now I have my service class that makes calls through my BaseService class using this interface.
public class TestSiteService : ClientBase<ITestService>
{
public TestSiteService (string endPointConfiguration):base(endPointConfiguration) { }
public TestSiteService ( EndpointAddress address, Binding binding ) : base( address, binding ) { }
public void GetTime( EventHandler<ClientEventArgs> callBack )
{
Begin( "GetTime", callBack, null, null );
}
}
Finally here is the code that actually calls everything and does the work.
TestSiteService client = new TestSiteService ( new EndpointAddress( "http://localhost:3483/wcf/Service.svc" ), new BasicHttpBinding() );
client.GetTime( delegate( object res, ClientBase<ITestService>.ClientEventArgs e )
{
Dispatcher.BeginInvoke( () => lblDisplay.Text = "Welcome " + e.LoadResult<Time>().theTime );
} );
Whew....I hope no one is lost from all this code I posted :P
Because you don't set the Namespace property on your DataContractAttribute, the namespace will be sythesized from the .NET class/namespace. You can see this in the SOAP message example you posted:
http://schemas.datacontract.org/2004/07/TestService.DataObjects
In order to have the contracts be considered equal, you must set the Namespace property on the DataContract to the same value on both sides. That might look a little something like this:
[DataContract(Namespace="urn:my-test-namespace")]
Extending on Drew Marsh's correct answer (+1 - thx) I had a generated Service Reference which was working, but when I tried to use the Wcf Client Factory one implementing the correct interface (but the namespace was different) then I was experiencing the problem described.
I had no easy way to work out what the "correct" namespace should have been but simply copying the following attributes from the service reference's DataContract entity to the one in the Wcf Client Factory implementation solved the issue;
[System.Runtime.Serialization.DataContractAttribute(Name = "BOSPrice", Namespace = "http://schemas.datacontract.org/2004/07/BOSDataService")]
[System.SerializableAttribute()]