【问题标题】:Proper routing configuration for multiple apis sharing same endpoint共享同一端点的多个 API 的正确路由配置
【发布时间】:2015-06-06 16:56:44
【问题描述】:

对于我希望接收的每种类型的 XML 发布数据,我有一个具有不同端点(不同控制器)的有效 API。现在,客户希望我们对所有事情都使用相同的端点。唯一确定方向的是 XML 数据的内容——基本上是根元素的名称。

我希望能够尽可能多地利用我现有的工作,因此我正在尝试添加一个新的控制器“路由器”,它正是这样做的——根据接收到的内容重定向到正确的路由。我已经尝试了一些东西,但似乎无法获得任何牵引力。

如果有更好的方法来处理这个问题,我愿意听听。

        // WebApiConfig.cs
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "{controller}/{id}",
            //routeTemplate: "Router",
            constraints: null,
            defaults: new { id = RouteParameter.Optional }
        );

//在RouteConfig.cs中——这对特定的MapRoute和MapHttpRoute是多余的吗?

        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(name: "First", url: "First/{action}/{id}" );
        routes.MapRoute(name: "Second", url: "Second/{action}/{id}" );
        routes.MapRoute(name: "Third", url: "Third/{action}/{id}" );

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", 
                            action = "Index", 
                            id = UrlParameter.Optional }
        );

但无论如何,我的 APi 流量确实到达了 RouterController (我承认我并不完全清楚它为什么起作用)但是有一次 在那里,我如何根据发布的 XML 数据进行重新路由?

public RouterController()
{
    log.Debug("Inside RouterController");
}


public IHttpActionResult Post(object postdata)
{
    // how to determine the postdata contents / XML structure to get the 
    // root element and then redirect to the "true" controller?
}

这里有几个问题:首先,为什么 WebApiConfig.cs 路由定义和 RouteConfig.cs 路由中有(明显的)冗余?其次,根据内容和路线适当识别流量的最佳方法是什么?

感谢您的帮助。我承认在这里跑得相当盲目,因此感谢您提供任何帮助。

【问题讨论】:

    标签: c# xml routing asp.net-web-api2


    【解决方案1】:

    我认为在你的路由中包含一些 xml 解析逻辑不是一个好主意(如果可能的话)。

    根据您的描述,我猜您有许多控制器方法和模型。您可以保持它们几乎不变,也许只是将方法设为私有。

    public class First
    {
        public string Name { get; set; }
    }
    
    public class Second
    {
        public string Name { get; set; }
    }
    
    private void HandleFirst(First model)
    {
        // Your existing code
    }
    
    private void HandleSecond(Second second)
    {
        // Your existing code
    }
    

    我的建议是使用一种控制器方法(您的客户想要的方式)来执行以下操作:

    1. 接受原始请求数据
    2. 解析 XML 并了解类型
    3. 通过反序列化 XML 创建模型
    4. 调用需要的方法

    这就是它的样子:

    public void Post(HttpRequestMessage request)
    {
        using (var xmlReader = XmlReader.Create(request.Content.ReadAsStreamAsync().Result))
        {
            xmlReader.MoveToContent();
            switch (xmlReader.Name)
            {
                case "First":
                    HandleFirst(Deserialize<First>(xmlReader));
                    break;
                case "Second":
                    HandleSecond(Deserialize<Second>(xmlReader));
                    break;
                default:
                    throw new NotSupportedException();
            }
        }
    }
    
    private T Deserialize<T>(XmlReader xmlReader)
    {
        var serializer = new XmlSerializer(typeof(T));
        return (T)serializer.Deserialize(xmlReader);
    }
    

    在这种情况下,您可以让您的路由配置非常简单。您只需要使用默认值即可。您还可以仔细查看 Web.API 2 中引入的 attribute routing

    【讨论】:

    • 非常感谢,这很有帮助。我以这种方式重新加工工具已经完成了一半,到目前为止一切都很顺利。欣赏!
    • 所以,我的一些类是嵌套的 xml 结构。当我执行 Deserialize(xmlReader) 时,作为根元素的直接子元素的任何元素都会在新的 NestedClass 对象中正确创建,但其下的任何元素及其子元素都为空。我已经为此纠结了好几个小时,无法弄清楚出了什么问题。
    • 我认为您需要提出新问题。添加用于序列化的 XML 示例和类。您可以在此处添加问题链接作为评论。
    • 终于发现了这个问题,这是我发布的 XML 中的一个问题,它掩盖了问题的真实性质。再次感谢,我已经开始运行了!
    猜你喜欢
    • 1970-01-01
    • 2022-10-01
    • 2013-11-13
    • 2019-04-10
    • 1970-01-01
    • 2019-03-04
    • 1970-01-01
    • 2012-07-21
    • 1970-01-01
    相关资源
    最近更新 更多