ASP.NET MVC 5属性路由:Url.Action返回null [英] ASP.NET MVC 5 Attribute Routing: Url.Action returns null

查看:213
本文介绍了ASP.NET MVC 5属性路由:Url.Action返回null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在重构我们的付款处理操作方法时遇到了问题(由我们的第三方在线付款提供商调用).我们有一个产品控制器,在类级别具有[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:

    具有路由属性[Route("{productCode}")]
  • Product(string contractNumber) 具有路由属性[Route("{productCode}")][HttpPost]属性的
  • MakePayment(string productCode, PaymentAmountType? amountSelection, decimal? amountValue)
  • 具有路由属性[Route("{productCode}")]
  • ProcessPayment(string productCode, string result)
  • Product(string contractNumber) with routing attribute [Route("{productCode}")]
  • MakePayment(string productCode, PaymentAmountType? amountSelection, decimal? amountValue) with routing attribute [Route("{productCode}")] and [HttpPost] attribute
  • ProcessPayment(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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆