Bagaimana cara menambahkan Filter Api Web ASP.Net global?

98

Saya telah membuat filter Web Api (menggunakan System.Web.Http.Filters.ActionFilterAttribute) tetapi saya tidak dapat membuatnya berfungsi di dalam ASP.Net MVC 4. Saya mencoba menambahkannya ke RegisterGlobalFilters()metode tetapi tidak berhasil.

Jadi jika seseorang menggunakan Web Api yang dihosting di ASP.Net MVC, bagaimana cara mendaftarkan filter?

Shane Courtrille
sumber

Jawaban:

110

Kode berikut, di Global.asax saya, berfungsi untuk saya:

public static void RegisterWebApiFilters(System.Web.Http.Filters.HttpFilterCollection filters)
{
  filters.Add(new MyWebApiFilter());
}

protected void Application_Start()
{
  RegisterWebApiFilters(GlobalConfiguration.Configuration.Filters);
}
Dave Bettin
sumber
6
Adakah yang bisa menjelaskan apa yang terjadi di sini? Mengapa ada dua set filter Global? Bukankah itu membuat 'Global' menjadi sebuah oxymoron?
Luke Puplett
6
Satu set filter untuk MVC dan yang lainnya untuk API Web. Mereka adalah dua hal yang terpisah dan biasanya Anda tidak ingin filter untuk satu diterapkan ke yang lain.
Shane Courtrille
2
Filter WebApi saya dipanggil dua kali. Ada yang punya masalah ini?
Andrew Kalashnikov
87

perhatikan bahwa jawaban ini berlaku hingga MVC 5 / Web API 2

Jawaban singkat: Filter MVC dan Web API tidak kompatibel silang, dan jika Anda ingin mendaftarkannya secara global, Anda harus menggunakan kelas konfigurasi yang sesuai untuk masing-masing.

Jawaban panjang: ASP.NET MVC dan Web API sengaja dirancang untuk bekerja dengan cara yang sama, tetapi pada kenyataannya keduanya adalah makhluk yang berbeda.

API Web berada di bawah System.Web.Httpnamespace, sedangkan MVC berada di bawah System.Web.Mvcnamespace. Keduanya akan hidup berdampingan dengan senang hati, tetapi yang satu tidak berisi yang lain dan terlepas dari kesamaan dalam model pemrograman, implementasi yang mendasarinya berbeda. Sama seperti pengontrol MVC dan pengontrol API Web mewarisi kelas pengontrol dasar yang berbeda (MVC diberi nama sederhana Controllerdan Web API diberi nama ApiController) filter MVC dan filter API Web mewarisi dari FilterAttributekelas yang berbeda (keduanya berbagi nama yang sama dalam kasus ini, tetapi merupakan kelas terpisah yang hidup di ruang nama masing-masing).

Filter global API Web didaftarkan melalui HttpConfigurationobjek yang tersedia untuk Anda dalam Registermetode WebApiConfig.cs jika Anda menggunakan template proyek dengan WebActivator:

public static void Register(HttpConfiguration config)
{
    //stuff before
    config.Filters.Add(new MyWebApiFilter());
    //stuff after
}

atau sebaliknya di global.asax.cs:

GlobalConfiguration.Configuration.Filters.Add(new MyWebApiFilter());

Filter global MVC didaftarkan melalui GlobalFilterCollectionobjek, yang tersedia untuk Anda melalui RegisterGlobalFiltersmetode FilterConfig.cs untuk proyek yang menggunakan WebActivator:

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        //stuff before
        filters.Add(new MyMvcFilter());
        //stuff after
    }
}

atau dalam file global.asax.cs sebagai cara GlobalFilters.Filterspengumpulan untuk mereka yang tidak memiliki WebActivator:

GlobalFilters.Filters.Add(new MyMvcFilter());

Perlu dicatat bahwa dalam kedua kasus Anda tidak perlu mewarisi dari FilterAttributejenis yang sesuai . Filter API Web hanya perlu mengimplementasikan antarmuka System.Web.Http.IFilter, sementara pendaftaran filter MVC memeriksa untuk memastikan bahwa kelas Anda mewarisi salah satu dari segelintir antarmuka filter yang ditentukan dalam System.Web.Mvcnamespace.

joelmdev
sumber
Menambahkan filter Api Web kustom di webapiconfig.cs berhasil untuk saya. Saya tidak mengerti mengapa itu tidak berhasil ketika ditambahkan di global.asax.cs
Tatipaka
terima kasih @tatipaka. menambahkan ke webapiconfig berhasil.
Gokulnath
12

Pada MVC 4 RC, nama kelas yang benar adalah HttpFilterCollection :

public static void RegisterWebApiFilters(System.Web.Http.Filters.HttpFilterCollection filters)
{
    filters.Add(new MyWebApiFilter());
}

protected void Application_Start()
{
    RegisterWebApiFilters(GlobalConfiguration.Configuration.Filters);
}
nuzzolilo
sumber
8

Daripada menggunakan filter global, saya lebih suka melakukan ini:

[MyWebApiFilter]
public class CustomizedApiControllerBase : ApiController
{
   ...
}

Dan setelah itu mewarisi semua pengontrol api dari CustomizedApiControllerBase Pendekatan ini lebih ekspresif dibandingkan dengan filter global di file global.ascx.

Mahmoud Moravej
sumber
Saya membuat Filter yang diturunkan dari System.Web.Http.Filters.ActionFilterAttribute dan melanjutkan untuk menggunakannya secara langsung pada metode yang saya perlukan. Ini berfungsi, jadi mengapa saya tidak perlu mendaftarkannya?
joedotnot
@joedotnot Ini tentang filter "global" bukan yang spesifik. Jika Anda dapat menentukan metode mana yang ingin Anda filter, pendekatan Anda baik-baik saja tetapi ketika Anda ingin memfilter apa pun tindakan pengontrol, Anda memerlukan filter global.
Mahmoud Moravej