0

我已经编写了一个 WCF 服务来处理我的回合制网页游戏的主要业务逻辑,并且在使用 WcfTestClient 进行测试时遇到了问题。从我通过 WCF 公开的方法的签名中可以看出,它有几个可选参数。

public PlayerActionResult DoAction(PlayerActionType type, int uid, string pparam = null, int amount = 0, string svalue = null);

因此,动作类型和执行动作的玩家的用户 id (uid) 绝对是一个要求,之后参数变为可选,因为某些动作可能需要也可能不需要另一个玩家、整数数量或一般字符串值(即攻击另一个玩家需要另一个 Player 对象,使用角色名称[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.HandleReply(ProxyOperationRuntime >operation, ProxyRpc& rpc) 在 System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime >operation, ProxyRpc& rpc) 的服务器堆栈跟踪.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)在 System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage 消息)

在 [0] 处重新抛出异常:

在 System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg,>IMessage retMsg)

在 System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData,Int32 类型)

在 IConquestService.DoAction(PlayerActionType 类型,Int32 uid,String pparam,Int32 数量,String svalue)

在 ConquestServiceClient.DoAction(PlayerActionType 类型,Int32 uid,String pparam,Int32 数量,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));
    }
4

1 回答 1

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 使用正在访问的路由。

于 2013-09-16T04:07:45.497 回答