标签: attributerouting

使用属性路由时查询字符串不起作用

我正在使用System.Web.Http.RouteAttributeSystem.Web.Http.RoutePrefixAttribute为我的Web API 2应用程序启用更干净的URL.对于我的大部分请求,我可以使用路由(例如Controller/param1/param2)或者我可以使用查询字符串(例如Controller?param1=bob&param2=mary).

不幸的是,对于我的一个控制器(并且只有一个),这会失败.这是我的控制器:

[RoutePrefix("1/Names")]
public class NamesController : ApiController
{

    [HttpGet]
    [Route("{name}/{sport}/{drink}")]
    public List<int> Get(string name, string sport, string drink)
    {
        // Code removed...
    }

    [HttpGet]
    [Route("{name}/{drink}")]
    public List<int> Get(string name, string drink)
    {
        // Code removed...
    }
}
Run Code Online (Sandbox Code Playgroud)

当我使用路由请求时,两者都可以正常工作.但是,如果我使用查询字符串,它会失败,告诉我该路径不存在.

我已经尝试将以下内容添加到我的WebApiConfig.cs类' Register(HttpConfiguration config)函数(在默认路由之前和之后),但它没有做任何事情:

config.Routes.MapHttpRoute(
name: "NameRoute",
routeTemplate: "{verId}/Names/{name}/{sport}/{drink}",
defaults: new { name = RouteParameter.Optional, sport = RouteParameter.Optional, drink = RouteParameter.Optional },
constraints: new { verId = @"\d+" }); …
Run Code Online (Sandbox Code Playgroud)

c# query-string asp.net-web-api attributerouting asp.net-web-api-routing

60
推荐指数
6
解决办法
7万
查看次数

ASP.NET Web API中带有可选参数的属性路由

我正在尝试使用Web API 2属性路由来设置自定义API.我的路由工作,我的函数被调用,但由于某种原因,我需要传入我的第一个参数,以便一切正常工作.以下是我要支持的网址:

http://mysite/api/servicename/parameter1
http://mysite/api/servicename/parameter1?parameter2=value2
http://mysite/api/servicename/parameter1?parameter2=value2&parameter3=value3
http://mysite/api/servicename/parameter1?parameter2=value2&parameter3=value3&p4=v4
Run Code Online (Sandbox Code Playgroud)

最后3个URL可以工作,但第一个说"在控制器名称上没有找到与请求相匹配的操作".

我的控制器看起来像这样:

public class MyServiceController : ApiController
{
    [Route("api/servicename/{parameter1}")]
    [HttpGet]
    public async Task<ReturnType> Get(string parameter1, DateTime? parameter2, string parameter3 = "", string p4 = "")
    {
        // process
    }
}
Run Code Online (Sandbox Code Playgroud)

c# asp.net-web-api attributerouting asp.net-web-api-routing

40
推荐指数
1
解决办法
3万
查看次数

MVC属性路由不起作用

我对MVC框架比较陌生,但我确实有一个功能正常的Web项目,其API控制器使用了AttributeRouting(NuGet包) - 但是,我正在启动另一个项目,它只是不想遵循我放入的路由地点.

控制器:

public class BlazrController : ApiController
{
    private readonly BlazrDBContext dbContext = null;
    private readonly IAuthProvider authProvider = null;

    public const String HEADER_APIKEY = "apikey";
    public const String HEADER_USERNAME = "username";

    private Boolean CheckSession()
    {
        IEnumerable<String> tmp = null;
        List<String> apiKey = null;
        List<String> userName = null;

        if (!Request.Headers.TryGetValues(HEADER_APIKEY, out tmp)) return false;
        apiKey = tmp.ToList();

        if (!Request.Headers.TryGetValues(HEADER_USERNAME, out tmp)) return false;
        userName = tmp.ToList();

        for (int i = 0; i < Math.Min(apiKey.Count(), userName.Count()); i++)
            if (!authProvider.IsValidKey(userName[i], …
Run Code Online (Sandbox Code Playgroud)

c# asp.net-mvc asp.net-web-api attributerouting

38
推荐指数
4
解决办法
3万
查看次数

CreatedAtRoute路由到不同的控制器

我正在使用属性路由创建一个新的webapi来创建嵌套路由,如下所示:

    // PUT: api/Channels/5/Messages
    [ResponseType(typeof(void))]
    [Route("api/channels/{id}/messages")]
    public async Task<IHttpActionResult> PostChannelMessage(int id, Message message)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        if (id != message.ChannelId)
        {
            return BadRequest();
        }

        db.Messages.Add(message);
        await db.SaveChangesAsync();

        return CreatedAtRoute("DefaultApi", new { id = message.Id }, message);
    }
Run Code Online (Sandbox Code Playgroud)

但是我想返回一个没有嵌套的路由,即:

/api/Messages/{id}
Run Code Online (Sandbox Code Playgroud)

这是在消息控制器上定义的.但是,上面的CreatedAtRoute调用不解析此路线而是抛出.我做错了什么,或者它不支持路由到不同的api控制器?我试图点击的路线不是属性路线,只是默认路线.

例外是:

消息:"发生了错误." ExceptionMessage:"UrlHelper.Link不能返回null." ExceptionType:"System.InvalidOperationException"StackTrace:"at System.Web.Http.Results.CreatedAtRouteNegotiatedContentResult 1.Execute() at System.Web.Http.Results.CreatedAtRouteNegotiatedContentResult1.ExecuteAsync(CancellationToken cancellationToken)at System.Web.Http.Controllers.ApiControllerActionInvoker.d__0.MoveNext()---堆栈跟踪结束从抛出异常的上一个位置---在System.Runtime.Compiler服务的System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务),System.Runtime.CompilerServices.TaskAwaiter的System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)1.GetResult() at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter1.GetResult( …

c# asp.net-web-api attributerouting asp.net-web-api-routing

36
推荐指数
2
解决办法
2万
查看次数

MapMvcAttributeRoutes:在应用程序的启动前初始化阶段,无法调用此方法

在使用ASP MVC V5和属性路由的解决方案中,我在测试项目中进行了非常简单的测试.属性路由和MapMvcAttributeRoutes方法是ASP MVC 5的一部分.

[Test]
public void HasRoutesInTable()
{
    var routes = new RouteCollection();
    routes.MapMvcAttributeRoutes();
    Assert.That(routes.Count, Is.GreaterThan(0));
}
Run Code Online (Sandbox Code Playgroud)

这导致:

System.InvalidOperationException : 
This method cannot be called during the applications pre-start initialization phase.
Run Code Online (Sandbox Code Playgroud)

此错误消息的大多数答案涉及在web.config文件中配置成员资格提供程序.该项目既没有成员资格提供者也没有web.config文件,因此出于某种其他原因似乎发生了错误.如何将代码移出此"预启动"状态以便测试可以运行?

调用ApiController后的工作属性的等效代码HttpConfiguration.EnsureInitialized().

asp.net-mvc unit-testing attributerouting asp.net-mvc-5

35
推荐指数
4
解决办法
1万
查看次数

在URL中使用斜杠"/"路由参数

我知道您可以在route属性中应用通配符以允许/例如日期输入:

[Route("orders/{*orderdate}")]
Run Code Online (Sandbox Code Playgroud)

通配符的问题仅适用于URI中的最后一个参数.如果要拥有以下URI,如何解决问题:

[Route("orders/{orderdate}/customers")]
Run Code Online (Sandbox Code Playgroud)

更新:

我知道通过重构代码来解决问题的选择很少,所以请不要提供类似的解决方案:

  1. 将路径模板更改为 [Route("orders/customers/{orderdate}")]
  2. 将日期更改为其他格式(例如"dd-mm-yyyy")

c# url asp.net-web-api attributerouting asp.net-web-api-routing

35
推荐指数
2
解决办法
3万
查看次数

ASP.NET帮助页面默认主页?

我想转到http://myserver并能够将帮助页面作为默认主页,因此访客http://myserver应首先看到的是帮助页面.

我有一个默认路由设置如下:

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)

然后我的帮助页面区域注册设置如下:

public override void RegisterArea(AreaRegistrationContext context)
{
    context.MapRoute(
        "HelpPage_Default",
        "doc/{action}/{apiId}",
        new { controller = "Help", action = "Index", apiId = UrlParameter.Optional });

    HelpPageConfig.Register(GlobalConfiguration.Configuration);
}
Run Code Online (Sandbox Code Playgroud)

当我改变RouteConfig时controller,"Help"我得到:

未找到视图"索引"或其主数据或视图引擎不支持搜索的位置

当我将帮助页面路由更改为"{controller}/{action}/{apiId}"我的AttributeRoutes时停止工作.

是否有一些简单的方法来使ASP.NET帮助页面成为默认主页?

asp.net-mvc-areas asp.net-mvc-4 attributerouting asp.net-web-api-helppages

27
推荐指数
2
解决办法
1万
查看次数

组合密钥资源REST服务

我在工作中遇到了一个问题,我无法找到有关在RESTful Web服务中针对主键是其他资源ID的组合的资源执行CRUD操作的通常标准或实践的信息.我们使用MVC WebApi来创建控制器.例如,我们有三个表:

  • Product:PK = ProductId
  • Part:PK = PartId
  • ProductPartAssoc:PK =(ProductId,PartId)

产品可以包含许多部件,而部件可以是许多产品的组件.关联表还包含与关联本身相关的其他信息,而不是可编辑的信息.

我们有ProductsControllerPartsController类使用定义为的路由模板处理通常的GET/PUT/POST/DELETE操作:{controller}/{id}/{action}以便以下IRI工作:

  • GET,POST /api/Products- 返回所有产品,创建新产品
  • GET,PUT,DELETE /api/Products/1- 检索/更新/删除产品1
  • GET,POST /api/Parts- 返回所有部件,创建一个新部件
  • GET,PUT,DELETE /api/Parts/2- 检索/更新/删除第2部分
  • 获取 /api/Products/1/Parts- 获取产品1的所有部件
  • 获取 /api/Parts/2/Products- 获取第2部分为组件的所有产品

我遇到问题的方法是如何为ProductPartAssoc资源定义路径模板.获取关联数据的路由模板和IRI应该是什么样的?坚持惯例,我希望如下:

  • GET,POST /api/ProductPartAssoc- 返回所有关联,创建关联
  • GET,PUT,DELETE /api/ProductPartAssoc/[1,2]- 检索/更新/删除产品1和第2部分之间的关​​联

我的同事发现这在美学上令人不悦,并且似乎认为最好不要有一个ProductPartAssocController类,而是添加其他方法ProductsController来管理关联数据:

  • GET,PUT,DELETE /api/Products/1/Parts/2- 获取产品1和第2部分之间关联的数据,而不是第2部分作为第1部分成员的数据,这通常是基于其他示例的情况,例如/Book/5/Chapter/3我在其他地方看到的情况.
  • POST没有任何线索,他们期望IRI看起来像什么.不幸的是,他们是决策者.

在一天结束时,我想我要求的是验证,或者我可以指出的方向,并说"看,这是其他人做的."

处理复合键识别的资源的典型做法是什么?

rest composite-key asp.net-web-api attributerouting asp.net-web-api-routing

23
推荐指数
1
解决办法
8764
查看次数

RoutePrefix与路由

据我所知,这RoutePrefix不会自己添加到路由表的路由.在您的操作上,您需要Route声明一个属性.我很难找到一个权威的博客/ msdn页面/一些东西,说明为什么defalut RoutePrefix不会添加到路由表的路由.

有没有人有一个确实含有此权威的权威帖子,如果是这样,你会告诉我它是谁.非常感谢你.

编辑 以澄清我的问题

什么都不行

[RoutePrefix("api/Steve")]
public class SteveController : ApiController
{
    public int get(){return 1000000;}
}
Run Code Online (Sandbox Code Playgroud)

作品

[RoutePrefix("api/Steve")]
public class SteveController : ApiController
{
    [Route("")]
    public int get(){return 1000000;}
}
Run Code Online (Sandbox Code Playgroud)

上面的场景是有效的,因为我们明确表示对该路径的get操作SteveController有一条空路线.一旦我们这样做,路线就会被添加到RouteTable

第一种情况不起作用,因为只是使用RoutePrefix不会向路由表添加任何内容.RoutePrefix本身不会产生路线.这似乎是常识,我想知道一个说明原因的来源.优先受尊敬的社区成员,即Jon Skeet或Microsoft团队成员.

c# asp.net-web-api attributerouting asp.net-web-api-routing asp.net-web-api2

23
推荐指数
2
解决办法
4万
查看次数

如何在不使用AttributeRouting在Route属性上指定名称的情况下生成WebApi2 URL?

我已将ASP.NET MVC5应用程序配置为使用AttributeRouting进行WebApi:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.MapHttpAttributeRoutes();
    }
}
Run Code Online (Sandbox Code Playgroud)

我有ApiController如下:

[RoutePrefix("api/v1/subjects")]
public class SubjectsController : ApiController
{
    [Route("search")]
    [HttpPost]
    public SearchResultsViewModel Search(SearchCriteriaViewModel criteria)
    {
        //...
    }
}
Run Code Online (Sandbox Code Playgroud)

我想为我的WebApi控制器操作生成一个URL,而不必指定显式路由名称.

根据CodePlex上的这个页面,所有MVC路由都有一个不同的名称,即使它没有指定.

如果没有指定的路由名称,Web API将生成默认路由名称.如果特定控制器上的操作名称只有一个属性路由,则路径名称将采用"ControllerName.ActionName"形式.如果该控制器上有多个具有相同操作名称的属性,则会添加后缀以区分路径:"Customer.Get1","Customer.Get2".

在ASP.NET上,它没有确切地说明默认命名约定是什么,但它确实表明每个路由都有一个名称.

在Web API中,每个路由都有一个名称.路由名称对于生成链接非常有用,因此您可以在HTTP响应中包含链接.

基于这些资源,以及StackOverflow用户Karhgath回答,我被认为以下会产生一个指向我的WebApi路由的URL:

@(Url.RouteUrl("Subjects.Search"))
Run Code Online (Sandbox Code Playgroud)

但是,这会产生错误:

在路径集合中找不到名为"Subjects.Search"的路径.

我已经根据我在StackOverflow上找到的其他答案尝试了一些其他变体,没有成功.

@(Url.Action("Search", "Subjects", new { httproute = "" }))

@(Url.HttpRouteUrl("Search.Subjects", new {}))
Run Code Online (Sandbox Code Playgroud)

实际上,即使在属性中提供Route名称,也只能使用:

@(Url.HttpRouteUrl("Search.Subjects", new {}))
Run Code Online (Sandbox Code Playgroud)

其中"Search.Subjects"被指定为Route属性中的路径名称.

我不想被迫为我的路线指定一个唯一的名称.

如何生成WebApi控制器操作的URL而无需在Route属性中明确指定路由名称?

CodePlex的默认路由命名方案是否可能已更改或记录错误?

有没有人对正确检索已使用AttributeRouting设置的路由的URL的方法有所了解?

c# asp.net asp.net-web-api attributerouting asp.net-web-api-routing

21
推荐指数
2
解决办法
2077
查看次数