如果你使用通用的System.action()调用,你如何从WCF调用返回值?

本文关键字:调用 返回值 WCF System 如果 action | 更新日期: 2023-09-27 18:06:24

为了减少代码量,我们的团队在StartProcess方法中调用WCF实现,用于单个方法的所有调用。这一切都很棒,但是由于泛型方法的实际调用使用了System。操作调用,它永远不能返回一个值,因为我正在进行的一个调用我想要请求/回复,我无法获得返回值。

下面是处理WCF请求的通用方法:

public static ProcessResultDC StartProcess<T>(T setupData, string processName, Action<T> action, string exteriorAccountNumber, string companyCode) where T : IAmValidatable, IHaveAProcessGuid {
    var result = new ProcessResultDC { Status = ProcessStatusEnum.Accepted };
    // Do some authentication stuff here
    try {
        action(setupData);    // <-- This returns void, but I would like to return a string to the client
    } catch (Exception exc) {
        result.Status = ProcessStatusEnum.Error;
        result.Messages.Add(exc.Message);
    }
    return result;
}

下面是客户端调用:

var createOnDemandDataDc = new CreateOnDemandDataDc { RawData = punchRawData };
var result = TimeForceProcessHelper.StartProcess(createOnDemandDataDc, "Create On Demand Data", x => new CreateOnDemandDataProxy().CreateOnDemandData(createOnDemandDataDc), "NA", companyCode);

结果变量没有办法知道来自动作调用的字符串,即使我的createOnDemandDataDc实现返回一个字符串。

有更好的方法吗?或者我可以简单地做一些事情,而不是一个Action()调用,以获得返回字符串?

如果你使用通用的System.action()调用,你如何从WCF调用返回值?

代替使用Action<T>作为回调参数,您可以使用Func<T, TResult>来允许回调返回一个值给StartProcess调用者。但是,这需要将所有回调函数更改为返回值的函数。如果你只有一个回调需要返回一个回复,这可能不是一个愉快的想法。

另一种有点脏的方法可能是在CreateOnDemandDataDc回调函数中直接编写对当前活动OperationContext的响应。查看OperationContext.Current.RequestContext.Reply及其相关属性/方法

我也是这样做AOP的。每个方面需要两个方法——一个用于Action,一个用于Func

如果你先写Func:

public static ProcessResultDC StartProcess<T, TResult>(
  T setupData,
  string processName,
  Func<T, TResult> fn,
  string exteriorAccountNumber,
  string companyCode
)
  where T : IAmValidatable, IHaveAProcessGuid
{
  var result = new ProcessResultDC { Status = ProcessStatusEnum.Accepted };
  // Do some authentication stuff here
  try
  {
    result.Result = fn(setupData);
  }
  catch (Exception exc)
  {
    result.Status = ProcessStatusEnum.Error;
    result.Messages.Add(exc.Message);
  }
  return result;
}

然后你可以为Action编写一个使用Func实现的代码:

public static ProcessResultDC StartProcess<T>(
  T setupData,
  string processName,
  Action<T> fn,
  string exteriorAccountNumber,
  string companyCode
)
  where T : IAmValidatable, IHaveAProcessGuid
{
  return StartProcess(
    setupData,
    processName,
    t => { fn( t ); return 0; },
    exteriorAccountNumber,
    companyCode
  );
}