【问题标题】:RESTful controller inside other URI controller in ASP.NET Web API (Nested controllers)ASP.NET Web API 中其他 URI 控制器内的 RESTful 控制器(嵌套控制器)
【发布时间】:2015-05-21 16:54:08
【问题描述】:

我是编写 RESTful Web 服务的新手,我想使用 ASP.NET Web API 构建一个 RESTful Web 服务,第三方开发人员将使用它来访问我的应用程序的数据。

我的控制器旨在响应以下 URI:

api/warehouse --> return list of warehouses
api/warehouse/001 --> return warehouse 001
api/Binwarehouse --> return list of bins by  warehouses
api/Binwarehouse/001 --> return list of bins for warehouse 001

但我真正需要做的是让这个 uri 结构正常工作

api/warehouse/001/Binwarehouse --> return a list of  bins for warehouse 001
api/warehouse/001/Binwarehouse/020 --> return bin "020" from warehouse 001

instead
api/Binwarehouse --> return list of bins by  warehouses
api/Binwarehouse/001 --> return list of bins for warehouse 001

如果这是我的代码,我该怎么做?

GLOBAL.ASAX

using System;
using System.Web;
using System.Web.Optimization;
using System.Web.Routing;
using System.Web.Http;

namespace PSWMWrapperApi
{
    public class Global : HttpApplication
    {
        void Application_Start(object sender, EventArgs e)
        {
            // Code that runs on application startup
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            AuthConfig.RegisterOpenAuth();
            RouteConfig.RegisterRoutes(RouteTable.Routes);

            RouteTable.Routes.MapHttpRoute(name: "ApiClientes", routeTemplate: "api/{controller}/{dni}",
                defaults: new { dni = System.Web.Http.RouteParameter.Optional });
        }     
    }
}

WarehouseController.cs

using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web;
using System.Web.Http;

namespace PSWMWrapperApi
{
    public class WarehouseController : ApiController
    {          
        private Warehouse[] MostrarLista()
        {
            DataSet dsTemp = Funciones.ListaAlmacenes(Funciones.String_ConectaStatic, "1", "1", "1");    
            Warehouse[] listaBodegas = null;

            if (dsTemp != null)
            {
                DataTable oDtTemp = dsTemp.Tables[0];
                if (oDtTemp != null)
                {
                    listaBodegas = new Warehouse[oDtTemp.Rows.Count];
                    for (int i = 0; i < oDtTemp.Rows.Count; i++)
                    {
                        DataRow orow =   oDtTemp.Rows[i];
                        listaBodegas[i] = new Warehouse(orow["WarehouseId"].ToString(), orow["WarehouseDscr"].ToString());
                    }
                }
            }
            return listaBodegas;
        }

        // GET api/<controller>
        public IEnumerable<Warehouse> Get()
        {
            return MostrarLista();
           // return listaClientes;
        }

        // GET api/<controller>/44444444K
        public Warehouse Get(String dni)
        {
           return MostrarLista().Where(x => x.WarehouseId == dni).FirstOrDefault();
        }

    }
}

BinWarehouseController.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using System.Data;

namespace PSWMWrapperApi
{
    public class BinWarehouseController : ApiController
    {
        private BinWarehouse[] MostrarLista()
        {

            DataSet dsTemp = Funciones.ListaBinsAlmacenes(Funciones.String_ConectaStatic, "1", "1","","");    // _fun.ListaAlmacenes( );
            BinWarehouse[] listaBodegas = null;

            if (dsTemp != null)
            {
                DataTable oDtTemp = dsTemp.Tables[0];
                if (oDtTemp != null)
                {
                    listaBodegas = new BinWarehouse[oDtTemp.Rows.Count];
                    for (int i = 0; i < oDtTemp.Rows.Count; i++)
                    {
                        DataRow orow = oDtTemp.Rows[i];
                        listaBodegas[i] = new BinWarehouse(orow["WarehouseId"].ToString(), orow["BinId"].ToString(), orow["BinDscr"].ToString());
                    }
                }
            }
            return listaBodegas;
        }

        // GET api/<controller>
        public IEnumerable<BinWarehouse> Get()
        {
            return MostrarLista();
            // return listaClientes;
        }


        // GET api/<controller>/44444444K
        public BinWarehouse[] Get(String dni)
        { 
                return    MostrarLista().Where(x => x.WarehouseId.Trim() == dni).ToArray();
        }
    }
}

感谢您的帮助

【问题讨论】:

  • 看看属性路由

标签: c# asp.net rest asp.net-web-api


【解决方案1】:

您需要做的是包含支持所需 URI 的路由配置。考虑到它们将按照注册的顺序进行评估,并且将使用第一个匹配的路由。所以你必须首先包括更具体的,然后是最一般的。除了匹配路由结构之外,您还可以定义参数,并选择控制器和操作。

您的路线可能如下所示:

config.Routes.MapHttpRoute(
    name: "BinWarehouse",
    routeTemplate: "api/warehouse/{warehouseId}/Binwarehouse/{binId}",
    defaults: new { controller = "BinWarehouse", action = "MostrarLista" }
);

config.Routes.MapHttpRoute(
    name: "BinWarehouse",
    routeTemplate: "api/warehouse/{warehouseId}/Binwarehouse",
    defaults: new { controller = "Warehouse", action = "MostrarLista" }
);

你的action必须接收到路由捕获的参数(路由参数),即

public BinWarehouse[] MostrarLista(int warehouseId, int binId)

public Warehouse[] MostrarLista(int warehouseId)

但是,请注意,您应该了解更多关于路由和 Web API 的一般知识,以便以正确的方式做事。这是您现在开始使用这项技术之前应该做的基本内容。请至少快速阅读此文档:ASP.NET Web API

如果您阅读文档,特别是那些与路由相关的文档,您会发现您可以选择使用属性路由,以及如何使用。

【讨论】:

    【解决方案2】:

    只需为您希望返回的每个数据规范创建特定的 Get 方法,这样您就可以根据需要的数据将参数传递给 REST 服务。

    //Current Get() Methods
    
    //Access url would like /BinWarehouse?warehouseNum=001&binNum=020
    public IEnumerable<BinWarehouse> Get(string warehouseNum, string binNum){
      //Grab specific data and return it
    }
    

    【讨论】:

    • OP 是在询问如何使他想要使用的 URI 工作,而不是如何编写另一个工作的 URI。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-12
    • 2012-11-30
    • 1970-01-01
    • 2014-06-01
    • 2016-05-04
    • 2018-03-24
    相关资源
    最近更新 更多