Hoje irei mostrar como podemos padronizar as resposta JSON do nossos Controllers no ASP.NET MVC.
Isso é bem útil para a criação de um padrão de respostas JSON em nossos Controllers e facilitar as comunicações AJAX.
Veja só o seguinte código:
public ActionResult Index(string uf) { var cities = this.stateService.GetCityByState(uf); return Json(new { Response = "OK", Data = cities, RequestTime = DateTime.Now }); }
Qual o problema do código acima ? A princípio nenhum mas tem um detalhe em um projeto de grande escala nós desenvolvemos diversas Actions provavelmente dezenas, centenas ou milhares e com um número grande de developers por equipe, correto ?
Será que todas as equipes seguirão esse modelo de resposta ? Não está muito fácil de se quebrar o padrão ?
Assim podemos concluir que precisamos padronizar as resposta em JSON e como fazer isso ? Veremos agora como é fácil a padronização utilizando ASP.NET MVC
Primeiro precisamos herdar da classe JSONResult e criar nosso padrão de resposta.
Veja como é simples implementar
public class StandardJsonResult : JsonResult { const string RequestRefused = "To allow GET requests, set JsonRequestBehavior to AllowGet."; public HttpStatusCode Status { get; set; } public override void ExecuteResult(ControllerContext context) { if (context == null) throw new ArgumentNullException("context"); if (JsonRequestBehavior == JsonRequestBehavior.DenyGet && String.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase)) throw new InvalidOperationException(RequestRefused); HttpResponseBase response = context.HttpContext.Response; response.ContentType = string.IsNullOrEmpty(ContentType) ? "application/json" : ContentType; if (ContentEncoding != null) { response.ContentEncoding = ContentEncoding; } SerializeData(response); } protected virtual void SerializeData(HttpResponseBase response) { var originalData = Data; Data = new { Success = true, Content = originalData, ErrorMessages = String.Empty, RequestTime = DateTime.Now, }; response.StatusCode = (int)HttpStatusCode.OK; response.Write(JsonConvert.SerializeObject(Data)); } }
Pronto, agora nossa classe de respostas JSON está implementada! Só que ainda não acabou, precisamos fazer nossos Controllers entender como retornar essa nova classe de resposta JSON.
Para isso vamos implementar uma classe BaseController que irá herdar de Controller
Vamos ao código:
public class BaseController : Controller { [Obsolete("Não use JSON, use JsonSuccess")] protected JsonResult Json<T>(T data) { throw new InvalidOperationException("Não use JSON, use JsonSuccess"); } protected StandardJsonResult JsonSuccess() { return new StandardJsonResult(); } protected StandardJsonResult JsonSuccess(Object Data) { return new StandardJsonResult() { Data = Data }; } }
Legal agora podemos padronizar as respostas dos nossos Controllers
public class StateController : Base.BaseController { [Inject] public IStateService stateService { get; set; } // GET: State [HttpPost] public ActionResult Index(string uf) { var cities = this.stateService.GetCityByState(uf); return JsonSuccess(cities); } }
Com esse tipo de implementação podemos padronizar todas as respostas JSON, desde de sucesso e até de erros.
O que acharam ? Não deixem de comentar.
Abs e até o próximo post
Rafael, ótimos tutoriais que você vem colocando para a galera.
Tenho uma dúvida referente a este tutorial.
Já que as respostas estão padronizadas, como eu trataria uma exception no código e capturaria isso no Jquery.Ajax em um padrão como este ?
Você tem um exemplo legal ?
Opa,
Obrigado pela visita
Tem como fazer sim com parte de erros se você ver no meu tutorial existe um campo chamado ErrorMessages
basta criar uma funcão na BaseController chamado JsonError no qual recebe um parametro uma lista de mensagem como o código abaixo
protected StandardJsonResult JsonError(IList errorMessage)
{
var result = new StandardJsonResult();
result.AddRange(errorMessage);
return result;
}
Abs.,