如何在不使用属性路由的路由属性上指定名称的情况下生成 Web Api 2 URL?

2024-03-31

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

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.MapHttpAttributeRoutes();
    }
}

我有一个ApiController如下:

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

我想生成 WebApi 控制器操作的 URL,而无需指定显式路由名称。

根据CodePlex 上的此页面 https://aspnetwebstack.codeplex.com/wikipage?title=Attribute%20routing%20in%20Web%20API,所有 MVC 路由都有一个不同的名称,即使未指定也是如此。

在没有指定路由名称的情况下,Web API 将生成一个 默认路由名称。如果只有一个属性路由 特定控制器上的操作名称,路由名称将采用 形式“控制器名称.操作名称”。如果有多个属性 在该控制器上具有相同的操作名称,后缀会添加到 区分路由:“Customer.Get1”、“Customer.Get2”。

在 ASP.NET 上 http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2#route-names,它没有确切说明默认的命名约定是什么,但它确实表明每个路由都有一个名称。

在 Web API 中,每条路线都有一个名字。路线名称很有用 生成链接,以便您可以在 HTTP 响应中包含链接。

基于这些资源和StackOverflow 用户 Karhgath 的回答 https://stackoverflow.com/a/21186709/1195273,我被引导相信以下内容会生成我的 WebApi 路由的 URL:

@(Url.RouteUrl("Subjects.Search"))

但是,这会产生错误:

在路线中找不到名为“Subjects.Search”的路线 收藏。

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

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

@(Url.HttpRouteUrl("Search.Subjects", new {}))

事实上,即使在属性中提供路由名称似乎也只适用于:

@(Url.HttpRouteUrl("Search.Subjects", new {}))

其中“Search.Subjects”被指定为 Route 属性中的路由名称。

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

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

默认路由命名方案是否可能已更改或在 CodePlex 中记录不正确?

是否有人对检索已使用属性路由设置的路由的 URL 的正确方法有所了解?


使用变通办法通过检查 Web Api 来查找路线IApiExplorer与强类型表达式一起,我能够生成 WebApi2 URL,而无需指定Name on the Route属性与属性路由。

我创建了一个帮助程序扩展,它允许我使用强类型表达式UrlHelper在 MVC 剃刀中。这对于从视图中解析 MVC 控制器的 URI 非常有效。

<a href="@(Url.Action<HomeController>(c=>c.Index()))">Home</a>
<li>@(Html.ActionLink<AccountController>("Sign in", c => c.Signin(null)))</li>
<li>@(Html.ActionLink<AccountController>("Create an account", c => c.Signup(), htmlAttributes: null))</li>
@using (Html.BeginForm<ToolsController>(c => c.Track(null), FormMethod.Get, htmlAttributes: new { @class = "navbar-form", role = "search" })) {...}    

我现在有一个视图,我正在尝试使用淘汰赛将一些数据发布到我的 Web api 并且需要能够执行类似的操作

var targetUrl = '@(Url.HttpRouteUrl<TestsApiController>(c => c.TestAction(null)))';

这样我就不必对我的网址进行硬编码(魔术字符串)

我当前用于获取 Web API url 的扩展方法的实现是在以下类中定义的。

public static class GenericUrlActionHelper {
    /// <summary>
    /// Generates a fully qualified URL to an action method 
    /// </summary>
    public static string Action<TController>(this UrlHelper urlHelper, Expression<Action<TController>> action)
       where TController : Controller {
        RouteValueDictionary rvd = InternalExpressionHelper.GetRouteValues(action);
        return urlHelper.Action(null, null, rvd);
    }

    public const string HttpAttributeRouteWebApiKey = "__RouteName";
    public static string HttpRouteUrl<TController>(this UrlHelper urlHelper, Expression<Action<TController>> expression)
       where TController : System.Web.Http.Controllers.IHttpController {
        var routeValues = expression.GetRouteValues();
        var httpRouteKey = System.Web.Http.Routing.HttpRoute.HttpRouteKey;
        if (!routeValues.ContainsKey(httpRouteKey)) {
            routeValues.Add(httpRouteKey, true);
        }
        var url = string.Empty;
        if (routeValues.ContainsKey(HttpAttributeRouteWebApiKey)) {
            var routeName = routeValues[HttpAttributeRouteWebApiKey] as string;
            routeValues.Remove(HttpAttributeRouteWebApiKey);
            routeValues.Remove("controller");
            routeValues.Remove("action");
            url = urlHelper.HttpRouteUrl(routeName, routeValues);
        } else {
            var path = resolvePath<TController>(routeValues, expression);
            var root = getRootPath(urlHelper);
            url = root + path;
        }
        return url;
    }

    private static string resolvePath<TController>(RouteValueDictionary routeValues, Expression<Action<TController>> expression) where TController : Http.Controllers.IHttpController {
        var controllerName = routeValues["controller"] as string;
        var actionName = routeValues["action"] as string;
        routeValues.Remove("controller");
        routeValues.Remove("action");

        var method = expression.AsMethodCallExpression().Method;

        var configuration = System.Web.Http.GlobalConfiguration.Configuration;
        var apiDescription = configuration.Services.GetApiExplorer().ApiDescriptions
           .FirstOrDefault(c =>
               c.ActionDescriptor.ControllerDescriptor.ControllerType == typeof(TController)
               && c.ActionDescriptor.ControllerDescriptor.ControllerType.GetMethod(actionName) == method
               && c.ActionDescriptor.ActionName == actionName
           );

        var route = apiDescription.Route;
        var routeData = new HttpRouteData(route, new HttpRouteValueDictionary(routeValues));

        var request = new System.Net.Http.HttpRequestMessage();
        request.Properties[System.Web.Http.Hosting.HttpPropertyKeys.HttpConfigurationKey] = configuration;
        request.Properties[System.Web.Http.Hosting.HttpPropertyKeys.HttpRouteDataKey] = routeData;

        var virtualPathData = route.GetVirtualPath(request, routeValues);

        var path = virtualPathData.VirtualPath;

        return path;
    }

    private static string getRootPath(UrlHelper urlHelper) {
        var request = urlHelper.RequestContext.HttpContext.Request;
        var scheme = request.Url.Scheme;
        var server = request.Headers["Host"] ?? string.Format("{0}:{1}", request.Url.Host, request.Url.Port);
        var host = string.Format("{0}://{1}", scheme, server);
        var root = host + ToAbsolute("~");
        return root;
    }

    static string ToAbsolute(string virtualPath) {
        return VirtualPathUtility.ToAbsolute(virtualPath);
    }
}

InternalExpressionHelper.GetRouteValues检查表达式并生成RouteValueDictionary将用于生成 url。

static class InternalExpressionHelper {
    /// <summary>
    /// Extract route values from strongly typed expression
    /// </summary>
    public static RouteValueDictionary GetRouteValues<TController>(
        this Expression<Action<TController>> expression,
        RouteValueDictionary routeValues = null) {
        if (expression == null) {
            throw new ArgumentNullException("expression");
        }
        routeValues = routeValues ?? new RouteValueDictionary();

        var controllerType = ensureController<TController>();

        routeValues["controller"] = ensureControllerName(controllerType); ;

        var methodCallExpression = AsMethodCallExpression<TController>(expression);

        routeValues["action"] = methodCallExpression.Method.Name;

        //Add parameter values from expression to dictionary
        var parameters = buildParameterValuesFromExpression(methodCallExpression);
        if (parameters != null) {
            foreach (KeyValuePair<string, object> parameter in parameters) {
                routeValues.Add(parameter.Key, parameter.Value);
            }
        }

        //Try to extract route attribute name if present on an api controller.
        if (typeof(System.Web.Http.Controllers.IHttpController).IsAssignableFrom(controllerType)) {
            var routeAttribute = methodCallExpression.Method.GetCustomAttribute<System.Web.Http.RouteAttribute>(false);
            if (routeAttribute != null && routeAttribute.Name != null) {
                routeValues[GenericUrlActionHelper.HttpAttributeRouteWebApiKey] = routeAttribute.Name;
            }
        }

        return routeValues;
    }

    private static string ensureControllerName(Type controllerType) {
        var controllerName = controllerType.Name;
        if (!controllerName.EndsWith("Controller", StringComparison.OrdinalIgnoreCase)) {
            throw new ArgumentException("Action target must end in controller", "action");
        }
        controllerName = controllerName.Remove(controllerName.Length - 10, 10);
        if (controllerName.Length == 0) {
            throw new ArgumentException("Action cannot route to controller", "action");
        }
        return controllerName;
    }

    internal static MethodCallExpression AsMethodCallExpression<TController>(this Expression<Action<TController>> expression) {
        var methodCallExpression = expression.Body as MethodCallExpression;
        if (methodCallExpression == null)
            throw new InvalidOperationException("Expression must be a method call.");

        if (methodCallExpression.Object != expression.Parameters[0])
            throw new InvalidOperationException("Method call must target lambda argument.");

        return methodCallExpression;
    }

    private static Type ensureController<TController>() {
        var controllerType = typeof(TController);

        bool isController = controllerType != null
               && controllerType.Name.EndsWith("Controller", StringComparison.OrdinalIgnoreCase)
               && !controllerType.IsAbstract
               && (
                    typeof(IController).IsAssignableFrom(controllerType)
                    || typeof(System.Web.Http.Controllers.IHttpController).IsAssignableFrom(controllerType)
                  );

        if (!isController) {
            throw new InvalidOperationException("Action target is an invalid controller.");
        }
        return controllerType;
    }

    private static RouteValueDictionary buildParameterValuesFromExpression(MethodCallExpression methodCallExpression) {
        RouteValueDictionary result = new RouteValueDictionary();
        ParameterInfo[] parameters = methodCallExpression.Method.GetParameters();
        if (parameters.Length > 0) {
            for (int i = 0; i < parameters.Length; i++) {
                object value;
                var expressionArgument = methodCallExpression.Arguments[i];
                if (expressionArgument.NodeType == ExpressionType.Constant) {
                    // If argument is a constant expression, just get the value
                    value = (expressionArgument as ConstantExpression).Value;
                } else {
                    try {
                        // Otherwise, convert the argument subexpression to type object,
                        // make a lambda out of it, compile it, and invoke it to get the value
                        var convertExpression = Expression.Convert(expressionArgument, typeof(object));
                        value = Expression.Lambda<Func<object>>(convertExpression).Compile().Invoke();
                    } catch {
                        // ?????
                        value = String.Empty;
                    }
                }
                result.Add(parameters[i].Name, value);
            }
        }
        return result;
    }
}

诀窍是获取操作的路由并使用它来生成 URL。

private static string resolvePath<TController>(RouteValueDictionary routeValues, Expression<Action<TController>> expression) where TController : Http.Controllers.IHttpController {
    var controllerName = routeValues["controller"] as string;
    var actionName = routeValues["action"] as string;
    routeValues.Remove("controller");
    routeValues.Remove("action");

    var method = expression.AsMethodCallExpression().Method;

    var configuration = System.Web.Http.GlobalConfiguration.Configuration;
    var apiDescription = configuration.Services.GetApiExplorer().ApiDescriptions
       .FirstOrDefault(c =>
           c.ActionDescriptor.ControllerDescriptor.ControllerType == typeof(TController)
           && c.ActionDescriptor.ControllerDescriptor.ControllerType.GetMethod(actionName) == method
           && c.ActionDescriptor.ActionName == actionName
       );

    var route = apiDescription.Route;
    var routeData = new HttpRouteData(route, new HttpRouteValueDictionary(routeValues));

    var request = new System.Net.Http.HttpRequestMessage();
    request.Properties[System.Web.Http.Hosting.HttpPropertyKeys.HttpConfigurationKey] = configuration;
    request.Properties[System.Web.Http.Hosting.HttpPropertyKeys.HttpRouteDataKey] = routeData;

    var virtualPathData = route.GetVirtualPath(request, routeValues);

    var path = virtualPathData.VirtualPath;

    return path;
}

现在如果我有以下 api 控制器

[RoutePrefix("api/tests")]
[AllowAnonymous]
public class TestsApiController : WebApiControllerBase {
    [HttpGet]
    [Route("{lat:double:range(-90,90)}/{lng:double:range(-180,180)}")]
    public object Get(double lat, double lng) {
        return new { lat = lat, lng = lng };
    }
}

到目前为止,当我测试它时,大部分都有效

@section Scripts {
    <script type="text/javascript">
        var url = '@(Url.HttpRouteUrl<TestsApiController>(c => c.Get(1,2)))';
        alert(url);
    </script>
}

I get /api/tests/1/2,这就是我想要的,我相信会满足您的要求。

请注意,对于具有以下路由属性的操作,它也会默认返回到 UrlHelperName.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在不使用属性路由的路由属性上指定名称的情况下生成 Web Api 2 URL? 的相关文章

  • 通过 SOAP 的 Gmt php 或 UTC C# 等效项

    is C DateTime UtcNow和 PHPdate c 是等价的 我怀疑 因为当我肥皂时 我得到了 C
  • 从另一个 FORM 中取回隐藏的 FORM

    我有两种形式Form1 and Form2 我正在打开Form2 from Form1 on button Click Form2 obj2 new Form2 this Visible false obj2 Show 然后我想回来Form
  • .pdbs 会减慢发布应用程序的速度吗?

    如果 dll 中包含 pdb 程序调试 文件 则行号将出现在引发的任何异常的堆栈跟踪中 这会影响应用程序的性能吗 这个问题与发布与调试 即优化 无关 这是关于拥有 pdb 文件的性能影响 每次抛出异常时都会读取 pdb 文件吗 加载程序集时
  • C++中的类要具备什么条件才能成为容器?

    我是 C 编程新手 偶然发现了这个术语containers举例如下vector deque map etc 一个企业的最低要求应该是什么class应该满足被称为container in C 我将从 范围 这个概念开始 Range 只有两个方
  • 具有多个谓词的 C++11 算法

    功能如std find if来自algorithmheader 确实很有用 但对我来说 一个严重的限制是我只能为每次调用使用 1 个谓词count if 例如给定一个像这样的容器std vector我想同时应用相同的迭代find if 多个
  • 如何查明 .exe 是否正在 C++ 中运行?

    给定进程名称 例如 程序 exe C 标准库没有这样的支持 您需要一个操作系统 API 来执行此操作 如果这是 Windows 那么您将使用 CreateToolhelp32Snapshot 然后使用 Process32First 和 Pr
  • 从时间列表中查找最接近的时间

    所以 这是场景 我有一个带有创建时间的文件 我想从该文件的创建时间最接近或相等的时间列表中选择一个时间 完成此操作的最佳方法是什么 var closestTime listOfTimes OrderBy t gt Math Abs t fi
  • make_shared<>() 中的 WKWYL 优化是否会给某些多线程应用程序带来惩罚?

    前几天我偶然看到这个非常有趣的演示 http channel9 msdn com Events GoingNative GoingNative 2012 STL11 Magic Secrets作者 Stephan T Lavavej 其中提
  • 虚拟并行端口模拟器

    在我的计算机网络课程中 我们应该通过使用本机寄存器 例如使用 outportb 等命令 来学习并行端口编程 我没有并行端口 因为我住在 2011 年 但想练习这些程序 我使用 dosbox 安装了旧的 Turboc 3 IDE 有没有一个程
  • Nhibernate:连接表并从其他表获取单列

    我有以下表格 create table Users Id uniqueidentifier primary key InfoId uniqueidentifier not null unique Password nvarchar 255
  • 判断串口是普通COM还是SPP

    我正在寻找一种方法来确定 COM 是标准 COM 还是 SPP COM 也称为 COM 设备的电缆替换蓝牙适配器 我有一个可以在 USB COM gt USB 和蓝牙下工作的设备 并且蓝牙接口可以与 SPP 一起工作 我目前正在使用Syst
  • C 类型命名约定,_t 或 ALLCAPS

    我一直想知道是否有任何命名约定 例如何时对类型使用全部大写以及何时追加 t 什么时候不使用任何东西 我知道当时 K R 发布了各种有关如何使用 C 的文档 但我找不到任何相关内容 在 C 标准库类型中 t看起来漂亮占主导地位 time t
  • 提升mapped_file_source、对齐方式和页面大小

    我正在尝试在性能很重要的上下文中解析一些大小高达几百兆字节的文本文件 因此我使用 boostmapped file source 解析器期望源以空字节终止 因此我想检查文件大小是否是页面大小的精确倍数 如果是 则使用较慢的非内存映射方法 我
  • 从点云检测平面集

    我有一组点云 我想测试3D房间中是否有角落 所以我想讨论一下我的方法 以及在速度方面是否有更好的方法 因为我想在手机上测试它 我将尝试使用霍夫变换来检测线 然后我将尝试查看是否有三条线相交 并且它们也形成了两个相交的平面 如果点云数据来自深
  • 将 2 个字节转换为整数

    我收到一个 2 个字节的端口号 最低有效字节在前 我想将其转换为整数 以便我可以使用它 我做了这个 char buf 2 Where the received bytes are char port 2 port 0 buf 1 port
  • 如何在 EF Core 2.1 中定义外键关系

    我的 DAL 使用 EF Core 2 1 这就是我的模型的样子 一名用户只能拥有一种角色 Role entity kind of master public class Role public int RoleId get set pub
  • MSChart 控件中的自定义 X/Y 网格线

    我有一个带有简单 2D 折线图的 C Windows 窗体 我想向其中添加自定义 X 或 Y 轴标记 并绘制自定义网格线 例如 以突出显示的颜色 虚线 我查看了 customLabels 属性 但这似乎覆盖了我仍然想显示的默认网格 这是为了
  • 在二进制数据文件的标头中放入什么

    我有一个模拟 可以读取我们创建的大型二进制数据文件 10 到 100 GB 出于速度原因 我们使用二进制 这些文件依赖于系统 是从我们运行的每个系统上的文本文件转换而来的 所以我不关心可移植性 当前的文件是 POD 结构的许多实例 使用 f
  • 如何在c中断言两个类型相等?

    在 C 中如何断言两种类型相等 在 C 中 我会使用 std is same 但搜索 StackOverflow 和其他地方似乎只能给出 C 和 C 的结果 在C中没有办法做到这一点吗 请注意 这不是询问变量是否具有某种类型 而是询问两个类
  • 是否可以使用 Dapper 流式传输大型 SQL Server 数据库结果集?

    我需要从数据库返回大约 500K 行 请不要问为什么 然后 我需要将这些结果保存为 XML 更紧急 并将该文件通过 ftp 传输到某个神奇的地方 我还需要转换结果集中的每一行 现在 这就是我正在做的事情 TOP 100结果 使用 Dappe

随机推荐

  • 设置对象彼此相等(java)

    所以我有一个名为 Person 的类 看起来像这样 public class Person private String personName public String toString return personName public
  • 使用 AutoFac 注入通用类型参数

    我想我真的很困惑我能用 AutoFac 做什么 有人可以让我走上正轨吗 我有一个基本类型 class PersonBase public string SaySomething return I am base 我派生出两个具体的类 cla
  • 自定义 ViewGroup 焦点处理

    假设我有一个可聚焦的自定义 ViewGroup 并且有一些可聚焦的子视图 适用于 Android 机顶盒的自定义垂直菜单 应在遥控器上做出反应 每当自定义 ViewGroup 获得焦点时 我需要将焦点传递给某些子视图 I set desce
  • 布局渲染后如何初始化 jQuery 对象?

    我想定义一些变量 以便在我的应用程序布局呈现后立即用于确定 jQuery 选择器的范围 我尝试用以下方式定义它们 Meteor startup function Define variables 但它不起作用 对象是空的 这是我声明我的应用
  • Pvr 在 cocos2d 3.2 版本中翻转:从 2.1 移植时的困境

    我目前正在将一个游戏从cocos2d 2 1版本移植到3 2版本 我们有超过 3600 个未翻转的 pvr gz 文件 例如在 2 1 下生成和工作的文件 我们使用TexturePacker测试了pvr图像的flipY选项 并且确实有足够的
  • Apache Ignite - (jvm-pause- detector-worker) JVM 暂停时间可能过长:

    使用 apache ignite 2 6 后 我在 JBoss 启动和停止时不断收到此警告 您能否帮我知道什么错误的配置会导致此警告 如果您需要更多详细信息 请告诉我 最有可能的是 JVM 正在经历长时间的垃圾收集暂停 可以配置详细的GC日
  • Keras 中的 5 层 DNN 使用 GPU 训练速度较慢

    我在 Keras 1 2 中使用 tensorflow gpu 作为后端编写了一个 5 层密集网络 并在我的 MacBookPro CPU 和 AWS 中的 P2 xlarge 实例 K80 启用 cuda 中对其进行训练 令人惊讶的是 我
  • 在事件中对 HTML 表格单元格(或整行)的背景颜色进行动画处理

    我有一张桌子 上面有一个菜单 食品 有几行和几列 第二列包含食品的链接 当用户点击它时 该商品已添加到购物车中 我想给用户一些点击和添加的视觉反馈 确实有效 我已经有一个用于添加链接的点击处理程序 商品点击进入购物车 一个简单的alert
  • 如何计算从 Shiny 中的文本输入框获取的数据?

    ui code library shiny shinyUI Use a fluid Bootstrap layout fluidPage Generate a row with a sidebar sidebarLayout Define
  • 将日期转换为特定格式的字符在R中

    我需要映射 3 4 个具有不同日期格式的不同数据帧 我们如何将日期转换为以下格式 YYYY MM DD 转换为以下格式的字符 MMM YY 从字符串创建日期对象 如果您的列已采用日期格式 请跳过此操作 original date lt as
  • 防止 SliverAppBar 标题在 Flutter 中收缩时换行

    我有一个 Flutter 应用程序 它在 CustomScrollView 中使用 SliverAppBar SliverAppBar 的标题非常长 因此当 AppBar 在滚动时压缩时 标题开始换行几次 我想在不使用溢出的情况下防止这种行
  • 根据条件合并不同行的字段

    亚马逊为其市场客户提供 CSV 报告 其中包含有关您销售的每篇文章的信息 每篇文章有四行 如下所示 orderid amounttype amountdescription amount 305 2406165 0572365 ItemPr
  • 每次点击都会弹出新窗口

    我有一个弹出窗口 我使用下面的脚本打开它 每次点击时 我想打开新的弹出窗口 据我了解 为窗口指定唯一的名称将解决问题 在本例中为 SampleWindow 保持窗户独特性的最佳方法是什么 还有其他方法可以管理 javascript 弹出窗口
  • Orchard CMS 事务错误

    我们的 Orchard 网站上经常随机出现以下错误 当在页面之间快速导航时 这种情况似乎最为普遍 日志中没有其他错误 因此我不确定如何找出根本原因 我们没有对 ODBC 或类似的东西做任何特殊的事情 这是 google 在搜索有关 Orch
  • 使用 x64 汇编代码的基本输入

    我正在编写有关汇编中基本输入和输出的教程 我使用的是 64 位 Linux 发行版 Ubuntu 在教程的第一部分中 我讨论了基本输出并创建了一个简单的程序 如下所示 global start section text start mov
  • 从 gradle/groovy 中的路径创建目录结构

    我正在从 git 命令行输出在项目的 gradle 构建中实现 diff 包生成任务 目前我有一个方法可以给我一个已更改文件的列表git diff name only 我想做的是在一个新目录中创建一个与每个文件的路径匹配的目录结构 例如 输
  • 从Python中的日期字符串中删除时间戳

    我遇到了应该忽略日期字符串中的时间戳的情况 我尝试过以下命令 但没有成功 start variable used below is in AbsTime Ex 01MAY2017 11 45 and not a string start d
  • 是否有任何 AngularJS + ASP.NET-WebApi + OData + Breeze.js + Typescript 示例,或者有人尝试将这些示例结合起来

    我试图结合这些技术 但没有什么好的结果 因为实体框架元数据不会被breeze js消耗 即使是所有设置的配置 这也是一个有点棘手的情况 实际上没有这样的例子 所以这个是我的示例代码 它不能正常工作 但不知何故 也许有人会发现我的错误 并最终
  • 错误:数据库连接“Sqlite”丢失,或无法创建 Cakephp 2.9.0

    您好 我正在使用 phpdesktop 构建桌面应用程序 我遇到了这个问题Error Database connection Sqlite is missing or could not be created 使用时cake bake 我能
  • 如何在不使用属性路由的路由属性上指定名称的情况下生成 Web Api 2 URL?

    我已将 ASP NET MVC5 应用程序配置为使用 WebApi 的 AttributeRouting public static class WebApiConfig public static void Register HttpCo