need route for my web api 2 controller

1k views Asked by At

I have a simple WebApi2 controller that returns XML but I cannot add another method properly with the routing I have defined:

namespace CBMI.WebAPIservice.Controllers
{
public class MarkersController : ApiController
{
    public HttpResponseMessage Get(int? id)
    {
        int i = id.HasValue ? id.Value : 0;
        XmlDocument docContent = GetXmlDataFromDB(i);
        return new HttpResponseMessage
        {
            Content = new StringContent(docContent.InnerXml.ToString(), Encoding.UTF8, "application/xml")
        };
    }
    public HttpResponseMessage GetGrantsIS()
    {
        XmlDocument docContent = GetXmlDataFromDB();
        return new HttpResponseMessage
        {
            Content = new StringContent(docContent.InnerXml.ToString(), Encoding.UTF8, "application/xml")
        };

    }
    public XmlDocument GetXmlDataFromDB()
    {
        string connStr = System.Convert.ToString(
                System.Web.Compilation.ConnectionStringsExpressionBuilder.GetConnectionString("MDWConnectionString"),
                System.Globalization.CultureInfo.CurrentCulture);
        SqlConnection conn = new SqlConnection(connStr);
        SqlCommand sqlCmd = new SqlCommand("dbo.FLAS_List_GrantLocationsByAmount_V1", conn);
        sqlCmd.CommandType = System.Data.CommandType.StoredProcedure;
        conn.Open();
        XmlDocument xmlDoc = new XmlDocument();
        XmlReader xmlReader = sqlCmd.ExecuteXmlReader();
        if (xmlReader.Read())
            xmlDoc.Load(xmlReader);
        conn.Close();
        return xmlDoc;
    }
    public XmlDocument GetXmlDataFromDB(int worldAreaID )
    {
        string scrambleAward = ""; 
        string connStr = System.Convert.ToString(
                System.Web.Compilation.ConnectionStringsExpressionBuilder.GetConnectionString("MDWConnectionString"),
                System.Globalization.CultureInfo.CurrentCulture);
        SqlConnection conn = new SqlConnection(connStr);
        SqlCommand sqlCmd = new SqlCommand("dbo.FLAS_List_Awards_V1", conn);
        sqlCmd.CommandType = System.Data.CommandType.StoredProcedure;
        sqlCmd.Parameters.AddWithValue("@AreaID", worldAreaID);
        sqlCmd.Parameters.AddWithValue("@Scramble", scrambleAward);
        conn.Open();
        XmlDocument xmlDoc = new XmlDocument();
        XmlReader xmlReader = sqlCmd.ExecuteXmlReader();
        if (xmlReader.Read())
            xmlDoc.Load(xmlReader);
        conn.Close();
        return xmlDoc;
    }

}

}

WebApiConfig.cs

namespace CBMI.WebAPIservice.App_Start
{
//  This code file defines the delegate where you should put your Web API configuration code.

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Web API routes
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute
            (
                name: "WebApi2",
                routeTemplate: "api/{controller}/{id}"
            );
        config.Routes.MapHttpRoute
            (
                name: "ApiGrantsIS",
                routeTemplate: "api/{controller}/{action}"
            );
    } 
}

}

I cannot understand how to change the routing to recognize the action such that the GetGrantsIS method is invoked. Instead, browsing with the following URL

CBMI.WebAPIservice/api/markers/GetGrantsIS

routes to the Get method which recognizes that id has no value. It then defaults to a value of 0 and it works but I need to have this URL invoke the GetGrantsIS method.

EDIT: attempt to add Attribute Routing gives new error

I decorated as follows:

    [Route("api/{controller}/GetGrantsIS")]
    public HttpResponseMessage GetGrantsIS()

and now I get this:

Server Error in '/CBMI.WebAPIservice' Application.

A direct route cannot use the parameter 'controller'. Specify a literal path in place of this parameter to create a route to a controller.

1

There are 1 answers

2
Woot On BEST ANSWER

Web Api 2 favors REST architecture, meaning it expects your actions to be GET, POST, PUT, DELETE.

However you can get your desired results using attribute routing.

If you wanted to use attribute routing you already have that setup in your WebApiConfig file. So you would just need to modify your code to use the Route attribute like so:

[Route("api/markers/getgrantsis")]
public HttpResponseMessage GetGrantsIS()
{
  XmlDocument docContent = GetXmlDataFromDB();
  return new HttpResponseMessage
  {
    Content = new StringContent(docContent.InnerXml.ToString(), Encoding.UTF8, "application/xml")
   };

}