C# 共享同一端点的多个API的正确路由配置

C# 共享同一端点的多个API的正确路由配置,c#,xml,routing,asp.net-web-api2,C#,Xml,Routing,Asp.net Web Api2,对于我希望接收的每种类型的XML post数据,我都有一个具有不同端点(不同控制器)的工作API。现在,客户希望我们对所有事情都使用相同的端点。唯一确定方向的是XML数据的内容——基本上是根元素的名称 我希望能够尽可能多地利用我现有的工作,因此我正在尝试添加一个新的控制器“路由器”,它正是这样做的——根据接收到的内容重定向到正确的路由。我试过一些东西,但似乎没有任何牵引力 如果有更好的方法来处理这件事,我会乐于听取 // WebApiConfig.cs confi

对于我希望接收的每种类型的XML post数据,我都有一个具有不同端点(不同控制器)的工作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路由中存在(明显的)冗余?其次,通过内容和路线识别流量的最佳方法是什么


谢谢你的帮助。我承认我在这里瞎了眼,所以我们非常感谢您的帮助

我认为在路由中使用一些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
}
我的建议是采用一种控制器方法(客户希望采用的方法)来完成以下工作:

  • 接受原始请求数据
  • 解析XML并了解其类型
  • 通过反序列化XML创建模型
  • 调用所需的方法
  • 这可能就是它的样子:

    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);
    }
    
    public void Post(HttpRequestMessage请求)
    {
    使用(var xmlReader=xmlReader.Create(request.Content.ReadAsStreamAsync().Result))
    {
    xmlReader.MoveToContent();
    开关(xmlReader.Name)
    {
    案例“第一”:
    HandleFirst(反序列化(xmlReader));
    打破
    案例“第二”:
    HandleSecond(反序列化(xmlReader));
    打破
    违约:
    抛出新的NotSupportedException();
    }
    }
    }
    私有T反序列化(XmlReader XmlReader)
    {
    var serializer=newxmlserializer(typeof(T));
    返回(T)序列化程序。反序列化(xmlReader);
    }
    

    在这种情况下,您可以使路由配置非常简单。您所需要的只是使用默认值。您还可以仔细查看Web.API 2中介绍的内容。

    非常感谢,这非常有帮助。我已经用这种方式完成了一半的重新加工,到目前为止,一切都很顺利。谢谢你!因此,我的一些类是嵌套的xml结构。当我执行反序列化(xmlReader)时,作为根元素的直接子元素的任何元素都会在新的NestedClass对象中正确创建,但低于该元素的所有元素及其子元素都为null。我已经纠结了几个小时,不知道出了什么问题。我想你们需要问一个新问题。添加用于序列化的XML示例和类。你可以在这里添加一个问题链接作为评论。最终发现了这个问题,我发布的XML中的一个问题掩盖了问题的本质。再次感谢,我已经准备好了!