ASP.NET HTTP-хендлер, возвращающий данные в формате JSON

28.11.2009 17:30 / Артём Волк / 2442 просмотра / ...

Существует несколько способов вернуть данные в формате JSON из ASP.NET:

Для сериализации .NET-объектов в формат JSON будет использоваться библиотека JSONSharp. Часто встречается требование, чтобы AJAX-ссылки были работоспособны и при прямом запросе. Поэтому в базовом классе в зависимости от типа запроса (AJAX или нет) будет осуществляться либо возврат данных в JSON-формате, либо редирект. Например, таким способом можно реализовать кнопку «Добавить в корзину», которая будет работать и при выключенном JavaScript.

Базовый класс для HTTP-хендлера:

namespace CrispStudio.Web
{
	/*
		Небольшой бонус: благодаря тому, что используется интерфейс IRequiresSessionState,
		внутри хендлера можно получить доступ к объекту Session	
	*/
	public abstract class JsonHttpHandler : IHttpHandler, IRequiresSessionState
	{
		protected object Result;

		protected abstract void HandleRequest(HttpContext context);

		protected bool IsAjax
		{
			get
			{
				return (HttpContext.Current.Request.Headers["X-Requested-With"] != null);
			}
		}

		public void ProcessRequest(HttpContext context)
		{
			HandleRequest(context);

			if (IsAjax)
			{
				context.Response.ContentType = "text/plain; charset=utf-8";
				if (Result != null)
				{
					JSONReflector jsonResult = new JSONReflector(Result);
					context.Response.Write(jsonResult.ToString());
				}
			}
			else
			{
				if (context.Request.UrlReferrer != null && context.Request.UrlReferrer.ToString() != String.Empty)
				{
					context.Response.Redirect(context.Request.UrlReferrer.ToString());
				}
				else
				{
					context.Response.Redirect("/");
				}
			}
		}

		public bool IsReusable
		{
			get
			{
				return false;
			}
		}
	}
}

Пример хендлера:

public class HalloWorldHandler : JsonHttpHandler
{
	protected override void HandleRequest(HttpContext context)
	{
		// Ещё бонус: удобно для отладки
		// System.Threading.Thread.Sleep(1000);

		Result = new
		{
			test = "Hallo, world!"
		};                
	}
}