升级2sxc至v14后Convert.FromBase64String无法正常工作
2sxc v14 API文件上传Base64转换问题解决方法
问题背景
升级自定义2sxc API至v14版本后,文件上传控制器中Base64转字节数组功能失效。原代码如下:
public class IntegrationApiController : Custom.Hybrid.Api14 { [HttpPost] public string UploadPdf([FromBody] dynamic bodyJson) { var entity = new Dictionary<string, object>(); var guid = Guid.NewGuid(); entity.Add("EntityGuid", guid); App.Data.Create("PDFForm", entity); var data = Convert.FromBase64String(bodyJson.file.ToString()); var returnThing = SaveInAdam(stream: new MemoryStream(data), fileName: bodyJson.fileName.ToString(), contentType: "PDFForm", guid: guid, field: "File"); return returnThing.Url; } }
首次报错信息:
{ "Message": "2sxc Api Controller Finder Error: Error selecting / compiling an API controller. Check event-log, code and inner exception. ", "ExceptionMessage": "c:\\Websites\\Mainstar\\Portals\\0\\2sxc\\DocusignForms\\api\\IntegrationApiController.cs(26): error CS1061: 'ToSic.Sxc.Services.IConvertService' does not contain a definition for 'FromBase64String' and no extension method 'FromBase64String' accepting a first argument of type 'ToSic.Sxc.Services.IConvertService' could be found (are you missing a using directive or an assembly reference?)", "ExceptionType": "System.Web.HttpCompileException", "StackTrace": " at System.Web.Compilation.AssemblyBuilder.Compile()\r\n at System.Web.Compilation.BuildProvidersCompiler.PerformBuild()\r\n at System.Web.Compilation.BuildManager.CompileWebFile(VirtualPath virtualPath)\r\n at System.Web.Compilation.BuildManager.GetVPathBuildResultInternal(VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile, Boolean throwIfNotFound, Boolean ensureIsUpToDate)\r\n at System.Web.Compilation.BuildManager.GetVPathBuildResultWithNoAssert(HttpContext context, VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile, Boolean throwIfNotFound, Boolean ensureIsUpToDate)\r\n at System.Web.Compilation.BuildManager.GetVPathBuildResult(HttpContext context, VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile, Boolean ensureIsUpToDate)\r\n at System.Web.Compilation.BuildManager.GetCompiledAssembly(String virtualPath)\r\n at ToSic.Sxc.Dnn.WebApiRouting.AppApiControllerSelector.HttpControllerDescriptor(HttpRequestMessage request, String controllerFolder, String controllerPath, String controllerTypeName, LogCall`1 wrapLog) in C:\\Projects\\2sxc\\2sxc\\Src\\Dnn\\ToSic.Sxc.Dnn.WebApi\\Dnn\\WebApiRouting\\AppApiControllerSelector.cs:line 168\r\n at ToSic.Sxc.Dnn.WebApiRouting.AppApiControllerSelector.SelectController(HttpRequestMessage request) in C:\\Projects\\2sxc\\2sxc\\Src\\Dnn\\ToSic.Sxc.Dnn.WebApi\\Dnn\\WebApiRouting\\AppApiControllerSelector.cs:line 83" }
改为System.Convert.FromBase64String后,出现新错误:Cannot perform runtime binding on a null reference
错误原因
- 命名冲突:Api14控制器内置了
Convert服务(属于ToSic.Sxc.Services.IConvertService),直接使用Convert.FromBase64String会调用该服务,而非.NET原生的System.Convert,导致找不到方法。 - 空引用问题:使用
dynamic参数无法确保请求体中的file和fileName字段存在,若请求格式不正确或字段缺失,调用ToString()时会触发空引用异常。
解决步骤
1. 完全限定.NET原生Convert命名空间
明确使用System.Convert.FromBase64String,避免与2sxc内置服务冲突。
2. 替换dynamic为强类型模型
定义强类型类接收请求体,确保参数类型安全,同时便于验证输入是否有效。
3. 添加参数验证
在处理前检查关键参数是否为空,提前抛出明确的错误信息。
完整修正代码
using System; using System.Collections.Generic; using System.IO; using System.Net; using System.Net.Http; using System.Web.Http; public class IntegrationApiController : Custom.Hybrid.Api14 { // 定义强类型模型接收请求体 public class PdfUploadRequest { public string File { get; set; } public string FileName { get; set; } } [HttpPost] public IHttpActionResult UploadPdf([FromBody] PdfUploadRequest request) { // 参数验证 if (request == null || string.IsNullOrEmpty(request.File) || string.IsNullOrEmpty(request.FileName)) { return BadRequest("请求参数不完整,必须包含File(Base64字符串)和FileName字段"); } try { var guid = Guid.NewGuid(); // 创建PDFForm实体 var entity = new Dictionary<string, object> { { "EntityGuid", guid } }; App.Data.Create("PDFForm", entity); // 使用System.Convert转换Base64为字节数组 var data = System.Convert.FromBase64String(request.File); var adamResult = SaveInAdam( stream: new MemoryStream(data), fileName: request.FileName, contentType: "PDFForm", guid: guid, field: "File"); return Ok(new { Url = adamResult.Url }); } catch (FormatException ex) { return BadRequest($"Base64格式错误:{ex.Message}"); } catch (Exception ex) { return InternalServerError(ex); } } }
额外说明
- 强类型模型确保请求体字段与代码预期一致,避免dynamic类型的隐式转换问题。
- 参数验证和异常捕获能返回更清晰的错误信息,便于调试和前端处理。
- 始终使用
System.Convert而非简写的Convert,避免与2sxc内置服务命名冲突。
内容的提问来源于stack exchange,提问作者John K.
相关产品推荐
相关产品推荐

