d_m*_*mcg 6 asp.net routes url-routing attributerouting asp.net-mvc-5
我在重构我们的支付处理操作方法(由我们的第 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被命中,因此该路由显然可以成功运行。
问题是MakePayment,在 中,以下调用返回null:
var rawCallbackUrl = Url.Action("ProcessPayment", "ExternalCallback", new { productCode = productCode });
Run Code Online (Sandbox Code Playgroud)
鉴于我指定了控制器和操作方法,为什么不在Url.Action(...)表单中返回预期的 URL order-processing/{productCode}/process-payment?
从第一天开始,我们的RegisterRoutes()方法RouteConfig已经正确初始化了属性路由
routes.MapMvcAttributeRoutes();
Run Code Online (Sandbox Code Playgroud)
如何获得从调用返回的正确 URL Url.Action(...)?
Doh - 我已经弄清楚出了什么问题。尽管对源代码中的名称(特定于我们的客户端)进行了清理,但事实证明以下调用中存在不匹配:
var rawCallbackUrl = Url.Action("ProcessPayment", "ExternalCallback", new { productCode = productCode });
Run Code Online (Sandbox Code Playgroud)
以及ProcessPayment()动作方法。
这类似于以下内容(请注意使用productNumber而不是productCode):
var rawCallbackUrl = Url.Action("ProcessPayment", "ExternalCallback", new { productNumber = productNumber });
Run Code Online (Sandbox Code Playgroud)
尝试引用操作方法:
[Route("order-processing/{productCode}/process-payment")]
public ActionResult ProcessPayment(string productCode, string result)
{
...
}
Run Code Online (Sandbox Code Playgroud)
事实证明,我还可以使用相同的前缀“产品”而不是“订单处理”,因为 MVCRoute在路由表中为每个属性创建一个路由。希望能帮助其他陷入类似情况的人。