Ho un'architettura abbastanza ben progettata in cui i controller vanno ai servizi che accedono ai repository che comunicano con il database.Come mantenere i controller piccoli in ASP.NET MVC?
Come tale, la logica nei controllori è mantenuta ad un minimo, ma ancora molto sottili pezzi di codice che eseguono alcuni compiti come
- convalidare il modello
- organizzare gli argomenti del metodo azione
- invocare alcuni servizi con questi argomenti, magari convalidare il risultato e restituire la vista se il modello è ora non valido
- infine produrre un modello dal risultato del servizio e restituirlo.
alcuni casi più lunghi fanno cose diverse a seconda di uno "stato" restituito dal servizio.
Ecco un paio di esempi:
[HttpPost]
[AjaxOnly]
[Authorize]
public JsonResult Preview(string input)
{
LinkResult parsed = linkService.ParseUserInput(input);
if (parsed.Result == LinkParseResult.Used)
{
long? postId = parsed.Link.PostId;
if (postId.HasValue)
{
Post post = postService.GetById(postId.Value, false);
return Json(new
{
faulted = "used",
link = DetailsRoute(post),
id = postId
});
}
else
{
return Json(new { faulted = "invalid" });
}
}
else if (parsed.Result == LinkParseResult.Invalid)
{
return Json(new { faulted = "invalid" });
}
else
{
Link link = parsed.Link;
if (link.Description != null && link.Description.Length > 200)
{
link.Description = link.Description.Substring(0, 200);
}
return AjaxView(link);
}
}
e (Post
viene dal dominio, PostModel
è il modello vista)
private PostModel PostModelConverter(Post post)
{
Link link = post.Link;
if (link == null)
{
throw new ArgumentException("post.Link can't be null");
}
if (link.Type == LinkType.Html)
{
return new PostedLinkModel
{
Description = link.Description,
PictureUrl = link.Picture,
PostId = post.Id,
PostSlug = postService.GetTitleSlug(post),
Timestamp = post.Created,
Title = link.Title,
UserMessage = post.UserMessage,
UserDisplayName = post.User.DisplayName
};
}
else if (link.Type == LinkType.Image)
{
return new PostedImageModel
{
PictureUrl = link.Picture,
PostId = post.Id,
PostSlug = postService.GetTitleSlug(post),
Timestamp = post.Created,
UserMessage = post.UserMessage,
UserDisplayName = post.User.DisplayName
};
}
return null;
}
Ciò solleva la questione su se visualizzare i modelli in realtà dovrebbe essere in di norma, o potrebbero essere parte del dominio o qualche altro progetto.
Non sono sicuro di poter fare molto sull'azione di anteprima, a parte forse usare un PreviewModel che riceve il collegamento e tronca la descrizione, ma questo salverebbe come, due righe.
Il convertitore di modello dovrebbe essere probabilmente da qualche altra parte, ma non ho idea di dove dovrebbe essere.
Un altro punto che viene in mente è se dovrei suddividere questo controller usando la parola chiave partial
(è una cattiva pratica usare questo per qualcosa di diverso dalle classi autogenerate?), O aggiungendo percorsi che usano controller diversi a seconda di quale azione è richiesta o quale metodo http viene utilizzato, qual è il solito modo di gestirlo?
Solo una preferenza personale, ma è possibile utilizzare le istruzioni switch invece di if .. else if ... ecc. –