我已经编写了一个WCF服务来处理基于回合制的Web游戏中的主要业务逻辑,而且在使用WcfTestClient进行测试时遇到了一个问题。从我在WCF上公开的方法的签名中可以看出,它有几个可选参数。
public PlayerActionResult DoAction(PlayerActionType type, int uid, string pparam = null, int amount = 0, string svalue = null);
因此,动作的类型绝对是执行动作的玩家的用户ID(uid),之后参数变为可选参数,因为某些动作可能需要或可能不需要其他玩家,整数或者一般字符串值(即攻击另一个玩家需要另一个玩家对象,使用角色[pparam]的名称查找)。以下是DoAction方法的完整实现:
public PlayerActionResult DoAction(PlayerActionType type, int uid, string pparam = null, int amount = 0, string svalue = null)
{
Player playerparam;
Player player;
// Verify players exist
if (!PlayerExists(uid))
{
return new PlayerActionResult(false, ResultType.NotFound);
}
else { player = GetPlayer(uid); }
if (pparam != null & !PlayerExists(pparam))
{
return new PlayerActionResult(false, ResultType.NotFound);
}
else { playerparam = GetPlayer(pparam); }
// Construct action and pass parameters
return player.DoAction(new PlayerAction(type, playerparam, amount, svalue));
}
鉴于这种方法,我决定进行一些测试,以确保大部分时间都能正常运行。一切正常,直到我尝试通过WcfTestClient将(null)传递给方法,此时我收到以下错误:
序列不包含元素
服务器堆栈跟踪: System.ServiceModel.Channels.ServiceChannel.ThrowIfFaultUnderstood(消息回复,> MessageFault错误,字符串操作,MessageVersion版本,FaultConverter faultConverter) 在System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime>操作,ProxyRpc& rpc) 在System.ServiceModel.Channels.ServiceChannel.Call(String action,Boolean oneway,> ProxyOperationRuntime operation,Object [] ins,Object [] outs,TimeSpan timeout) 在System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage> methodCall,ProxyOperationRuntime操作) 在System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
在[0]处重新抛出异常:
在System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg,> IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData,Int32 type)
at IConquestService.DoAction(PlayerActionType type,Int32 uid,String pparam,Int32 amount,String svalue)
at ConquestServiceClient.DoAction(PlayerActionType type,Int32 uid,String pparam,Int32 amount,String svalue)
我已经在这种困境中熬了一段时间,并对“序列包含无元素”关键字进行了多次搜索,但对此特定问题无济于事。 请记住,当我从我的MVC应用程序调用此方法时,一切都运行得非常顺利,动作逻辑被调用并处理没有问题。 它似乎只有在我尝试在WcfTestClient中传递(null)作为pparam。如果有人偶然发现并且能够启发我,我会非常感激。
更新:
感谢您的建议!我在发布这篇文章的15分钟内摆弄它,我做了一些修改,最终修复了问题。我保留了可选参数,并通过首先实例化PlayerAction对象,然后直接在方法中设置该对象的playerparam属性(如果存在pparam字符串)来重新转发方法。现在看来是这样的:
public PlayerActionResult DoAction(PlayerActionType type, int uid, string pparam = null, int amount = 0, string svalue = null)
{
Player player;
PlayerAction action = new PlayerAction();
action.type = type;
// Verify executor exists
if (!PlayerExists(uid))
{
return new PlayerActionResult(false, ResultType.NotFound);
}
else { player = GetPlayer(uid); }
if (pparam != null & !PlayerExists(pparam))
{
if (!PlayerExists(pparam))
{
return new PlayerActionResult(false, ResultType.NotFound);
}
action.playerparam = GetPlayer(pparam);
}
// Construct action and pass parameters
return player.DoAction(new PlayerAction(type, amount, svalue));
}
答案 0 :(得分:0)
您是否尝试将这些实现为重载而不是可选参数?
例如:
public PlayerActionResult DoAction(PlayerActionType type, int uid);
public PlayerActionResult DoAction(PlayerActionType type, int uid, string pparam);
public PlayerActionResult DoAction(PlayerActionType type, int uid, string pparam, int amount);
//etc...
Windows Communication Foundation可能无法理解所分配的默认参数,而只是将OperationContract作为一个在WSDL中包含两个参数的方法进行传输。
这可以解释为什么它在MVC中工作,因为WCF需要在SOAP信封中传输的信息来正确地决定在服务器上执行哪个方法,而MVC使用被访问的路由。