修改生成dir路径
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
parent
2bf47515e7
commit
0ef7fd85d4
|
|
@ -96,8 +96,11 @@ builder.Services.AddJsonLocalization(options => options.ResourcesPath = "Resourc
|
|||
// 异常、参数统一验证过滤器、Json序列化配置、字符串参数绑型统一Trim()
|
||||
builder.Services.AddControllers(options =>
|
||||
{
|
||||
// 关键配置:禁用不可空引用类型的自动 Required 验证
|
||||
options.SuppressImplicitRequiredAttributeForNonNullableReferenceTypes = true;
|
||||
|
||||
// 插到最前,抢在默认绑定器之前
|
||||
//options.ModelBinderProviders.Insert(0, new NullableStructModelBinderProvider());
|
||||
//options.ModelBinderProviders.Insert(0, new SpecificNullableBinderProvider());
|
||||
|
||||
options.Filters.Add<ModelActionFilter>();
|
||||
options.Filters.Add<ProjectExceptionFilter>();
|
||||
|
|
|
|||
|
|
@ -101,22 +101,24 @@ namespace IRaCIS.Core.API
|
|||
public void SetValue(object target, object value)
|
||||
{
|
||||
|
||||
_memberInfo.SetValue(target, value);
|
||||
|
||||
#region 前端针对 string 类型的变量,如果传递null 会报错必传
|
||||
|
||||
if (_memberInfo.PropertyType == typeof(string))
|
||||
{
|
||||
_memberInfo.SetValue(target, value == null ? string.Empty : value);
|
||||
}
|
||||
else
|
||||
{
|
||||
_memberInfo.SetValue(target, value);
|
||||
}
|
||||
//if (_memberInfo.PropertyType == typeof(string))
|
||||
//{
|
||||
// _memberInfo.SetValue(target, value == null ? string.Empty : value);
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// _memberInfo.SetValue(target, value);
|
||||
//}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 处理模型验证区分 string string?
|
||||
|
||||
//////接收模型的时候 定义的明明是string 但是上面也有该属性,判断不准的 比如阅片跟踪列表查询
|
||||
//var isNullable1 = _memberInfo.CustomAttributes.Any(a => a.AttributeType.Name == "NullableAttribute");
|
||||
|
||||
////不影响 string? 传递null 变为""
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Binders;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata;
|
||||
using Microsoft.Extensions.Localization;
|
||||
using Newtonsoft.Json;
|
||||
using System.Reflection;
|
||||
|
||||
|
||||
namespace IRaCIS.Core.Application.Filter;
|
||||
|
|
@ -31,97 +34,40 @@ public class ModelActionFilter(IStringLocalizer _localizer) : ActionFilterAttrib
|
|||
}
|
||||
|
||||
|
||||
public class NullableStructModelBinderProvider : IModelBinderProvider
|
||||
|
||||
|
||||
|
||||
public class SpecificNullableBinderProvider : IModelBinderProvider
|
||||
{
|
||||
public IModelBinder? GetBinder(ModelBinderProviderContext context)
|
||||
{
|
||||
// 获取要绑定的模型类型,比如 Guid?, int?, DateTime? 等
|
||||
var type = context.Metadata.ModelType;
|
||||
|
||||
//创建默认的模型绑定器(系统的原逻辑)
|
||||
var fallback = context.CreateBinder(context.Metadata);
|
||||
|
||||
|
||||
// 1. 处理 string 类型
|
||||
if (type == typeof(string))
|
||||
// 只处理 Guid? 和 int?
|
||||
if (type == typeof(Guid?) || type == typeof(int?))
|
||||
{
|
||||
return new StringNotNullableModelBinder(fallback);
|
||||
return new SpecificNullableBinder();
|
||||
}
|
||||
|
||||
// 检查是否是 Nullable<T> 类型
|
||||
// 1. 必须是泛型类型
|
||||
// 2. 泛型定义必须是 Nullable<>
|
||||
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
|
||||
{
|
||||
// 获取可空类型内部的实际类型,如 Guid?, int? 中的 Guid, int
|
||||
var innerType = Nullable.GetUnderlyingType(type)!;
|
||||
|
||||
|
||||
var binderType = typeof(NullableEmptyStringToNullBinder<>).MakeGenericType(innerType);
|
||||
|
||||
// 实例化绑定器,传入默认绑定器作为备用
|
||||
return (IModelBinder)Activator.CreateInstance(binderType, fallback)!;
|
||||
}
|
||||
|
||||
|
||||
return null; // 返回 null 表示"我不处理这个类型"
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// 泛型约束:T 必须是值类型(struct),这确保了只处理可空值类型 比如处理guid? 传递"" 为null
|
||||
public class NullableEmptyStringToNullBinder<T> : IModelBinder where T : struct
|
||||
public class SpecificNullableBinder : IModelBinder
|
||||
{
|
||||
private readonly IModelBinder _fallbackBinder;
|
||||
|
||||
// 构造函数接收一个备用的绑定器(系统的默认绑定器)
|
||||
public NullableEmptyStringToNullBinder(IModelBinder fallbackBinder)
|
||||
public Task BindModelAsync(ModelBindingContext context)
|
||||
{
|
||||
_fallbackBinder = fallbackBinder;
|
||||
}
|
||||
|
||||
public async Task BindModelAsync(ModelBindingContext context)
|
||||
{
|
||||
// 获取前端传递的值
|
||||
var value = context.ValueProvider.GetValue(context.ModelName).FirstValue;
|
||||
|
||||
// 关键逻辑:如果值是空字符串或空白,直接返回 null
|
||||
if (string.IsNullOrWhiteSpace(value))
|
||||
{
|
||||
// 设置绑定结果为 null(表示空值)
|
||||
context.Result = ModelBindingResult.Success(null);
|
||||
return;
|
||||
}
|
||||
|
||||
// 非空 → 完全走系统原逻辑
|
||||
|
||||
// 如果不是空字符串,则使用系统的默认绑定逻辑
|
||||
// 比如将 "123" 转换为 int? 123,或将 GUID 字符串转换为 Guid?
|
||||
await _fallbackBinder.BindModelAsync(context);
|
||||
}
|
||||
}
|
||||
|
||||
// 处理 string 的绑定器 如果前端不传递 或者null 时 处理为 ""
|
||||
public class StringNotNullableModelBinder : IModelBinder
|
||||
else
|
||||
{
|
||||
private readonly IModelBinder _fallbackBinder;
|
||||
|
||||
public StringNotNullableModelBinder(IModelBinder fallbackBinder)
|
||||
{
|
||||
_fallbackBinder = fallbackBinder;
|
||||
context.Result = ModelBindingResult.Success(value);
|
||||
}
|
||||
|
||||
public async Task BindModelAsync(ModelBindingContext context)
|
||||
{
|
||||
var value = context.ValueProvider.GetValue(context.ModelName).FirstValue;
|
||||
|
||||
// 前端不传或传空字符串,都设为 string.Empty
|
||||
if (string.IsNullOrWhiteSpace(value))
|
||||
{
|
||||
context.Result = ModelBindingResult.Success(string.Empty);
|
||||
return;
|
||||
}
|
||||
|
||||
await _fallbackBinder.BindModelAsync(context);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
using FellowOakDicom;
|
||||
using DocumentFormat.OpenXml.Office.CustomUI;
|
||||
using FellowOakDicom;
|
||||
using FellowOakDicom.Media;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
|
@ -57,6 +58,7 @@ namespace IRaCIS.Core.Application.Helper
|
|||
var mappings = new List<string>();
|
||||
int index = 1;
|
||||
|
||||
var studyUid=list.FirstOrDefault()?.StudyInstanceUid;
|
||||
|
||||
var dicomDir = new DicomDirectory();
|
||||
|
||||
|
|
@ -130,7 +132,7 @@ namespace IRaCIS.Core.Application.Helper
|
|||
|
||||
var relativePath= await _oSSService.UploadToOSSAsync(memoryStream, ossFolder, "DICOMDIR", true);
|
||||
|
||||
dic.Add("DICOMDIR" , relativePath.Split('/').Last());
|
||||
dic.Add($"{studyUid}_DICOMDIR" , relativePath.Split('/').Last());
|
||||
}
|
||||
|
||||
//清理临时文件
|
||||
|
|
|
|||
|
|
@ -1185,6 +1185,9 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
|||
|
||||
foreach (var item in list.GroupBy(t => new { t.StudyInstanceUid, t.DicomStudyId }))
|
||||
{
|
||||
|
||||
var studyUid = item.Key.StudyInstanceUid;
|
||||
|
||||
var ossFolder = $"{pathInfo.TrialId}/Image/{pathInfo.SubjectId}/{pathInfo.VisitId}/{item.Key.StudyInstanceUid}";
|
||||
|
||||
var isSucess = await SafeBussinessHelper.RunAsync(async () => await DicomDIRHelper.GenerateStudyDIRAndUploadAsync(item.ToList(), dirDic, ossFolder, _oSSService));
|
||||
|
|
@ -1192,7 +1195,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
|||
|
||||
if (isSucess)
|
||||
{
|
||||
await _dicomStudyRepository.BatchUpdateNoTrackingAsync(t => t.Id == item.Key.DicomStudyId, u => new DicomStudy() { StudyDIRPath = $"/{ossFolder}/{dirDic["DICOMDIR"]}" });
|
||||
await _dicomStudyRepository.BatchUpdateNoTrackingAsync(t => t.Id == item.Key.DicomStudyId, u => new DicomStudy() { StudyDIRPath = $"/{ossFolder}/{dirDic[$"{studyUid}_DICOMDIR"]}" });
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1625,6 +1628,8 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
|||
|
||||
var ossFolder = $"{pathInfo.TrialId}/Image/{pathInfo.SubjectId}/{visitId}/{item.Key.StudyInstanceUid}";
|
||||
|
||||
var studyUid = item.Key.StudyInstanceUid;
|
||||
|
||||
var isSucess = await SafeBussinessHelper.RunAsync(async () => await DicomDIRHelper.GenerateStudyDIRAndUploadAsync(item.ToList(), dirDic, ossFolder, _oSSService));
|
||||
|
||||
|
||||
|
|
@ -1632,11 +1637,11 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
|||
{
|
||||
if (isTaskStudy)
|
||||
{
|
||||
await _taskStudyRepository.BatchUpdateNoTrackingAsync(t => t.Id == item.Key.DicomStudyId, u => new TaskStudy() { StudyDIRPath = $"/{ossFolder}/{dirDic["DICOMDIR"]}" });
|
||||
await _taskStudyRepository.BatchUpdateNoTrackingAsync(t => t.Id == item.Key.DicomStudyId, u => new TaskStudy() { StudyDIRPath = $"/{ossFolder}/{dirDic[$"{studyUid}_DICOMDIR"]}" });
|
||||
}
|
||||
else
|
||||
{
|
||||
await _dicomStudyRepository.BatchUpdateNoTrackingAsync(t => t.Id == item.Key.DicomStudyId, u => new DicomStudy() { StudyDIRPath = $"/{ossFolder}/{dirDic["DICOMDIR"]}" });
|
||||
await _dicomStudyRepository.BatchUpdateNoTrackingAsync(t => t.Id == item.Key.DicomStudyId, u => new DicomStudy() { StudyDIRPath = $"/{ossFolder}/{dirDic[$"{studyUid}_DICOMDIR"]}" });
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -2303,6 +2308,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
|||
|
||||
var subjectId = item.First().SubjectId;
|
||||
|
||||
var studyUid = item.Key.StudyInstanceUid;
|
||||
|
||||
var ossFolder = $"{inCommand.TrialId}/Image/{subjectId}/{visitId}/{item.Key.StudyInstanceUid}";
|
||||
|
||||
|
|
@ -2310,7 +2316,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
|||
|
||||
if (isSucess)
|
||||
{
|
||||
await _dicomStudyRepository.BatchUpdateNoTrackingAsync(t => t.Id == item.Key.DicomStudyId, u => new DicomStudy() { StudyDIRPath = $"/{ossFolder}/{dirDic["DICOMDIR"]}" });
|
||||
await _dicomStudyRepository.BatchUpdateNoTrackingAsync(t => t.Id == item.Key.DicomStudyId, u => new DicomStudy() { StudyDIRPath = $"/{ossFolder}/{dirDic[$"{studyUid}_DICOMDIR"]}" });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,6 +87,8 @@ namespace IRaCIS.Core.Application.Service
|
|||
|
||||
public string? StringNUllValue { get; set; }
|
||||
|
||||
public string StringBackDefaultValue { get; set; } = string.Empty;
|
||||
|
||||
public Guid GuidValue { get; set; } = NewId.NextSequentialGuid();
|
||||
|
||||
public Guid? GuidNUllValue { get; set; }
|
||||
|
|
@ -104,12 +106,15 @@ namespace IRaCIS.Core.Application.Service
|
|||
public DateTime? DateTimeNUllValue { get; set; }
|
||||
}
|
||||
|
||||
|
||||
//创建一个模型验证的方法
|
||||
[AllowAnonymous]
|
||||
[HttpPost]
|
||||
public async Task<IResponseOutput> PostModelVerify(ModelVerifyCommand modelVerify)
|
||||
{
|
||||
|
||||
return ResponseOutput.Ok(modelVerify);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue