MVC4 Web API路由冲突

时间:2012-06-23 00:57:21

标签: asp.net-mvc-routing asp.net-mvc-4 asp.net-web-api

问题

我们刚刚从MVC4 Web API Beta切换到RC,我们在服务中遇到了Multiple actions were found that match the request ...异常。

背景

我们在POST

中定义了两个ApiController个动作
public class MyModelController : ApiController
{
    ...
    // POST /mymodel
    public MyModel Post(MyModel model)
    {
       ...
    }

    // POST /mymodel/upload
    [ActionName("Upload")]
    public HttpResponseMessage UploadModelImage()
    {
        HttpRequestMessage request = Request;
        if (!request.Content.IsMimeMultipartContent())
        {
            throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.UnsupportedMediaType, request));
        }
       ...
    }
}

第一个操作(默认POST操作)用于从传递给服务的JSON创建新的MyModel对象。我们门户网站的用户可以选择在创建新MyModel对象时上传图像,在这种情况下,我们使用第二个Upload操作来保存文件并将新对象保留到数据库中。此操作将读取多部分请求内容,解析模型的属性并保存上载到CDN的图像。

由于我们切换到RC,上传操作(http://www.myapidomain.com/mymodel/upload)正常,但常规POST操作(http:// www .myapidomain.com / mymodel /)失败Multiple actions were found that match the request ...异常引用上面列出的两种方法作为冲突。

以下是我们的路线:

routes.MapHttpRoute(
    "Default", // route name
    "{controller}" // route template
    );

routes.MapHttpRoute(
    "OnlyId", // route name
    "{controller}/{id}", // route template
    new {}, // defaults
    new {controller = @"[^0-9]+", id = @"[0-9]+"} // constraints
    );

routes.MapHttpRoute(
    "OnlyAction", // route name
    "{controller}/{action}", // route template
    new {}, // defaults
    new {controller = @"[^0-9]+", action = ActionNameConstraint.Instance} // constraints
    );

routes.MapHttpRoute(
    "DependantAction", // route name
    "{controller}/{principalId}/{action}/{dependentId}", // route template
    new {dependentId = System.Web.Http.RouteParameter.Optional}, // defaults
    new {controller = @"[^0-9]+", action = ActionNameConstraint.Instance} // constraints
    );

ActionNameConstraint只是一个自定义约束,可确保{action}必须属于{controller}

问题

我已经尝试用不同的顺序搞乱路线,看看是否能解决这个问题而没有运气。我正在寻求以下任何解决方案的帮助:

  1. 我们路线中的潜在问题。
  2. content-type路由的替代解决方案。只需要为多部分表单帖子调用Upload操作。如果内容类型是JSON或XML,则应使用常规操作。我无法找到任何表明可以做到这一点的资源,但我希望有人考虑过这个。
  3. 用于从请求内容中读取文件流的模型绑定方法,因此我们不再需要单独的Upload操作

1 个答案:

答案 0 :(得分:0)

默认情况下,不可能在单个控制器中混合使用REST样式路由和RPC样式路由 - 这似乎是你想要做的。

在ASP.NET Web Stack的代码复制中存在一个未解决的问题,其中Web API源存在 - http://aspnetwebstack.codeplex.com/workitem/184

如果你想这样使用它,你需要将上传操作移动到一个单独的控制器,该控制器将以仅RPC方式调用。