I am brand-spanking-new to Web API. I am working on a proof of concept project for my team where we will create SSRS 2012 reports based off of Web-API XML data sources. However, the Web-API should not be configured to only negotiate XML as the content type. In a future phase, our web-applications should be able to retrieve JSON objects from the same controllers/actions.
I began by following this tutorial and everything worked, no problem.
Next I configured my routes so I can call actions directly, and I added QueryStringMappings
to my Global.asax so I could specify the content type.
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { id = UrlParameter.Optional }
);
}
}
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
GlobalConfiguration.Configuration.Formatters.JsonFormatter.AddQueryStringMapping("$format", "json", "application/json");
GlobalConfiguration.Configuration.Formatters.XmlFormatter.AddQueryStringMapping("$format", "xml", "application/xml");
}
}
This works great and I can now use localhost:XXXXX/api/Products/GetAllProducts/?$format=xml
as my data source connection string in SSRS. I'm not sure if this is the best way to do this, but it worked, so I stuck with it. Without the query string mappings the data source did not work in SSRS.
Here is where I ran into trouble. I branched off and created my first model/controller/action. When I run the project in my browser (Chrome or IE 10) and try to specify the format as XML localhost:XXXXX/api/Calcs/ComputeFooCalculation?$format=xml
, I get a JSON result back. The Products controller continues to work fine for JSON or XML content types, but for some reason my action will only render as JSON. Here is what my code looks like. Let me know if you need models or anything else. FooCalculation
has a nested object Bar
. Both FooCalculation
and Bar
have strings, doubles and DateTimes.
Controller:
public class CalcsController : ApiController
{
public FooCalculation ComputeFooCalculation()
{
var Foo = GetFoo();
var Bar = GetBar();
var FooCalculation = new FooCalculation(Foo, Bar);
return FooCalculation;
}
}
Sample JSON Result:
{"Foo":"XXX","FooRate":{"Foo":"XXX","Bar":"SN","FooBar":-1.00813E-05,"BarFoo":-3.2644199999999995E-06,"FoooBarrr":-4.17501E-06,"BarDate":"2013-05-14T00:00:00"},"BarRate":{"Foo":"XXX","Bar":"1W","FooBar":-2.08687E-05,"BarFoo":-3.11313E-05,"FoooBarrr":-3.3E-05,"BarDate":"2013-05-21T00:00:00"},"BarDate":"2013-05-20T00:00:00","FooDays":6,"FooBar":-7.3741306716417904E-06,"Bar":-0.0011149741306716415}
Place a parameterless constructor in your model class. The XML formatting is trying to instantiate an empty XML tree prior to you retrieving all of your data.