MVC使用查询字符串参数指定操作而不是" /"文件夹

时间:2018-01-11 19:00:14

标签: asp.net-mvc url-rewriting

在MVC6中,有没有办法将我的URL中的操作指定为查询字符串而不是路径?

E.G。 http://localhost/Index2http://localhost/Edit

这两个分别在我的控制器中触发Index2和Edit动作。但是我正在使用一个网站,我们只允许使用一个网址(长篇故事)...所以可以通过导航到相应的网址来触发完全相同的操作,例如

http://localhost/Default.aspx?action=Index2http://localhost/Default.aspx?action=Edit

我想我能做的就是在我的控制器中执行十几个动作功能,并将它们全部组合到Index动作中,并基于"动作"查询字符串参数,执行switch / case-select语句,并将每个原始action / subs复制到每个CASE下的各自块中。但是我希望可以做一些看起来更清洁的事情。

仅供参考:我不会将查询字符串用于其他任何事情。 POSTS

将我的所有价值观从行动转移到行动

2 个答案:

答案 0 :(得分:0)

是的,您使用Route装饰器,但不添加路由字符串,而是添加空字符串。例如:

namespace TestAPI.Controllers
{
    [RoutePrefix("api/testapi")] // eg: http://localhost/api/testapi?param1=foo&param2=bar
    public class TestAPIController : BaseAPIController
    {
        [HttpGet]
        [Route("")] // so that ASP MVC recognizes query strings
        public HttpResponseMessage Get()
        {

            // get the query parameters into a collection
            var queryparams = Request.GetQueryNameValuePairs().Select(q => new { q.Key, q.Value });


            // declare main keys value pairs
            string param1 = queryparams.Where(k => k.Key == "param1").Select(v => v.Value).FirstOrDefault();
            string param2 = queryparams.Where(k => k.Key == "param2").Select(v => v.Value).FirstOrDefault();

            // Do your stuff

            // Return a response


        }
    }
}

答案 1 :(得分:0)

通过继承RouteBase,这类事情很容易实现。它允许您使用几乎任何想要分析请求的逻辑,并根据请求中的内容将其指向特定的操作方法。

以下是使用http://localhost/Default.aspx?action=Index2http://localhost/Default.aspx?action=Edit

示例的路线
public class CustomRoute : RouteBase
{
    public override RouteData GetRouteData(HttpContextBase httpContext)
    {
        RouteData result = null;

        // Trim off the leading "/"
        var path = httpContext.Request.Path.Substring(1);

        if (path.Equals("Default.aspx", StringComparison.OrdinalIgnoreCase))
        {
            result = new RouteData(this, new MvcRouteHandler());

            result.Values["controller"] = "Home";
            result.Values["action"] = httpContext.Request.QueryString["action"] ?? "Index";
        }

        // IMPORTANT: Returning null tells the routing framework to try
        // the next registered route.
        return result;
    }

    public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
    {
        // Returning null skips this route.
        // Alternatively, implement a scheme to turn the values passed here
        // into a URL. This will be used by UrlHelper to build URLs in views.
        return null;
    }
}

可以像这样注册MVC。

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.Add(new CustomRoute());

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

请注意订单路线已注册非常重要。

如果您坚持使用filename.extension模式还有一件事 - 您必须配置IIS以允许请求到达MVC,因为默认情况下any URL with a . in it will throw a 404 not found error

<system.webServer>
  <handlers>
    <add name="ApiURIs-ISAPI-Integrated-4.0"
      path="/Default.aspx"
      verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS"
      type="System.Web.Handlers.TransferRequestHandler"
      preCondition="integratedMode,runtimeVersionv4.0" />
  </handlers>
</system.webServer>