【问题标题】:need route for my web api 2 controller我的 web api 2 控制器需要路由
【发布时间】:2016-12-27 19:58:46
【问题描述】:

我有一个返回 XML 的简单 WebApi2 控制器,但我无法使用我定义的路由正确添加另一个方法:

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}"
            );
    } 
}

}

我无法理解如何更改路由以识别 action 以便调用 GetGrantsIS 方法。而是使用以下 URL 浏览

CBMI.WebAPIservice/api/markers/GetGrantsIS

路由到识别 id 没有值的 Get 方法。然后它默认值为 0 并且它可以工作,但我需要让这个 URL 调用 GetGrantsIS 方法。

编辑:尝试添加属性路由会出现新错误

我的装饰如下:

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

现在我明白了:

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.

【问题讨论】:

标签: c# routes asp.net-web-api2 asp.net-web-api-routing asp.net-apicontroller


【解决方案1】:

Web Api 2 支持 REST 架构,这意味着它希望您的操作是 GET、POST、PUT、DELETE。

但是,您可以使用attribute routing 获得您想要的结果。

如果您想使用属性路由,您已经在 WebApiConfig 文件中进行了设置。因此,您只需要修改代码以使用 Route 属性,如下所示:

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

}

【讨论】:

  • 谢谢;这现在有效。关于您所做的 REST 评论,我想如果我的方法以 Get.. 开头(如上面的 GetGrantsIS),那么它可以在不使用属性路由的情况下解决。我考虑过用一个新的控制器来解决这个问题。
  • 确实如此,但它不会更改 URL。例如,您可以使用 GetGrantsIS() 并通过 /api/markers/ 访问它,但无法通过 /api/markers/GetGrantsIs 访问它。在第二种情况下,框架将尝试将 GetGransIS 解析为 Id 字段的 int 或完全忽略它。如果您想要可通过 URL 访问的自定义 get 方法,您最好的选择是属性路由。希望这是有道理的。
猜你喜欢
  • 1970-01-01
  • 2015-05-04
  • 1970-01-01
  • 1970-01-01
  • 2020-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多