2010-12-14 62 views
6

J'ai un contrôleur appelé AuctionsController. J'y ai actions appelé Index() et AuctionCategoryListing():Besoin de conseils avant de développer une mauvaise habitude

//Used for displaying all auctions. 
public ActionResult Index() 
{ 
    AuctionRepository auctionRepo = new AuctionRepository(); 
    var auctions = auctionRepo.FindAllAuctions(); 
    return View(auctions); 
} 

//Used for displaying auctions for a single category. 
public ActionResult AuctionCategoryListing(string categoryName) 
{ 
    AuctionRepository auctionRepo = new AuctionRepository(); 
    var auctions = auctionRepo.FindAllAuctions() 
         .Where(c => c.Subcategory.Category.Name == categoryName); 
    return View("Index", auctions); 
} 

Comme vous pouvez le dire, ils ont tous deux invoquent le même point de vue (cette action est appelée « d'invoquer une vue » Qu'est-ce que c'est le nom propre. ?).

@model IEnumerable<Cumavi.Models.Auction> 

@{ 
    ViewBag.Title = "Index"; 
} 

<h2>Index</h2> 

<p> 
    @Html.ActionLink("Create New", "Create") 
</p> 
<table> 
    <tr> 
     <th></th> 
     <th> 
      IDSubcategory 
     </th> 
     <th> 
      IDCity 
     </th> 
     <th> 
      IDPerson 
     </th> 
     <th> 
      Title 
     </th> 
     <th> 
      TextBody 
     </th> 
     <th> 
      ContactNumber 
     </th> 
     <th> 
      AskingPrice 
     </th> 
     <th> 
      AddressDirection 
     </th> 
     <th> 
      LatestUpdateDate 
     </th> 
     <th> 
      VisitCount 
     </th> 
    </tr> 

@foreach (var item in Model) { 
    <tr> 
     <td> 
      @Html.ActionLink("Edit", "Edit", new { id=item.ID }) | 
      @Html.ActionLink("Details", "Details", new { id=item.ID }) | 
      @Html.ActionLink("Delete", "Delete", new { id=item.ID }) 
     </td> 
     <td> 
      @item.IDSubcategory 
     </td> 
     <td> 
      @item.IDCity 
     </td> 
     <td> 
      @item.IDPerson 
     </td> 
     <td> 
      @item.Title 
     </td> 
     <td> 
      @item.TextBody 
     </td> 
     <td> 
      @item.ContactNumber 
     </td> 
     <td> 
      @String.Format("{0:F}", item.AskingPrice) 
     </td> 
     <td> 
      @item.AddressDirection 
     </td> 
     <td> 
      @String.Format("{0:g}", item.LatestUpdateDate) 
     </td> 
     <td> 
      @item.VisitCount 
     </td> 
    </tr> 
} 

</table> 

Ils héritent tous les deux du même modèle. Ma question est la suivante: est-ce que je fais les choses de la bonne manière? Ou est-ce juste un hack j'ai réussi à gratter ensemble. Aide-moi avant que j'apprenne une mauvaise habitude.

+1

Je jauge des réponses selon upvotes, celui qui est downvoting chaque réponse ici s'il vous plaît arrêter. : \ –

+0

Entendre entendre, ou au moins avoir la courtoisie de donner une raison, nous sommes tous ici pour apprendre au moins contribuer à la discussion en offrant une explication/opinion. – RichardW1001

Répondre

3

Je modifier ce à:

public ActionResult Index(string categoryName) 
{ 

    AuctionRepository auctionRepo = new AuctionRepository(); 
    var auctions=auctionRepo.FindAllAuctions(); 

    if (!string.IsNullOrEmpty(categoryName)) 
    { 
     auctions = auctions.Where(c => c.Subcategory.Category.Name == categoryName); 
    } 

    return View(auctions); 
} 

Votre itinéraire pourrait alors ressembler à:

context.MapRoute(
     "auction_defalt", 
     "Auction/{categoryName}", 
     new { controller="Auction", action = "Index", categoryName = UrlParameter.Optional } 

Puisque les actions sont si semblables, je ne vois pas de raison de les séparer.

+0

Pouvez-vous élaborer sur ce que '{index}' représente? Mes URL sont comme: Enchères/Vêtements, ou Enchères/Électronique - etc. Je ne veux pas vraiment casser cela. –

+1

{index} était incorrect. J'ai mis à jour ma réponse. –

+0

J'ai fini par choisir ceci comme réponse parce que c'est le code le plus succinct et l'intention du code est très simple et pas compliquée. –

1

Vous devez faire des branchements quelque part, donc c'est probablement plus une question de préférence.

La façon dont je le manipulerais est d'avoir une seule méthode, et de prendre le nom de la catégorie comme paramètre. Puisque les chaînes sont nullables, si elles ne sont pas spécifiées, elles seront nulles. Ma méthode d'action serait probablement quelque chose comme:

public ActionResult Index(string categoryName) 
{ 
    AuctionRepository auctionRepo = new AuctionRepository(); 
    var auctions = auctionRepo.FindAllAuctions(); 

    if(String.IsNullOrEmpty(categoryName) == false) 
     auctions = auctions.Where(c => c.Subcategory.Category.Name == categoryName); 

    return View(auctions); 
} 
+0

J'aime vraiment votre suggestion. Je vais certainement l'essayer et voir comment ça va. Voyons voir ce que les autres pensent. –

+0

Quelqu'un est à la traîne ici, juste downvoting toutes les réponses. –

+0

Oui, j'ai vu que c'était fait à peu près tout le monde, c'est pourquoi j'ai supprimé mon commentaire. Il doit toujours y en avoir au moins un :) –

-1

C'est une caractéristique de MVC que la vue et le contrôleur sont indépendants. Vous pouvez également utiliser des vues partagées ou partielles pour la même chose, si je peux dire que c'est une bonne chose parce que vous écrivez du code réutilisable et que vous l'utilisez.

0

Je préférerais le repo à faire des choses telles que le filtrage et l'intérêt pour la pagination de la performance et le concept SEC

public ActionResult Index(string categoryName) 
    { 
     AuctionRepository auctionRepo = new AuctionRepository(); 

    //Let the Repo Handle things like filtering and pagination, avoiding performance issues 

     var auctions = auctionRepo.FindAllAuctions(categoryName); 

     return View(auctions); 
    } 

DAL devrait être responsable de ces tâches.

+0

Ma méthode FindAllAuctions renvoie un IQueryable . Donc, que je filtre dans le Controller ou dans la classe Repository, c'est une question de préférence. Je peux même utiliser Skip() et Take() sur IQueryable pour paginer. –

+0

Ok, je suis d'accord que vous préférez, si vous faites du filtrage sur plusieurs champs, je vous recommande de jeter un coup d'oeil à PredicateBuilder pour éviter toutes les choses if then elseif au niveau du contrôleur. – JOBG

+0

..ou vous pouvez simplement le faire dans une procédure stockée. –

2

Comme tout framework, ASP.NET MVC vous offre de nombreuses possibilités de prise de vue dans le pied. Sans réflexion préalable, la réutilisation des actions du contrôleur, des modèles de vue et des vues peut rapidement devenir un cauchemar de maintenance. Sans compter que sans pareille considération vos routes deviendront difficiles à lier ensemble. En suivant les principes de la convention sur la configuration, vous pouvez résoudre votre problème en utilisant des actions distinctes mais en réutilisant une vue partielle. Pour moi, l'action d'index du AuctionsController devrait être responsable de la liste de toutes les enchères dans le système. Je n'appellerais pas l'action de ma catégorie AuctionCategoryListing, mais je l'appellerais simplement Category. Grâce à la convention cela a pour effet agréable de jeter les routes comme:

  • site.com/auctions/ pour l'indice
  • site.com/auctions/category/CATEGORYNAME pour la catégorie.

La route est facilement compréhensible par l'utilisateur et vous permet de comprendre clairement ce que chacun fait.(À ce stade Omar fournit a good suggestion in his answer pour laisser votre référentiel gérer la pagination, le filtrage, etc.)

En ce qui concerne ce que chaque action devrait retourner, vous avez plusieurs options. Ma préférence serait de renvoyer des vues séparées contenant chacune une référence à un partiel commun. Cela vous donne la possibilité de créer différentes vues entourant le partiel mais permet de réutiliser la pièce commune.

Pour en savoir plus qui pourraient être utiles:

+0

Oui MVC encourage la séparation des préoccupations, mais il ne l'applique pas du tout, donc les gens commencent à faire des choses qui semblent bonnes, mais à long terme causer beaucoup de maux de tête, croyez-moi je sais ce que c'est (douloureux) . Ce qui vous a épargné quelques heures de conception au début vous ramènera à la fin, comme la question demande de l'aide pour développer une mauvaise habitude que je voulais juste souligner. Et ne vous méprenez pas c'est juste un conseil – JOBG

+1

@Omar très d'accord. Nous utilisons une architecture où les actions du contrôleur sont ** TRÈS ** petites. – ahsteele