Blazor WASM项目中Shared层能否引用Server与Client项目?
你的这个方案完全可行,并不违反Blazor WASM的分层原则
Blazor WASM强调Client和Server不直接引用,核心是避免客户端绑定服务端的实现细节(比如直接引用控制器类、业务逻辑类),但你在Shared层做的事情完全是安全的:
你用nameof(Web.Server.SchedulerController)只是在编译阶段获取控制器类的名称字符串,并没有让Client项目加载Server的程序集。Shared层的枚举本质上只是存储了路由需要的字符串标识,客户端用它生成URL时,完全不需要知道服务端控制器的具体实现。
这个方案的核心优势
- 编译时防错:如果服务端的控制器/动作方法重命名,
nameof会直接在编译阶段报错,不会等到上线后出现404才发现问题 - 路由统一维护:所有前端需要调用的路由入口都在Shared层的枚举里管理,不用在客户端到处写硬编码的URL字符串
可以再优化的几个点
- 去掉硬编码的命名空间:把
nameof(Web.Server.SchedulerController)改成nameof(SchedulerController)就行——只要Server项目引用了Shared层,编译时就能正确识别类名,还能避免命名空间变更带来的麻烦 - 适配自定义路由:如果你的控制器用了
[Route("api/scheduler")]这类自定义路由模板,直接把Display的Name改成实际路由值就行,比如[Display(Name = "api/scheduler")] - 修正URL构建的小问题:原代码里
routeValues是prms的笔误,另外返回相对URI(UriKind.Relative)比绝对URI更适合Blazor客户端的场景
优化后的代码示例
Shared层枚举
public enum EnumControllersList { [Display(Name = nameof(SchedulerController))] SchedulerController, // 其他控制器... } public enum EnumActionList { [Display(Name = nameof(SchedulerController.CreateAppointment))] CreateAppointment, // 其他动作... }
URL构建方法
public Uri Action(EnumControllersList controller, EnumActionList action, object prms = null) { var controllerName = EnumHelper<EnumControllersList>.GetDisplayValue(controller); var actionName = EnumHelper<EnumActionList>.GetDisplayValue(action); var baseRoute = $"{controllerName}/{actionName}"; if (prms == null) { return new Uri(baseRoute, UriKind.Relative); } var queryString = ToQueryString(prms); return new Uri($"{baseRoute}?{queryString}", UriKind.Relative); }
总的来说,这个方案既解决了硬编码URL的维护问题,又严格遵守了Blazor WASM的分层隔离原则,完全可以放心用。
内容的提问来源于stack exchange,提问作者Igor Markiv
相关产品推荐
相关产品推荐

