在Asp.net MVC中,网址结构如下
http://example.com/ {controller}/{action}/{id}
对于每个"控制器",比如http://example.com/blog,都有一个BlogController.
但是我的{controller}部分的url不是预先决定的,但它是在运行时动态确定的,我如何创建一个"动态控制器",将任何东西映射到同一个控制器,然后根据该值确定什么去做?
与{action}相同,如果我的网址的{action}部分也是动态的,有没有办法对此方案进行编程?
鉴于以下webapiconfig;
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
Run Code Online (Sandbox Code Playgroud)
和这个控制器;
public class ProductsController : ApiController
{
Product[] _products = new Product[]
{
new Product { Id = 1, Name = "Tomato Soup", Category = "Groceries", Price = 1 },
new Product { Id = 2, Name = "Yo-yo", Category = "Toys", Price = 3.75M },
new Product { Id = 3, Name = "Hammer", Category = "Hardware", Price = 16.99M }
};
public IEnumerable<Product> GetAllProducts() …Run Code Online (Sandbox Code Playgroud) c# asp.net-mvc asp.net-mvc-routing wcf-web-api asp.net-web-api
我收到了一个用Asp.Net MVC4构建的原型应用程序.它目前正在使用NInject,ServiceLocator等全部替换默认控制器工厂.
问题是,通过替换默认控制器工厂,对JS文件的请求被视为对控制器和操作的合法请求.
因此,查看Visual Studio创建的默认模板,路由配置如下所示:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
Run Code Online (Sandbox Code Playgroud)
看了之后,我问自己:为什么"/Scripts/jquery.js"的请求不会被Asp.Net MVC解释?我的意思是,为什么它不认为"脚本"是一个控制器而"jquery.js"是一个动作?
因为如果禁用控制器工厂覆盖,项目可以工作,我只能假设默认工厂负责这种检查.这意味着"/ Scripts/jquery.js"确实传递给控制器工厂,这是我真正不知道的事情.
任何人都可以对此有所了解吗?
当覆盖控制器工厂以避免此类问题时,应该做什么样的处理?
在MVC中,我知道我们可以从get请求获取参数,如下所示:
请求:
http://www.example.com/method?param1=good¶m2=bad
Run Code Online (Sandbox Code Playgroud)
在控制器中
public ActionResult method(string param1, string param2)
{
....
}
Run Code Online (Sandbox Code Playgroud)
但在我的情况下,外部网站发送给我一个获取请求,如:
http://www.example.com/method?param.1=good¶m.2=bad
Run Code Online (Sandbox Code Playgroud)
在控制器中,当我尝试满足此请求时,如下所示:
public ActionResult method(string param.1, string param.2)
{
....
}
Run Code Online (Sandbox Code Playgroud)
由于变量名中的点,我得到构建错误.我怎样才能获得这些参数?不幸的是,我不能要求他们更改参数名称.
如果我有这样的动作:
public ActionResult DoStuff(List<string> stuff)
{
...
ViewData["stuff"] = stuff;
...
return View();
}
Run Code Online (Sandbox Code Playgroud)
我可以使用以下URL点击它:
http://mymvcapp.com/controller/DoStuff?stuff=hello&stuff=world&stuff=foo&stuff=bar
Run Code Online (Sandbox Code Playgroud)
但在我的ViewPage中,我有这个代码:
<%= Html.ActionLink("click here", "DoMoreStuff", "MoreStuffController", new { stuff = ViewData["stuff"] }, null) %>
Run Code Online (Sandbox Code Playgroud)
不幸的是,MVC不够聪明,无法识别该动作采用数组,并展开列表以形成正确的URL路由.相反,它只是在对象上执行.ToString(),它只列出了List中的数据类型.
当目标Action的参数之一是数组或列表时,有没有办法让Html.ActionLink生成正确的URL?
- 编辑 -
正如Josh在下面指出的那样,ViewData ["stuff"]只是一个对象.我试图简化问题,但引起了一个无关的错误!我实际上使用的是专用的ViewPage <T>,因此我有一个紧密耦合的类型感知模型.ActionLink实际上看起来像:
<%= Html.ActionLink("click here", "DoMoreStuff", "MoreStuffController", new { stuff = ViewData.Model.Stuff }, null) %>
Run Code Online (Sandbox Code Playgroud)
其中ViewData.Model.Stuff被键入为List
这是我在Global.asax中的路线
routes.MapRoute("PizzaGet", "pizza/{pizzaKey}", new { controller = "Pizza", action = "GetPizzaById" });
routes.MapRoute("DeletePizza", "pizza/{pizzaKey}", new { controller = "Pizza", action = "DeletePizza" });
Run Code Online (Sandbox Code Playgroud)
这是我的控制器方法
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult GetPizzaById(long pizzaKey)
[AcceptVerbs(HttpVerbs.Delete)]
public ActionResult DeletePizza(long pizzaKey)
Run Code Online (Sandbox Code Playgroud)
当我做一个GET它返回对象,但当我做一个删除我得到一个404.看起来这应该工作,但事实并非如此.
如果我切换两条路线然后我可以做DELETE,但在GET上获得404.
现在这真的很美.谢谢
routes.MapRoute("Pizza-GET","pizza/{pizzaKey}",
new { controller = "Pizza", action = "GetPizza"},
new { httpMethod = new HttpMethodConstraint(new string[]{"GET"})});
routes.MapRoute("Pizza-UPDATE", "pizza/{pizzaKey}",
new { controller = "Pizza", action = "UpdatePizza" },
new { httpMethod = new HttpMethodConstraint(new string[] { "PUT" }) });
routes.MapRoute("Pizza-DELETE", "pizza/{pizzaKey}",
new { controller …Run Code Online (Sandbox Code Playgroud) 我正在尝试在登录表单中实现"记住我"功能.我使用ASP.NET MVC作为我的Web应用程序.我设法让cookie的东西工作,但我没有自动登录用户,以防他/她之前检查记住我复选框.我知道问题是什么,但我不知道如何解决它.
在我的HomeController中,我有以下内容:
private LoginViewModel CheckLoginCookie()
{
if (!string.IsNullOrEmpty(_appCookies.Email) && !string.IsNullOrEmpty(_appCookies.Password))
{
var login = new LoginViewModel
{
Email = _appCookies.Email,
Password = _appCookies.Password
};
return login;
}
return null;
}
public ActionResult Index()
{
var login = CheckLoginCookie();
if (login != null)
return RedirectToAction("Login", "User", login);
var viewModel = new HomeIndexViewModel
{
IntroText =
"Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, …Run Code Online (Sandbox Code Playgroud) 我正在使用ASP.Net MVC.这是来自名为Course的控制器的代码片段:
public ActionResult List(int id)
{
var viewmodel.ShowUrl = Url.Action("Show", "Course");
...
}
public ActionResult Show(int id)
{
...
}
Run Code Online (Sandbox Code Playgroud)
viewmodel.ShowUrl获取"id"参数的值.所以viewmodel.ShowUrl变为"/ Course/Show/151"(id的值为151); 我希望能够根据用户交互在客户端上设置id部分.我希望viewmodel.ShowUrl的值为"/ Course/Show".
这对我来说似乎是个错误.我没告诉Url.Action包含id值.它正在独立完成.如果我想设置id值,那么我会做这样的事情:
var viewmodel.ShowUrl = Url.Action("Show", "Course", new {id = somevalue});
Run Code Online (Sandbox Code Playgroud)
那么,你如何阻止MVC添加id值?我可以将viewmodel.ShowUrl硬编码为"/ Course/Show",但这似乎是一个kludgy解决方案.谢谢.
我有一个称为控制器Dashboard3个操作:Summary,Details,和Status,其中没有一个采取的ID或任何其他参数.我希望URL /Dashboard路由到控制器的Summary操作,但是我无法找出添加路由的正确方法.在,我有以下内容:Dashboard/Dashboard/SummaryGlobal.asax.cs
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new {controller = "Home", action = "Index", id = UrlParameter.Optional} // Parameter defaults
);
routes.MapRoute(
"/Dashboard",
"Dashboard",
new { controller = "Dashboard", action = "Summary" }
);
Run Code Online (Sandbox Code Playgroud)
对于第二部分,我也尝试过:
routes.MapRoute(
"/Dashboard",
"{controller}",
new { controller = "Dashboard", action = "Summary" }
);
Run Code Online (Sandbox Code Playgroud)
和
routes.MapRoute(
"/Dashboard",
"{controller}",
new { action = "Summary" }
);
Run Code Online (Sandbox Code Playgroud)
但是在尝试访问时我总是得到404 /Dashboard …
在MVC-5中,我可以routetable通过访问来编辑初始启动之后RouteTable.Routes.我希望在MVC-6中也这样做,这样我就可以在运行时添加/删除路由(对CMS很有用).
在MVC-5中执行此操作的代码是:
using (RouteTable.Routes.GetWriteLock())
{
RouteTable.Routes.Clear();
RouteTable.Routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
RouteTable.Routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
Run Code Online (Sandbox Code Playgroud)
但我RouteTable.Routes在MVC-6中找不到或类似的东西.知道如何在运行时更改路径集合吗?
我想在CMS中创建页面时使用此原则添加额外的URL.
如果你有一个类:
public class Page
{
public int Id { get; set; }
public string Url { get; set; }
public string Html { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
和控制器像:
public class CmsController : Controller
{
public ActionResult Index(int id)
{
var page = DbContext.Pages.Single(p => p.Id …Run Code Online (Sandbox Code Playgroud) asp.net-mvc ×7
c# ×5
routes ×2
arrays ×1
asp.net ×1
asp.net-core ×1
get ×1
list ×1
parameters ×1
remember-me ×1
url ×1
url.action ×1
wcf-web-api ×1