是否可以将GET和POST分离为单独的API控制器类型并使用相同的路径前缀访问它们?
这是我的控制器:
[RoutePrefix("api/Books")]
public class BooksWriteController : EventStoreApiController
{
[Route("")]
public void Post([FromBody] CommandWrapper commandWrapper){...}
}
[RoutePrefix("api/Books")]
public class BooksReadController : MongoDbApiController
{
[Route("")]
public Book[] Get() {...}
[Route("{id:int}")]
public Book Get(int id) {...}
}
Run Code Online (Sandbox Code Playgroud) 我有一个带有名为SlashBaseService的基本ApiController的webapi项目:
[RouteArea("uBase")]
public abstract class SlashBaseService : ApiController
{
}
Run Code Online (Sandbox Code Playgroud)
生成的dll用于WebForms项目中,因此我还有一个WebActivator类,其中包含以下代码来生成路由:
RouteTable.Routes.MapHttpAttributeRoutes(config =>
{
// Get all services inheriting from SlashBaseService
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
foreach (var type in assembly.GetTypes())
{
if (type.IsSubclassOf(typeof(SlashBaseService)))
{
// Scan assembly
config.ScanAssembly(assembly);
// Skip the remaining types in this assembly
break;
}
}
}
});
RouteTable.Routes.MapHttpRoute(
name: "DefaultBase",
routeTemplate: "base/{controller}/{id}",
defaults: new { id = RouteParameter.Optional });
Run Code Online (Sandbox Code Playgroud)
我还在一个单独的程序集中有一个testservice:
public class SampleSlashBaseService : SlashBaseService
{
[GET("TestOpenMethod")]
public string GetTestOpenMethod()
{
return "Hello anonymous!"; …Run Code Online (Sandbox Code Playgroud) 开源属性路由允许具有多个路由前缀.为什么ASP.NET Web API 2.0不允许具有多个RoutePrefix().
[RoutePrefix("api/v1/{abc}/Entity")]
[RoutePrefix("api/v1/{abc}/{xyz?}/Entity")]
public class MyApiController : ApiController
{
[Route("")]
public IHttpResult Get()
{
return Ok("Hello World");
}
}
Run Code Online (Sandbox Code Playgroud) 我已将项目从webapi升级到webapi2,现在正在使用属性路由.我有一个方法,我使用Url helper获取url.哪个是替换Url helper的最佳方法(因为这不适用于属性).
我的旧用法示例代码:
protected Uri GetLocationUri(object route, string routeName = WebApiConfig.RouteDefaultApi)
{
string uri = Url.Link(routeName, route);
return new Uri(uri);
}
Run Code Online (Sandbox Code Playgroud)
路线配置:
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: RouteDefaultApi,
routeTemplate: "{controller}/{id}/{action}",
defaults: new { id = RouteParameter.Optional, action = "Default" }
);
}
Run Code Online (Sandbox Code Playgroud)
用法:
Uri myUrl = GetLocationUri(route: new { action = "images", id = eventId });
Run Code Online (Sandbox Code Playgroud) 我想定义一条路线如下 -
[Route("clients/{*code}/{id:guid}/update")]
public ActionResult Update(string code, Guid id)
{
}
Run Code Online (Sandbox Code Playgroud)
代码将类似于"foo/bar/xyz".
不幸的是,开箱即用的MVC不支持路径定义中间的贪婪参数.
我有两个项目的解决方案.一个Web Api bootstap项目,另一个是类库.
类库包含一个带属性路由的ApiController.我将web api项目中的引用添加到类库中,并希望它能够正常工作.
Web api中的路由配置为:
config.MapHttpAttributeRoutes();
Run Code Online (Sandbox Code Playgroud)
控制器很简单,看起来像:
public class AlertApiController:ApiController
{
[Route("alert")]
[HttpGet]
public HttpResponseMessage GetAlert()
{
return Request.CreateResponse<string>(HttpStatusCode.OK, "alert");
}
}
Run Code Online (Sandbox Code Playgroud)
但是当我转到网址"/ alert"时我得到了404.
我在这里错过了什么?为什么我不能使用这个控制器?组装肯定是加载所以我不认为http://www.strathweb.com/2012/06/using-controllers-from-an-external-assembly-in-asp-net-web-api/是答案这里.
有任何想法吗?
c# asp.net-web-api attributerouting asp.net-web-api-routing asp.net-web-api2
当我尝试在LINQPad中使用Selfhosted WebAPI时,我只是得到了相同的错误,该类的控制器不存在.
我是否必须为WebAPI(控制器/类)创建单独的程序集,然后在我的查询中引用它们?
这是我正在使用的代码
#region namespaces
using AttributeRouting;
using AttributeRouting.Web.Http;
using AttributeRouting.Web.Http.SelfHost;
using System.Web.Http.SelfHost;
using System.Web.Http.Routing;
using System.Web.Http;
#endregion
public void Main()
{
var config = new HttpSelfHostConfiguration("http://192.168.0.196:8181/");
config.Routes.MapHttpAttributeRoutes(cfg =>
{
cfg.AddRoutesFromAssembly(Assembly.GetExecutingAssembly());
});
config.Routes.Cast<HttpRoute>().Dump();
AllObjects.Add(new UserQuery.PlayerObject { Type = 1, BaseAddress = "Hej" });
config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
using(HttpSelfHostServer server = new HttpSelfHostServer(config))
{
server.OpenAsync().Wait();
Console.WriteLine("Server open, press enter to quit");
Console.ReadLine();
server.CloseAsync();
}
}
public static List<PlayerObject> AllObjects = new List<PlayerObject>();
public class PlayerObject
{
public uint Type { get; …Run Code Online (Sandbox Code Playgroud) 当我在Admin区域内并使用属性路由映射我的路线时,它找不到视图,因为它不会查看实际区域视图文件夹,而只查看全局视图文件夹.
只有当我通过完整路径查看它然后才能显示它,否则它会抛出我的错误.
错误
The view 'Authorize' or its master was not found or no view engine supports the searched locations. The following locations were searched:
~/Views/Home/Authorize.aspx
~/Views/Home/Authorize.ascx
~/Views/Shared/Authorize.aspx
~/Views/Shared/Authorize.ascx
~/Views/Home/Authorize.cshtml
~/Views/Home/Authorize.vbhtml
~/Views/Shared/Authorize.cshtml
~/Views/Shared/Authorize.vbhtml
Run Code Online (Sandbox Code Playgroud)
码
[RoutePrefix("admin")]
public class HomeController : Controller
{
[Route]
public ActionResult Index()
{
return View("Authorize"); // Error
return View("~/Areas/Admin/Views/Home/Authorize.cshtml"); // Working
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,如果我禁用属性路由并切换回旧的路由,它将起作用.有什么方法可以解决这个问题,或者它是按照预期的方式工作的,我应该在所有方面应用完整的路径?
c# asp.net-mvc asp.net-mvc-areas attributerouting asp.net-mvc-5
...猜我是第一个问这个问题的人?
假设您有以下路由,每个路由在不同的控制器上声明:
[HttpGet, Route("sign-up/register", Order = 1)]
[HttpGet, Route("sign-up/{ticket}", Order = 2)]
Run Code Online (Sandbox Code Playgroud)
...你可以在MVC 5.0中使用除Order参数之外的相同代码执行此操作.但升级到MVC 5.1后,您会在问题标题中收到异常消息:
找到了与URL匹配的多种控制器类型.如果多个控制器上的属性路由与请求的URL匹配,则会发生这种情
那么新RouteAttribute.Order属性只是控制器级别?我知道在AttributeRouting.NET中你也可以这样做SitePrecedence.当所有操作都在同一个控制器中时,是否有获得上述路由的唯一方法?
更新
对不起,我应该提到这些路由是在MVC控制器上,而不是WebAPI.我不确定这会如何影响ApiControllers.
asp.net-mvc-controller attributerouting asp.net-mvc-5 asp.net-mvc-5.1
所以,我正在将区域从使用AreaRegistration切换到使用属性路由.我遇到的问题似乎是由路由加载到路由表中的顺序引起的.我通过最后加载有问题的路由解决了AreaRegistration中的问题,因此只有当所有其他路由不匹配时才会匹配该路由.使用属性路由,这似乎不可能.我在创建路由时有Order参数,但这不会影响路由表的方式,除非非常狭窄.
这是我在AreaRegistration文件中的路由:
context.MapRoute(
name: "ActionItems_home",
url: "ActionItems/{group}/{statuses}/{overdueOnly}",
defaults: new { controller = "Home", action = "Index", group = "All", statuses = "New,Open", overdueOnly = false },
namespaces: new string[] { "IssueTracker.Areas.ActionItems.Controllers" }
);
Run Code Online (Sandbox Code Playgroud)
现在,当我尝试将其切换到属性路由时,唯一接近工作的是:
[Route("", Order = 4)]
[Route("{group:regex(^(?!Item|DecisionLogs))?}", Order = 3)]
[Route("{group:regex(^(?!Item|DecisionLogs))}/{statuses=New,Open?}", Order = 2)]
[Route("{group:regex(^(?!Item|DecisionLogs))}/{statuses=New,Open}/{overdueOnly:bool=false?}", Order = 1)]
Run Code Online (Sandbox Code Playgroud)
请注意,我必须放入正则表达式,因为否则不会调用Item控制器 - 相反,我最终将字符串'Item'作为group参数传入.但正则表达式并不特别有助于URL的最终呈现方式.
我想为在URL,除非他们非默认被抑制的可选参数.我已经尝试将参数指定为可选参数,使用默认值,以及可选参数和默认值.他们似乎都没有真正做到这一点.
目前的解决方案,至少没有呈现一个查询字符串的URL,但它们包括可选参数,使事情难看.现在,我只是简单地将令人震惊的路线留在AreaRegistration文件中,而不是用[Route()]碎片装饰它们.