Calling a WCF Service from Silverlight: Somewhere my parameters are disappearing
I'm trying to call a WCF service from Silverlight using a generated proxy, and for some reason my parameters are getting nulled out. I make the call like so:
Events.EventServiceClient events = new Events.EventServiceClient(new BasicHttpBinding(), new EndpointAddress("http://localhost:52878/EventService.svc"));
event.EventTypeName = e.GetType().FullName;
events.AddEventWrapperAsync(new EventWrapper(event));
While debugging, when I call the AddEventWrapperAsync method I see that I have a valid object.However, stepping into the next call
public System.IAsyncResult BeginAddEventWrapper(BCL.BusinessObjects.EventWrapper Event, System.AsyncCallback callback, object asyncState) {
object[] _args = new object[1];
_args[0] = Event;
System.IAsyncResult _result = base.BeginInvoke("AddEventWrapper", _args, callback, asyncState);
return _result;
}
I find the "Event" parameter is set to a new EventWrapper(that is, all fields are set to their default values).
Anyone know where to start looking? It's obviously a serialization issue, but beyond that I'm perplexed.
Update: Here's the EventWrapper
using System;
using System.Collections.Generic;
using BCL.FLY;
using BCL.CTB;
using BCL.WCN;
using BCL;
using System.ServiceModel;
using System.Runtime.Serialization;
namespace BCL.BusinessObjects
{
[Serializable]
[DataContract]
public class Point
{
[DataMember]
public Double X { get; set; }
[DataMember]
public Double Y { get; set; }
public Point(System.Windows.Point point){
this.X = point.X;
this.Y = point.Y;
}
}
[DataContract]
public class EventWrapper
{
[DataMember]
public Guid Id { get; set; }
[DataMember]
public string StudentID{get;set;}
[DataMember]
public DateTime LocalTimestamp{get;set;}
[DataMember]
public GameEventType Type { get; set; }
[DataMember]
public int Level { get; set; }
[DataMember]
public int Score { get; set; }
[DataMember]
public string message { get; set; }
[DataMember]
public EventLoggingLevel LogLevel { get; set; }
[DataMember]
public int SessionID { get; set; }
[DataMember]
public string EventTypeName { get; set; }
[DataMember]
public double Speed { get; set; }
[DataMember]
public GameEventSubtype SubType { get; set; }
//CTBEvent
[DataMember]
public double BallSize{get;set;}
[DataMember]
public string CTBRuleType{get;set;}
[DataMember]
public Point ClickLocation{get;set;}
[DataMember]
public TimeSpan StimulusDuration{get;set;}
[DataMember]
public List<BallInfo> BallStates{get;set;}
//FLYEvent
[DataMember]
public string Category{get;set;}
[DataMember]
public List<BflyInfo> ButterFlies{get;set;}
//WCNEvent
[DataMember]
public TimeSpan TimeGiven{get;set;}
[DataMember]
public TimeSpan TimeRemaning{get;set;}
[DataMember]
public WCNTrialData TrialData{get;set;}
#region constructors
public EventWrapper() { }
public EventWrapper(IGameEvent _event)
{
this.StudentID = _event.StudentID;
this.LocalTimestamp = _event.LocalTimestamp;
this.Type = _event.Type;
this.Level = _event.Level;
this.Score = _event.Score;
this.message = _event.message;
this.LogLevel = _event.LogLevel;
this.SessionID = _event.SessionID;
this.EventTypeName = _event.EventTypeName;
this.Speed = _event.Speed;
this.SubTyp开发者_如何转开发e = _event.SubType;
}
public EventWrapper(CTBEvent _event)
{
this.StudentID = _event.StudentID;
this.LocalTimestamp = _event.LocalTimestamp;
this.Type = _event.Type;
this.Level = _event.Level;
this.Score = _event.Score;
this.message = _event.message;
this.LogLevel = _event.LogLevel;
this.SessionID = _event.SessionID;
this.EventTypeName = _event.EventTypeName;
this.Speed = _event.Speed;
this.SubType = _event.SubType;
this.BallSize = _event.BallSize;
this.CTBRuleType = _event.CTBRuleType;
this.ClickLocation = new Point(_event.ClickLocation);
this.StimulusDuration = _event.StimulusDuration;
this.BallStates = _event.BallStates;
}
public EventWrapper(FLYEvent _event)
{
this.StudentID = _event.StudentID;
this.LocalTimestamp = _event.LocalTimestamp;
this.Type = _event.Type;
this.Level = _event.Level;
this.Score = _event.Score;
this.message = _event.message;
this.LogLevel = _event.LogLevel;
this.SessionID = _event.SessionID;
this.EventTypeName = _event.EventTypeName;
this.Speed = _event.Speed;
this.SubType = _event.SubType;
this.Category = _event.Category;
this.ButterFlies = _event.ButterFlies;
}
public EventWrapper(WCNEvent _event)
{
this.StudentID = _event.StudentID;
this.LocalTimestamp = _event.LocalTimestamp;
this.Type = _event.Type;
this.Level = _event.Level;
this.Score = _event.Score;
this.message = _event.message;
this.LogLevel = _event.LogLevel;
this.SessionID = _event.SessionID;
this.EventTypeName = _event.EventTypeName;
this.Speed = _event.Speed;
this.SubType = _event.SubType;
this.TimeGiven = _event.TimeGiven;
this.TimeRemaning = _event.TimeRemaning;
this.TrialData = _event.TrialData;
}
#endregion
}
}
Here's the event that was generated when I selected "Add Service Reference"
public partial class CTBEvent : BCL.WCFEvents.IGameEvent {
private double BallSizeField;
private System.Collections.ObjectModel.ObservableCollection<BCL.WCFEvents.BallInfo> BallStatesField;
private string CTBRuleTypeField;
private System.Windows.Point ClickLocationField;
private System.TimeSpan StimulusDurationField;
private System.Collections.ObjectModel.ObservableCollection<string> _tField;
[System.Runtime.Serialization.DataMemberAttribute()]
public double BallSize {
get {
return this.BallSizeField;
}
set {
if ((this.BallSizeField.Equals(value) != true)) {
this.BallSizeField = value;
this.RaisePropertyChanged("BallSize");
}
}
}
[System.Runtime.Serialization.DataMemberAttribute()]
public System.Collections.ObjectModel.ObservableCollection<BCL.WCFEvents.BallInfo> BallStates {
get {
return this.BallStatesField;
}
set {
if ((object.ReferenceEquals(this.BallStatesField, value) != true)) {
this.BallStatesField = value;
this.RaisePropertyChanged("BallStates");
}
}
}
[System.Runtime.Serialization.DataMemberAttribute()]
public string CTBRuleType {
get {
return this.CTBRuleTypeField;
}
set {
if ((object.ReferenceEquals(this.CTBRuleTypeField, value) != true)) {
this.CTBRuleTypeField = value;
this.RaisePropertyChanged("CTBRuleType");
}
}
}
[System.Runtime.Serialization.DataMemberAttribute()]
public System.Windows.Point ClickLocation {
get {
return this.ClickLocationField;
}
set {
if ((this.ClickLocationField.Equals(value) != true)) {
this.ClickLocationField = value;
this.RaisePropertyChanged("ClickLocation");
}
}
}
[System.Runtime.Serialization.DataMemberAttribute()]
public System.TimeSpan StimulusDuration {
get {
return this.StimulusDurationField;
}
set {
if ((this.StimulusDurationField.Equals(value) != true)) {
this.StimulusDurationField = value;
this.RaisePropertyChanged("StimulusDuration");
}
}
}
[System.Runtime.Serialization.DataMemberAttribute()]
public System.Collections.ObjectModel.ObservableCollection<string> _t {
get {
return this._tField;
}
set {
if ((object.ReferenceEquals(this._tField, value) != true)) {
this._tField = value;
this.RaisePropertyChanged("_t");
}
}
}
}
A couple of questions:
- Probably unrelated to the problem but why are you using reserved keywords like "event" as variable names?
- You have debugged the server side and verified that parameter mangling really occurs and is not just a problem with the debug view, correct?
- What makes you think this is a serialization issue? From what I've read no serialization has occured yet.
- Are you sure that the generated proxy/client code matches the current version of the service hosted at http://localhost:52878/EventService.svc
- Update: Just a shot in the dark. Does calling the method using the Begin/End methods make any difference? (I know it shouldn't)
Update 1: Could you share the source for BCL.BusinessObjects.EventWrapper with us?
Update 2: Those custom constructors for the EventWrapper class look suspicous to me because on the client the EventWrapper should have been generated by the Service Reference and thus should not contain these constructors. So you have either modified Reference.cs on the Client - something that you shouldn't do or you have somehow imported the code from the Server Side code - something that you shouldn't do either. Which one is it?
Could you please try the webservice first with WCFTestClient or SoapUI? It could be the server-side that is acting up.
Also, I prefer contract sharing. This way much less stuff can go wrong because you don't need to generate those service references.
精彩评论