在ASP.NET Boilerplate中重写SignalR契约解析器遇阻
I've run into this exact issue before with older ABP versions, so let's break down why the documented AbpSignalRContractResolver.IgnoredAssemblies approach might not be working for you, and how to fix it properly.
Common Reasons the Documented Method Fails
- You're ignoring the wrong assembly: The
IgnoredAssembliescollection targets assemblies where you want SignalR to use default camelCase serialization. If your DTOs/return types are in your Application layer (not Web layer), adding your Web module assembly won't affect them. - ABP's default resolver is overriding your settings: ABP replaces SignalR's default serializer with its own
AbpSignalRContractResolverduring initialization, so just adding assemblies to the ignore list might not be enough if you haven't explicitly configured camelCase for the resolver. - Incorrect configuration order: If you're adding the ignore list after
app.MapSignalR(), ABP's initialization might have already locked in the serializer settings.
Step-by-Step Fix
1. Target the Correct Assembly
First, make sure you're adding the assembly that contains your return types (e.g., your Application module assembly, not Web):
// In your Web Module's PreInitialize method AbpSignalRContractResolver.IgnoredAssemblies.Add(typeof(MyApplicationModule).Assembly);
Replace MyApplicationModule with the actual module class where your DTOs/return models are defined.
2. Explicitly Configure CamelCase Serialization for SignalR
If ignoring assemblies still doesn't work, you need to override SignalR's default JSON serializer to use camelCase directly. Do this before calling app.MapSignalR() in your Startup.cs:
public void Configuration(IAppBuilder app) { // Override SignalR's JSON serializer to use camelCase GlobalHost.DependencyResolver.Register(typeof(JsonSerializer), () => { return JsonSerializer.Create(new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver(), ReferenceLoopHandling = ReferenceLoopHandling.Ignore // Prevent circular reference issues }); }); // Map SignalR after configuring the serializer app.MapSignalR(); // Rest of your ABP initialization code... }
Alternatively, you can add this configuration in your Web Module's PreInitialize method to keep all module-related settings in one place.
3. Verify Your Hub Method Returns
Test with a simple return type to confirm:
public class TestDto { public string FullName { get; set; } public int Age { get; set; } } public class MyHub : AbpHub { public TestDto GetTestData() { return new TestDto { FullName = "John Doe", Age = 30 }; } }
When you call GetTestData() from the client, the response should be {"fullName":"John Doe","age":30} instead of PascalCase.
Why This Works
- By adding the correct assembly to
IgnoredAssemblies, you tell ABP's resolver to leave those types alone, letting SignalR use its default (now camelCase) serializer. - Explicitly setting
CamelCasePropertyNamesContractResolverensures that even if ABP's resolver interacts with your types, the serialization still follows camelCase rules.
内容的提问来源于stack exchange,提问作者Francisco Garcia

