【问题标题】:What is the correct model binding architecture for this situation?这种情况下正确的模型绑定架构是什么?
【发布时间】:2014-05-14 03:30:48
【问题描述】:

我正在用 WebApi 替换一些旧的 web 服务代码,我遇到了这样的情况:代码曾经做这样的事情:

If Request.QueryString("value") = 1 Then
    {do first action}
Else
    {do second action}
End If

每个动作完全不同,每个动作都有一组独立的other查询字符串参数。

在我的新版本中,我将其建模为:

Public Function FirstAction(model as FirstActionModel) As HttpResponseMessage

Public Function SecondAction(model as SecondActionModel) As HttpResponseMessage

问题是传入的请求将只调用/api/actions?actiontype=1&params.../api/actions?actiontype=2&params... 并且参数不同。

我希望能够将带有actiontype=1 的请求路由到FirstAction,并将actiontype=2 路由到SecondAction。但是我不能使用路由,因为重要的值在查询字符串中,而不是路径。

我该怎么做?

【问题讨论】:

  • 为什么不能像 "/api/actions/action1?params..." 这样的 url 添加动作类型?您需要将其作为 url 参数吗?
  • 我不控制调用者,所以无法将参数从查询字符串切换到路径。
  • 你可以做的是设置一个单独的动作来检查actiontype参数并相应地重定向/调用其他动作。
  • 我试过了,但是我失去了模型绑定。
  • 也许你可以使用IHttpActionSelector接口?在您的自定义实现中,您可以访问 HttpControllerContext 对象并检查其 Request 属性以访问 url 参数。

标签: asp.net asp.net-mvc asp.net-mvc-3 model-binding


【解决方案1】:

正如我在 cmets 中提到的,您可以使用 IHttpActionSelector 来实现这一点。但是您可以从默认实现继承而不是直接实现接口。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web;
using System.Web.Http.Controllers;

namespace WebApplication1
{
    public class CustomHttpActionSelector : ApiControllerActionSelector 
    {
        public override HttpActionDescriptor SelectAction(HttpControllerContext controllerContext)
        {
            var urlParam = HttpUtility.ParseQueryString(controllerContext.Request.RequestUri.Query);
            var actionType = urlParam["actiontype"];
            if (actionType == null)
                return base.SelectAction(controllerContext);

            MethodInfo methodInfo;
            if (actionType.ToString() == "1")
                methodInfo = controllerContext.ControllerDescriptor.ControllerType.GetMethod("Action1");
            else
                methodInfo = controllerContext.ControllerDescriptor.ControllerType.GetMethod("Action2");

            return new ReflectedHttpActionDescriptor(controllerContext.ControllerDescriptor, methodInfo);
        }
    }
}

要注册它,您需要在WebApiConfig.cs 文件中添加以下行:

config.Services.Replace(typeof(IHttpActionSelector), new CustomHttpActionSelector());

在您的控制器中,您可以添加两个方法 Action1 和 Action2:

    public string Action1(string param)
    {
        return "123";
    }

    public string Action2(string param)
    {
        return "345";
    }

【讨论】:

  • 哇,这完全奏效了!非常感谢您提供的信息和详细的代码示例,这使它变得容易多了。
猜你喜欢
  • 2011-03-10
  • 1970-01-01
  • 1970-01-01
  • 2015-06-17
  • 2018-05-03
  • 1970-01-01
  • 1970-01-01
  • 2013-04-23
  • 2011-03-26
相关资源
最近更新 更多