根据文章" ASP.NET MVC5中的新功能 ",您必须将此添加到RegisterRoutes()方法才能使用属性路由:
routes.MapMvcAttributeRoutes();
Run Code Online (Sandbox Code Playgroud)
...所以现在的方法是:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
Run Code Online (Sandbox Code Playgroud)
我没有那个额外的/中间调用,我的属性路由一直在工作.
那么,如果有的话,为我做什么呢?
c# asp.net-web-api attributerouting asp.net-web-api-routing asp.net-mvc-5
我已经定义了属性路由,它将两个参数作为datetime
[Route("{controller}/{action}/{*startDate:datetime}/{*endDate:datetime}")]
public bool OverView(DateTime startDate,DateTime endDate)
{
var dt = startDate.ToString("yyyy-MM-dd");
return true;
}
Run Code Online (Sandbox Code Playgroud)
但不确定,它是如何可能的.属性路由适用于单个参数,但不确定它如何适用于2个参数.此外,很难知道如何将两个参数与网址区分开来
单一的param,工作正常
http://domain.com/Home/overview/2014/02/01
两个参数的网址是什么?我尝试了下面的一个,但有一个例外
http://domain.com/Home/overview/2014/02/01/2014/02/04
Exception
A catch-all parameter can only appear as the last segment of the route URL.
Parameter name: routeUrl
Run Code Online (Sandbox Code Playgroud) 我在我的控制器中使用MVC5的属性路由.
有没有办法控制控制器之间的属性路由优先级?
考虑以下
[Route("home/{action=index}/{username?}")]
public class HomeController : Controller
{
[Route("home/index/{username?}", Order = 1)]
[Route("home/{username?}", Order = 2)]
[Route("{username?}", Order = 3)]
public ActionResult Index()
{
// ... bunch of stuff
}
}
Run Code Online (Sandbox Code Playgroud)
根据上面的代码,HomeController.Index()应使用以下请求调用action方法:
第二控制器:
[Authorize(Roles = "Member")]
[Route("profile/{action=index}")]
public class ProfileController : Controller
{
[Route("profile")]
public ActionResult Index()
{
}
}
Run Code Online (Sandbox Code Playgroud)
本ProfileController.Index()应使用下面的请求来调用.
从示例中,如果我发送domain/profile了url,则会引发歧义异常.似乎domain/{username}和之间存在歧义domain/profile …
我想根据Accept标头中请求的媒体类型选择我的Controller的Action.
例如,我有一个名为subject的资源.其分配的路线是:
GET /臣//subjectId:int}
通常,浏览器正在请求text/html,这很好.默认的Media Formatter可以处理这个问题.
现在,我有一个自定义逻辑,我希望在访问同一路径时使用一个接受标头指定application/pdf为接受的媒体类型.
我可以创建一个自定义媒体格式化程序,但是,据我所知,这意味着任何设置为Accept标头的请求路径application/pdf也将通过此媒体格式化程序运行.这是无法接受的.
在Java中,有一个名为的注释@Produces:
@Produces注释用于指定资源可以生成并发送回客户端的MIME媒体类型或表示.如果在类级别应用@Produces,则资源中的所有方法都可以默认生成指定的MIME类型.如果在方法级别应用,则注释将覆盖在类级别应用的任何@Produces注释.
这将允许我执行以下操作:
namespace MyNamespace
{
[RoutePrefix("subjects")]
public class SubjectsController : Controller
{
[Route("{subjectId:int}")]
[HttpGet]
public ActionResult GetSubject(int subjectId)
{
}
[Route("{subjectId:int}")]
[HttpGet]
[Produces("application/pdf")]
public ActionResult GetSubjectAsPdf(int subjectId)
{
//Run my custom logic here to generate a PDF.
}
}
}
Run Code Online (Sandbox Code Playgroud)
当然,我找不到.NET中的Produces属性,所以这不起作用.我也找不到类似的属性.
我当然可以手动检查动作正文中的标题,并将其重定向到另一个动作,但这似乎充其量只是hackish.
.NET 4.5中是否有一种机制可以用来解决我忽略或丢失的问题?
(我正在使用NuGet存储库中的MVC 5.2.2)
我在重构我们的支付处理操作方法(由我们的第 3 方在线支付提供商调用)时遇到问题。我们有一个产品控制器,在类级别具有[Authorize]和[RoutePrefix("products")]属性,以及操作方法,包括以下内容:
Product(string contractNumber)具有路由属性[Route("{productCode}")]MakePayment(string productCode, PaymentAmountType? amountSelection, decimal? amountValue)具有路由属性[Route("{productCode}")]和[HttpPost]属性ProcessPayment(string productCode, string result)具有路由属性[Route("{productCode}")]由于我们的支付网关需要能够ProcessPayment在访问者重定向到同一 URL 之前调用我们的操作,因此我们必须将其重构为不带该[Authorize]属性的单独控制器。(我们已经有防止重复记入付款的机制。)
在此重构之前,MakePayment操作方法在以下调用中正确地制定了正确的返回 URL Url.Action():
var rawCallbackUrl = Url.Action("ProcessPayment", new { productCode = productCode });
Run Code Online (Sandbox Code Playgroud)
现在,操作ProcessPayment方法已从产品控制器移出并移入新控制器 ,ExternalCallbackController该控制器没有属性(更不用说[Authorize]),以避免将 HTTP 401 响应返回给支付提供商。
现在,路线属性 onProcessPayment是[Route("order-processing/{productCode}/process-payment")]为了避免与RoutePrefix产品控制器上的 发生冲突。对此更新的操作方法的所有引用均已更新以指定ExternalCallbackController.
手动浏览到该 URL 会导致内部设置的断点ProcessPayment被命中,因此该路由显然可以成功运行。 …
我目前正在开发一个小型的ASP.NET MVC项目.该项目几个月前发布.但是现在应该针对可用性和SEO原因实施更改.我决定使用属性路由来创建干净的URL.
目前,产品页面通过以下方式调用:
hostname.tld /控制器/ GetArticle/1234
我定义了一个像这样的新Route:
[Route("Shop/Article/{id:int}/{title?}", Name = "GetArticle", Order = 0)]
public ActionResult GetArticle(int id, string title = null) {
// Logic
}
Run Code Online (Sandbox Code Playgroud)
一切正常,但由于向后兼容性和SEO原因,旧的路线应该仍然可用.并使用HTTP状态代码301重定向到新URL.
我听说可以为一个动作分配多个路径,如下所示:
[Route("Shop/Article/{id:int}/{title?}", Name = "GetArticle", Order = 0)]
[Route("Controller/GetArticle/{id:int}", Name = "GetArticle_Old", Order = 1)]
public ActionResult GetArticle(int id, string title = null) {
// Logic
}
Run Code Online (Sandbox Code Playgroud)
但我不知道这是一个很好的解决方案,或者如何确定调用哪条路线?
我想知道如果我们RoutePrefix在web api控制器中使用与控制器实际名称不同的名称.它会起作用吗?
就我而言
[RouterPrefix("quotation")]
public class SaleOrderController : ApiController { ... }
Run Code Online (Sandbox Code Playgroud)
如果我们RoutePrefix如上所述定义,我们无法访问它,/quotation但我们可以使用它来访问它saleorder.
那么RoutePrefix我做错了什么或者我做错了什么?
c# asp.net-mvc asp.net-mvc-routing asp.net-web-api attributerouting
我试图强制路由参数,guid但低于错误
"执行函数时出现异常:GetUser - >发生了一个或多个错误. - >异常绑定参数'req' - >从'System.String'到'System.Guid'的无效转换."
public static async Task<HttpResponseMessage> Run(
[HttpTrigger(AuthorizationLevel.Admin, "get", Route = "GetUser/{userId:guid}")] HttpRequestMessage req,
Guid userId, ILogger log)
{
}
Run Code Online (Sandbox Code Playgroud)
我的要求是 http://localhost:7071/api/GetUser/246fb962-604d-4699-9443-fa3fa840e9eb/
我错过了什么吗?我们不能强制路由参数是guid吗?
在ASP.NET Core(v 2.1.5)中,您可以创建控制器,而无需从Controller类继承(如您所知).如果你这样做,你必须RouteAttribute用来定义你的路线.但是,如果我们可以将隐式路由(而不是属性路由)与ApiController属性一起使用,我感兴趣.示例:具有此隐式路由Startup.cs:
app.UseMvc(routeBuilder =>
{
routeBuilder.MapRoute("api_default", "{controller}/{action}/{id?}");
});
Run Code Online (Sandbox Code Playgroud)
还有这个 Cotroller
[ApiController]
public class ValuesController
{
[HttpGet]
public string Get(int id) => id.ToString();
}
Run Code Online (Sandbox Code Playgroud)
将抛出此异常:
InvalidOperationException:Action'TestApi.Controllers.ValuesController.Get'没有属性路由.使用ApiControllerAttribute注释的控制器上的操作方法必须是属性路由.
有没有办法避免异常?
c# attributerouting .net-core asp.net-core asp.net-core-webapi
我在我的 ASP.NET Core 3.1 应用程序 (MVC) 中使用了区域。
现在我希望所有没有明确区域的请求默认转到“主要”区域。这是我目前设置端点路由的方式:
app.UseEndpoints(endpoints =>
{
// 1
endpoints.MapControllerRoute(
name: "area",
pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}");
// 2
endpoints.MapAreaControllerRoute(
name: "default",
areaName: "Main",
pattern: "{area=Main}/{controller=Home}/{action=Index}/{id?}");
});
Run Code Online (Sandbox Code Playgroud)
我的目标是:
如果请求 URL 包含现有区域名称,请使用路由 [1]。如果没有区域名称,则使用路由[2](默认为“Main”区域)。
我的问题:
如何设置默认区域?
好的,解决了。最后,这对我有用:
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "area:exists}/{controller=Home}/{action=Index}/{id?}");
endpoints.MapAreaControllerRoute(
name: "default",
areaName: "Main",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
Run Code Online (Sandbox Code Playgroud) attributerouting ×10
c# ×5
asp.net-mvc ×4
asp.net-core ×2
.net-4.5 ×1
.net-core ×1
asp.net ×1
azure ×1
routes ×1
url-routing ×1