问题描述
我在重构我们的付款处理操作方法时遇到了问题(由我们的第三方在线付款提供商调用).我们有一个产品控制器,在类级别具有[Authorize]
和[RoutePrefix("products")]
属性,其操作方法包括以下内容:
I am experiencing an issue with a refactoring of our payment processing action method (called by our 3rd-party online payment provider). We have a product controller with the [Authorize]
and [RoutePrefix("products")]
attributes at the class level, and action methods including the following:
- 具有路由属性
-
Product(string contractNumber)
具有路由属性[Route("{productCode}")]
和[HttpPost]
属性的 -
MakePayment(string productCode, PaymentAmountType? amountSelection, decimal? amountValue)
具有路由属性 -
ProcessPayment(string productCode, string result)
[Route("{productCode}")]
的[Route("{productCode}")]
的Product(string contractNumber)
with routing attribute[Route("{productCode}")]
MakePayment(string productCode, PaymentAmountType? amountSelection, decimal? amountValue)
with routing attribute[Route("{productCode}")]
and[HttpPost]
attributeProcessPayment(string productCode, string result)
with routing attribute[Route("{productCode}")]
因为在访问者被重定向到相同的URL之前,我们的支付网关需要能够调用我们的ProcessPayment
操作,所以我们不得不将其重构为没有[Authorize]
属性的单独的控制器. (我们已经有了防止双重付款的机制.)
Because our payment gateway needs to be able to call our ProcessPayment
action before the visitor is redirected to that same URL, we've had to refactor that to a separate controller without the [Authorize]
attribute. (We already have mechanisms to prevent double-crediting a payment.)
在进行此重构之前,MakePayment
操作方法在以下对Url.Action()
的调用中正确地制定了正确的返回URL:
Before this refactoring, the MakePayment
action method correctly formulated the correct return URL in the following call to Url.Action()
:
var rawCallbackUrl = Url.Action("ProcessPayment", new { productCode = productCode });
ProcessPayment
操作方法现在已从产品控制器中移出,并移到新的控制器ExternalCallbackController
中,该控制器具有 no 属性(更不用说[Authorize]
)了,以便避免将HTTP 401响应返回给支付提供商.
The ProcessPayment
action method has now been moved out of the product controller and into a new controller, ExternalCallbackController
, which has no attributes (let alone [Authorize]
), in order to avoid having an HTTP 401 response returned to the payment provider.
ProcessPayment
上的route属性现在为[Route("order-processing/{productCode}/process-payment")]
,以避免与产品控制器上的RoutePrefix
冲突.对此更新的操作方法的所有引用都进行了更新,以指定ExternalCallbackController
.
The route attribute on ProcessPayment
is now [Route("order-processing/{productCode}/process-payment")]
to avoid clashing with the RoutePrefix
on the product controller. All references to this updated action method are updated to specify the ExternalCallbackController
.
手动浏览到URL会导致击中ProcessPayment
中设置的断点,因此路由显然可以成功运行.
Manually browsing to the URL causes the breakpoint set inside ProcessPayment
to be hit, so the route apparently works successfully.
问题在于,在MakePayment
中,以下调用返回null
:
The problem is that in MakePayment
, the following call returns null
:
var rawCallbackUrl = Url.Action("ProcessPayment", "ExternalCallback", new { productCode = productCode });
鉴于我同时指定了控制器和操作方法,为什么Url.Action(...)
不以order-processing/{productCode}/process-payment
的形式返回预期的URL?
Given that I am specifying both the controller and action method, why is Url.Action(...)
not returning the expected URL in the form order-processing/{productCode}/process-payment
?
从第1天起,我们在RouteConfig
中的RegisterRoutes()
方法已正确初始化了属性路由
From Day 1, our RegisterRoutes()
method in RouteConfig
has had attribute routing properly initialised with
routes.MapMvcAttributeRoutes();
如何获得从Url.Action(...)
调用返回的正确URL?
How can I get the correct URL returned from the call to Url.Action(...)
?
推荐答案
Doh-我知道出了什么问题.尽管对源代码中的名称进行了清理(特定于我们的客户端),但事实证明,以下调用存在不匹配:
Doh - I've figured out what went wrong. Despite the sanitising of names in the source code (which were specific to our client), it turns out that there was a mismatch in the following call:
var rawCallbackUrl = Url.Action("ProcessPayment", "ExternalCallback", new { productCode = productCode });
和ProcessPayment()
操作方法.
这类似于以下内容(请注意使用 productNumber 代替 productCode ):
This is akin to the following (note the use of productNumber instead of productCode):
var rawCallbackUrl = Url.Action("ProcessPayment", "ExternalCallback", new { productNumber = productNumber });
尝试引用操作方法:
[Route("order-processing/{productCode}/process-payment")]
public ActionResult ProcessPayment(string productCode, string result)
{
...
}
事实证明,我也可以使用相同的前缀产品"代替订单处理",因为MVC在路由表中为每个属性路由创建一个Route
.希望能帮助其他陷入类似情况的人.
It also turns out that I can also use the same prefix "products" instead of "order-processing", as MVC creates one Route
per attribute route in the routing table. Hope that helps others stuck in a similar situation.
这篇关于ASP.NET MVC 5属性路由:Url.Action返回null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!