在MVC6中,有没有办法将我的URL中的操作指定为查询字符串而不是路径?
E.G。 http://localhost/Index2和http://localhost/Edit
这两个分别在我的控制器中触发Index2和Edit动作。但是我正在使用一个网站,我们只允许使用一个网址(长篇故事)...所以可以通过导航到相应的网址来触发完全相同的操作,例如
http://localhost/Default.aspx?action=Index2和http://localhost/Default.aspx?action=Edit
我想我能做的就是在我的控制器中执行十几个动作功能,并将它们全部组合到Index动作中,并基于"动作"查询字符串参数,执行switch / case-select语句,并将每个原始action / subs复制到每个CASE下的各自块中。但是我希望可以做一些看起来更清洁的事情。
仅供参考:我不会将查询字符串用于其他任何事情。 POSTS
将我的所有价值观从行动转移到行动答案 0 :(得分:0)
是的,您使用Route
装饰器,但不添加路由字符串,而是添加空字符串。例如:
namespace TestAPI.Controllers
{
[RoutePrefix("api/testapi")] // eg: http://localhost/api/testapi?param1=foo¶m2=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=Index2和http://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>