Açıkçası bu yanıtı vermekte geciktim ama MVC5'te belirli bir eylem için IValueProvider
'u değiştirmenin bir yolunu geliştirdim. Bu sorunun yaşlandığından MVC3'te bunun mümkün olup olmadığına bakma çabasından hiç geçmedim, ama sanırım bir şekilde benzer.
Yasal Uyarı: Hoş değil.
Birincisi, biz eyleme özgü yapılandırmaları yapmak için, bir ayrıntıda uygulayabileceği yeni bir arayüz oluşturmak: kanca (eğer async
kullanıyorsanız veya AsyncControllerActionInvoker
) Sonra
internal interface IActionConfigurator
{
void Configure(ControllerContext controllerContext, ActionDescriptor actionDescriptor);
}
, biz özel bir ControllerActionInvoker
oluşturmak bizim yeni arayüz:
internal sealed class CustomControllerActionInvoker : AsyncControllerActionInvoker
{
protected override ActionDescriptor FindAction(ControllerContext controllerContext, ControllerDescriptor controllerDescriptor, string actionName)
{
var actionDescriptor = base.FindAction(controllerContext, controllerDescriptor, actionName);
var configurators = actionDescriptor.GetCustomAttributes(typeof(IActionConfigurator), true).Cast<IActionConfigurator>();
foreach (var configurator in configurators)
configurator.Configure(controllerContext, actionDescriptor);
return actionDescriptor;
}
}
Şimdi, ayarlamak için özel bir DefaultControllerFactory
uygulamak zorunda Controller.ActionInvoker
:
ControllerBuilder.Current.SetControllerFactory(typeof(CustomControllerFactory));
ve özel ayrıntı bizim IActionConfigurator
arabirimini uygulamak: Yeni Denetleyici örneği yana
internal sealed class IgnoreJsonActionConfiguratorAttribute : Attribute, IActionConfigurator
{
public void Configure(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
{
// Here we can configure action-specific stuff on the controller
var factories = ValueProviderFactories.Factories.Where(f => !(f is JsonValueProviderFactory)).ToList();
controllerContext.Controller.ValueProvider = new ValueProviderFactoryCollection(factories).GetValueProvider(controllerContext);
}
}
internal sealed class CustomControllerFactory : DefaultControllerFactory
{
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
var instance = base.GetControllerInstance(requestContext, controllerType);
var controller = instance as Controller;
if (controller != null)
controller.ActionInvoker = new CustomControllerActionInvoker();
return instance;
}
}
Son olarak, başlatma kodu varsayılan olarak bizim özel kontrolörü fabrika set Her istek üzerine oluşturulur, MVC'nin eylemi nasıl işlediğini değiştirmek için denetleyiciye eyleme özel değerler atayabiliriz.
[AcceptVerbs(HttpVerbs.Post)]
[IgnoreJsonActionConfigurator]
public async Task<ActionResult> Foo() { ... }
Teşekkürler, bu hile yaptı! Bu belgelenmemiş bir özellik mi yoksa sadece bir şey mi özledim? –
MVC, varsayılan olarak bir dizi değer sağlayıcıları fabrika içerir. MVC3 ile JsonValueProviderFactory'yi varsayılanlardan biri olarak dahil ettiler. Yukarıdaki kodun tamamı onu bulur ve uygulama başladığında kaldırır. Çevresinde başka bir yol ajax istekleri içerik türü uygulama/json kullanmak zorunda olmayabilirdi, ama değer sağlayıcı fabrika çıkarılması muhtemelen daha doğru olduğunu hissediyorum. –
Açıklama için teşekkürler. Hatta querystrings ve rotalar gibi şeyler için sağlayıcı fabrikalar olduğunu bile bilmiyordum. ModelBinder'ın hepsini ele aldığını varsaymıştım. –