背景:
在做一个Dicom Web Service, 当中WADO-RS中须要解析TransferSyntax, 然后就用到了fo-dicom中的DicomFile.ChangeTransferSyntax方法。代码相似:
var df = DicomFile.Open(samplesDir + @"User Submittedoverlays.dcm");
df = df.ChangeTransferSyntax(DicomTransferSyntax.JPEG2000Lossless);
问题:
就是上述代码在Console(exe)中执行正常, 在WebApi服务中则抛出异常:No codec registered for tranfer syntax:
原因:
查看fo-dicom源代码后, 发现DicomCodec是在DicomTranscoder的静态构造方法里用MEF初始化的。
代码相似:
static DicomTranscoder()
{
LoadCodecs(null, "Dicom.Native*.dll");
}
public static void LoadCodecs(string path = null, string search = null)
{
if (path == null)
{
path = Path.GetDirectoryName(new Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath);
}
var log = LogManager.Default.GetLogger("Dicom.Imaging.Codec");
var catalog = ( search == null )
? new DirectoryCatalog(path)
: new DirectoryCatalog(path, search);
var container = new CompositionContainer(catalog);
foreach (var lazy in container.GetExports<IDicomCodec>())
{
var codec = lazy.Value;
log.Debug("Codec: {0}", codec.TransferSyntax.UID.Name);
_codecs[codec.TransferSyntax] = codec;
}
}
当为Console时,上述path就是exe所在的路径,因此MEF的机制能够找到Dicom.Native.DLL,然后就能够取到Codecs。
当为AspNet WebApi时。上述path是C:WindowsMicrosoft.NETFrameworkv4.0.30319Temporary ASP.NET Files
oote298f90df8a423a
assemblydl32196513d06fccd3_417bd001。每一个DLL都在独立的路径下, 导致在WebApi的dll的路径找不到Dicom.Native.DLL,因此就取不到Codecs,从而抛出异常No codec registered for tranfer syntax:解决的方法:
在WebApiConfig.Register方法中加入例如以下代码:
var path = Path.GetDirectoryName(new Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath);
Dicom.Imaging.Codec.DicomTranscoder.LoadCodecs(path, "Dicom.Native*.dll");