2017-08-01 42 views
5

Poszukuje najlepszych praktyk podczas pracy z zagnieżdżonymi trasami w .NET Core MVC.NETCORE MVC - Praca z zagnieżdżonymi, wielowymiarowymi trasami

Powiedzmy CampusController.cs współpracuje z modelu podstawowego:

[Route("api/campus/")] 
public class CampusController : Controller 
{ 
    ... 
    [HttpGet] 
    [Route("{campusId}")] 
    public IActionResult GetCampusInfo ([FromQuery]int campusId) { ... } 
} 

I BuildingController.cs współpracuje z modelu dziecko:

[Route("api/campus/{campusId}/building")] 
public class BuildingController : Controller 
{ 
    ... 
    [HttpGet] 
    [Route("{buildingId}")] 
    public IActionResult GetBuilding ([FromQuery]int buildingId) { ... } 

    [Route("{buildingId}/")] 
    public IActionResult GetBuilding ([FromQuery]int buildingId) { ... } 
    .... 
    (more Action Methods) 
} 

If buildingId mapuje bezpośrednio do bazy danych może to pobierane nawet jeśli pod warunkiem campusId nie jest rodzicem. Aby adres URL był czysty podczas wywoływania /api/campus/{campusId}/building/{buildingId}, chciałbym sprawdzić poprawność {campusId} i zwrócić kod IActionResult zakodowany 4xx, jeśli jest nieprawidłowy. Musi istnieć lepszy sposób niż włączenie logiki walidacji do każdej metody działania wewnątrz BuildingController.

  • Czy istnieje sposób kaskadowania wielu metod działania na różnych kontrolerach? Aby metoda sprawdzania poprawności na CampusController była wywoływana jako pierwsza, a następnie wywołać metodę na BuildingController?
  • Czy istnieje sposób weryfikacji poziomu kontrolera na poziomie campusId, który może spowodować zwarcie i zwrócić ActionResult, jeśli sprawdzanie poprawności nie powiedzie się?

EDYCJA: Kiedy mówię o logice walidacji, mam na myśli sygnały API; nie logika biznesowa, która faktycznie określa, czy identyfikator campusID jest/nie jest prawidłowy.

Z góry dziękuję!

Odpowiedz

5

przypadku korzystania zastępczy w prefiksie trasy będzie trzeba także uwzględnić go w działaniu samego

[Route("api/campus/{campusId:int}/building")] 
public class BuildingController : Controller { 
    //... 

    [HttpGet] 
    [Route("{buildingId:int}")] // Matches GET api/campus/123/building/456 
    public IActionResult GetBuilding ([FromRoute]int campusId, [FromRoute]int buildingId) { 
     //... validate campus id along with building id 
    }  
} 

Jeżeli dana o wielokrotnym kodu dla walidacji następnie utworzyć kontroler bazowy życzenie kampusu powiązane i mają wspólną walidacji metoda.

Inną opcją jest posiadanie usługi/repozytorium, którego można użyć do zweryfikowania identyfikatora kampusu i jego związku z podanym identyfikatorem budynku, jeśli jest to konieczne.

+1

To rozwiązanie jest dla mnie najbardziej sensowne, ponieważ cały model 'campus' nie musi być w klasie' BuildingController'; konieczne jest jedynie proste sprawdzenie poprawności. Dzięki! –

+0

Dlaczego nie używać FromRoute zamiast FromQuery? – 000

+0

@Sam 'FromRoute' jest poprawny. Właśnie skopiowałem parametry z PO. to był niedopatrzenie z mojej strony. Zaktualizuję. Dziękuję za wskazanie tego. – Nkosi

2

Brzmi jak chcesz użytkownikom zapewnić campusId podczas rozmowy z BuildingController, a BuildingController do sprawdzania campusId w suchym rodzaju sposób.

Jeśli to przypadek, można utworzyć model wejściowy dla swoich metod BuildingController:

public class BuildingIdInput 
{ 
    [Required] 
    public int? CampusId { get; set; } 
    [Required] 
    public int? BuildingId { get; set; } 
} 

Wtedy można pozwolić wejściowe użytkownika MVC wiążą się z tym modelem.