Obligando al servicio web ASP.net a devolver JSON

Tengo un servicio web ASP.net que estoy usando para una aplicación web que me devuelve datos XML o JSON, según la función a la que llame. Esto ha estado funcionando bien hasta ahora, pero me he encontrado con un problema. Quiero crear un enlace "exportar" en mi página que descargará un archivo JSON. El enlace está formateado muy simple:

<a href="mywebserviceaddress/ExportFunc?itemId=2">Export This Item</a>

Como puede imaginar, esto debería exportar el artículo 2. Hasta ahora, bien, ¿sí?

El problema es que, dado que no estoy solicitando específicamente que el tipo de contenido aceptado sea JSON, ASP.net se niega a devolver nada, excepto XML, que simplemente no es apropiado para esta situación. El código es esencialmente como sigue:

    [WebMethod]
    [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
    public Item ExportItem(int itemId)
    {
        Context.Response.AddHeader("content-disposition", "attachment; filename=export.json"); //Makes it a download

        return GetExportItem(itemId);
    }

A pesar de haber especificado el ResponseFormat como JSON, siempre recupero XML a menos que solicite este método a través de AJAX (usando Google Web Toolkit, BTW):

    RequestBuilder builder = new RequestBuilder(RequestBuilder.POST, "mywebserviceaddress/ExportFunc");
    builder.setHeader("Content-type","application/json; charset=utf-8");
    builder.setHeader("Accepts","application/json");
    builder.sendRequest("{\"itemId\":2}", new RequestCallback(){...});

Eso es genial, pero AJAX no me da un diálogo de descarga. ¿Hay alguna forma de obligar a ASP.net a que me devuelva JSON, independientemente de cómo se soliciten los datos? Me parece que no tener una anulación manual para este comportamiento es un descuido de diseño.

RESPUESTA RÁPIDA:

En primer lugar, permítanme decir que creo que la respuesta de Womp es probablemente la mejor manera de avanzar a largo plazo (Convertir a WCF), pero el control final me llevó a la respuesta que usaré para el futuro inmediato. Además, debe tenerse en cuenta que esto parece funcionar principalmente porque solo quería una descarga, puede que no funcione tan bien en todas las situaciones. En cualquier caso, aquí está el código que terminé usando para obtener el resultado que quería:

    [WebMethod]
    [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
    public void ExportItem(int itemId)
    {
        Item item = GetExportItem(itemId);            

        JavaScriptSerializer js = new JavaScriptSerializer();
        string str = js.Serialize(item);

        Context.Response.Clear();
        Context.Response.ContentType = "application/json";
        Context.Response.AddHeader("content-disposition", "attachment; filename=export.json");
        Context.Response.AddHeader("content-length", str.Length.ToString());
        Context.Response.Flush();
        Context.Response.Write(str);
    }

Tenga en cuenta el tipo de retorno devacío (lo que significa que su WDSL será casi inútil para esta función). Devolver cualquier cosa arruinará la respuesta que se está construyendo a mano.

Respuestas a la pregunta(3)

Su respuesta a la pregunta