我正在尝试在我的 ASP rest API 中实现 HATEOAS,更改 ReferenceResolverProvider
。
问题是,根据我使用的 Controller ,我想使用不同的 ReferenceResolvers
,因为我需要对每个 Controller 采取不同的行为。
现在我有了通用选项:
services.AddMvc()
.AddJsonOptions(option => option.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver())
.AddJsonOptions(options => options.SerializerSettings.ReferenceResolverProvider = () => new RoomsReferenceResolver<Room>())
.AddJsonOptions(options => options.SerializerSettings.PreserveReferencesHandling = PreserveReferencesHandling.Objects);
我想要这样的东西:
services.AddMvc()
.AddJsonOptions(option => option.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver())
.AddJsonOptions<RoomsController>(options => options.SerializerSettings.ReferenceResolverProvider = () => new RoomsReferenceResolver<Room>())
.AddJsonOptions(options => options.SerializerSettings.PreserveReferencesHandling = PreserveReferencesHandling.Objects);
最佳答案
您似乎想要创建每个 Controller 特定的格式化程序。这可以通过使用名为 IResourceFilter
的过滤器来实现。一个简单的例子:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class CamelCaseJsonFormatterResourceFilter : Attribute, IResourceFilter
{
private readonly JsonSerializerSettings serializerSettings;
public CamelCaseJsonFormatterResourceFilter()
{
// Since the contract resolver creates the json contract for the types it needs to deserialize/serialize,
// cache it as its expensive
serializerSettings = new JsonSerializerSettings()
{
ContractResolver = new CamelCasePropertyNamesContractResolver()
};
}
public void OnResourceExecuted(ResourceExecutedContext context)
{
}
public void OnResourceExecuting(ResourceExecutingContext context)
{
// remove existing input formatter and add a new one
var camelcaseInputFormatter = new JsonInputFormatter(serializerSettings);
var inputFormatter = context.InputFormatters.FirstOrDefault(frmtr => frmtr is JsonInputFormatter);
if (inputFormatter != null)
{
context.InputFormatters.Remove(inputFormatter);
}
context.InputFormatters.Add(camelcaseInputFormatter);
// remove existing output formatter and add a new one
var camelcaseOutputFormatter = new JsonOutputFormatter(serializerSettings);
var outputFormatter = context.OutputFormatters.FirstOrDefault(frmtr => frmtr is JsonOutputFormatter);
if (outputFormatter != null)
{
context.OutputFormatters.Remove(outputFormatter);
}
context.OutputFormatters.Add(camelcaseOutputFormatter);
}
}
// Here I am using the filter to indicate that only the Index action should give back a camelCamse response
public class HomeController : Controller
{
[CamelCaseJsonFormatterResourceFilter]
public Person Index()
{
return new Person() { Id = 10, AddressInfo = "asdfsadfads" };
}
public Person Blah()
{
return new Person() { Id = 10, AddressInfo = "asdfsadfads" };
}
如果您对过滤器的执行顺序感到好奇,下面是它们的顺序示例:
Inside TestAuthorizationFilter.OnAuthorization
Inside TestResourceFilter.OnResourceExecuting
Inside TestActionFilter.OnActionExecuting
Inside Home.Index
Inside TestActionFilter.OnActionExecuted
Inside TestResultFilter.OnResultExecuting
Inside TestResultFilter.OnResultExecuted
Inside TestResourceFilter.OnResourceExecuted
关于c# - 在 ASP.NET 5 中创建基于每个请求的 Controller /操作的格式化程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33455790/