如何设置使用AttributeRouting时使用的默认控制器,而不是WebAPI使用的默认RouteConfiguration.即删除注释的代码部分,因为使用AttribteRouting时这是多余的
public class RouteConfig
{
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)
如果我评论上面的部分并尝试运行webapi应用程序,我会收到以下错误,因为没有定义默认的Home控制器/操作. HTTP错误403.14 - 禁止Web服务器配置为不列出此目录的内容.
如何通过归属控制器/操作的属性路由指定路由?
编辑:代码示例:
public class HomeController : Controller
{
[GET("")]
public ActionResult Index()
{
return View();
}
public ActionResult Help()
{
var explorer = GlobalConfiguration.Configuration.Services.GetApiExplorer();
return View(new ApiModel(explorer));
}
}
Run Code Online (Sandbox Code Playgroud) 我按照此处列出的想法创建了一些集成测试:http: //www.strathweb.com/2012/06/asp-net-web-api-integration-testing-with-in-memory-hosting/
当我尝试从手工制作的HttpConfiguration对象注册路由时,我收到以下错误:"路由模板'api/Contacts/{id}'的路径上的约束条目'inboundHttpMethod'必须具有字符串值或者是一种实现'IHttpRouteConstraint'的类型."
示例代码:控制器:
[RoutePrefix("api")]
public class ContactsController : ApiController
{
[GET("Contacts/{id}",RouteName="GetContactsById")]
public ContactDTO Get(int id)
{
return new ContactDTO{ ID =1, Name="test"};
}
}
}
Run Code Online (Sandbox Code Playgroud)
TestClass(MSTest):
[TestClass]
public class ContactsTest
{
private string _url = "http://myhost/api/";
private static HttpConfiguration config = null;
private static HttpServer server = null;
private HttpRequestMessage createRequest(string url, string mthv, HttpMethod method)
{
var request = new HttpRequestMessage();
request.RequestUri = new Uri(_url + url);
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(mthv));
request.Method = method;
return request;
}
private …Run Code Online (Sandbox Code Playgroud) 在较旧的MVC版本中,使用AttributeRouting库,我可以有多个路由并指定优先级,因此在生成URL时选择最合适的路径:
[Route("", ActionPrecedence = 1)]
[Route("city/{citySlug}", ActionPrecedence = 2)]
Run Code Online (Sandbox Code Playgroud)
在MVC 5中,ActionPrecedence属性上没有属性.在这种情况下,如何指定路由优先级?
我有一个控制器被调用HotelsController来插入和编辑酒店。
它具有以下设置(为简单起见删除了方法实现):
[RoutePrefix("{member_id:int}/hotels")]
public class HotelsController : ApplicationController
{
[Route("delete/{id:int}", Name = NamedRoutes.HotelDelete)]
public ActionResult Delete(int id)
{
}
[Route("new", Name = NamedRoutes.HotelNew)]
public ActionResult New()
{
}
[HttpPost]
[ValidateInput(false)]
public ActionResult New(HotelDataEntry hotel)
{
}
[Route("edit/{id:int}", Name = NamedRoutes.HotelEdit)]
public ActionResult Edit(int id)
{
}
[HttpPost]
[ValidateInput(false)]
public ActionResult Edit(HotelDataEntry hotel)
{
}
}
Run Code Online (Sandbox Code Playgroud)
如您所见,以下路由使用了属性路由:
以下路由不使用属性路由:
路由在 Global.asax.cs 中设置如下:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute("{resource}.aspx/{*pathInfo}");
routes.IgnoreRoute("{resource}.ashx/{*pathInfo}");
routes.IgnoreRoute("{resource}.asmx/{*pathInfo}");
routes.MapMvcAttributeRoutes();
routes.MapRoute(
Routen.Standard.ToString(), …Run Code Online (Sandbox Code Playgroud) c# asp.net asp.net-mvc-routing attributerouting asp.net-mvc-5
我不确定我尝试做的是否有效,因为我是C#/ ASP.NET/MVC堆栈的相对新手.
我在ModelController.cs中有这样的控制器动作
//Get
[Route("{vehiclemake}/models", Name = "NiceUrlForVehicleMakeLookup")]
public async Task<ActionResult> Index(string vehicleMake)
{
// Code removed for readaility
models = await db.VehicleModels.Where(make => make.VehicleMake.Make == vehicleMake).ToListAsync();
return View(models);
}
Run Code Online (Sandbox Code Playgroud)
在另一个名为VehicleMakeController.cs的控制器中,我有以下内容:
[HttpPost]
[Route("VehicleMake/AddNiceName/{makeId}")]
public ActionResult AddNiceName(VehicleMake vehicleMake, int? makeId)
{
if (ModelState.IsValid)
{
var vehicle = db.VehicleMakes.Find(makeId);
vehicle.MakeNiceName = vehicleMake.MakeNiceName;
db.SaveChanges();
return RedirectToRoute("NiceUrlForVehicleMakeLookup");
}
VehicleMake make = vehicleMake;
return View(make);
}
Run Code Online (Sandbox Code Playgroud)
我想做的是,当数据库更新成功时,我正在返回的地方,重定向到我定义的自定义路由(此部分: 返回RedirectToRoute("NiceUrlForVehicleMakeLookup");)
我正在使用的观点只是标准观点,这可以实现,还是我需要开始研究部分或区域?
提前致谢
c# asp.net-mvc asp.net-mvc-routing attributerouting asp.net-mvc-5
我想用这些URL到达Bikes控制器:
/bikes // (default path for US)
/ca/bikes // (path for Canada)
Run Code Online (Sandbox Code Playgroud)
实现这一目标的一种方法是每个Action使用多个Route Attributes:
[Route("bikes")]
[Route("{country}/bikes")]
public ActionResult Index()
Run Code Online (Sandbox Code Playgroud)
为了保持DRY,我更喜欢使用RoutePrefix,但不允许使用多个Route Prefix:
[RoutePrefix("bikes")]
[RoutePrefix("{country}/bikes")] // <-- Error: Duplicate 'RoutePrefix' attribute
public class BikesController : BaseController
[Route("")]
public ActionResult Index()
Run Code Online (Sandbox Code Playgroud)
我试过使用这个Route Prefix:
[RoutePrefix("{country}/bikes")]
public class BikesController : BaseController
Run Code Online (Sandbox Code Playgroud)
结果:/ ca / bikes工作,/自行车404s.
我试过让国家选择:
[RoutePrefix("{country?}/bikes")]
public class BikesController : BaseController
Run Code Online (Sandbox Code Playgroud)
相同的结果:/ ca / bikes工作,/自行车404s.
我试过给国家一个默认值:
[RoutePrefix("{country=us}/bikes")]
public class BikesController : BaseController
Run Code Online (Sandbox Code Playgroud)
相同的结果:/ ca / bikes工作,/自行车404s.
有没有其他方法可以使用属性路由实现我的目标? (是的,我知道我可以通过在RouteConfig.cs中注册路由来完成这些工作,但这不是我在这里寻找的东西).
我正在使用Microsoft.AspNet.Mvc 5.2.2.
仅供参考:这些是简化示例 - 实际代码具有{country}值的IRouteConstraint,例如:
[Route("{country:countrycode}/bikes")]
Run Code Online (Sandbox Code Playgroud) 我有以下两个控制器:
[RoutePrefix("/some-resources")
class CreationController : ApiController
{
[HttpPost, Route]
public ... CreateResource(CreateData input)
{
// ...
}
}
[RoutePrefix("/some-resources")
class DisplayController : ApiController
{
[HttpGet, Route]
public ... ListAllResources()
{
// ...
}
[HttpGet, Route("{publicKey:guid}"]
public ... ShowSingleResource(Guid publicKey)
{
// ...
}
}
Run Code Online (Sandbox Code Playgroud)
所有这三个行动实际上都有三条不同的路线:
GET /some-resourcesPOST /some-resourcesGET /some-resources/aaaaa-bbb-ccc-dddd如果我将它们放入单个控制器中,一切正常,但是如果我将它们分开(如上所示),WebApi会抛出以下异常:
找到了与URL匹配的多种控制器类型.如果多个控制器上的属性路由与请求的URL匹配,则会发生这种情
这个消息很明显.在寻找适合控制器/操作的候选者时,WebApi似乎没有考虑HTTP方法.
我怎样才能实现预期的行为?
更新:我已经深入研究了Web API内部,我明白这是默认情况下的工作方式.我的目标是分离代码和逻辑 - 在现实世界中,这些控制器具有不同的依赖关系并且更复杂一些.为了维护,可测试性,项目组织等,它们应该是不同的对象(SOLID和东西).
我认为我可以覆盖一些WebAPI服务(IControllerSelector等),但这似乎是一个有点风险和非标准的方法,这个简单的 - 和我假设 - 常见的情况.
c# asp.net-web-api attributerouting asp.net-web-api-routing asp.net-web-api2
我正在尝试改变这个基于约定的路线:
routes.MapRoute(
"MovieByReleaseDate",
"movies/released/{year}/{month}",
new { controller = "Movies", action = "ByReleasedDate" },
);
Run Code Online (Sandbox Code Playgroud)
属性路由:
[Route("movies/released/{year}/{month}")]
Run Code Online (Sandbox Code Playgroud)
但我不知道如何像第一种方式那样定义默认参数。
我在重构我们的支付处理操作方法(由我们的第 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)
但我不知道这是一个很好的解决方案,或者如何确定调用哪条路线?