ASP.NET MVC 3 - 替换 HttpContext 响应不起作用
我正在使用 Nopcommerce,它最近已升级为使用 MVC3 - 之前它使用 Webforms。我正在尝试连接到 Worldpay(支付网关)托管网站。这个过程有点复杂,但本质上需要向 Worldpay 提交一个表单,然后用户被重定向到他们的托管网站以填写他们的信用卡详细信息等。Nopcommerce
使用 Post 方法来处理这个问题,该方法在服务器端,构建需要发布的表单,并用构建的 HTML 替换 httpcontext 响应。
_httpContext.Response.Clear();
_httpContext.Response.Write("<html><head>");
_httpContext.Response.Write(string.Format("</head><body onload=\"document.{0}.submit()\">", FormName));
_httpContext.Response.Write(string.Format("<form name=\"{0}\" method=\"{1}\" action=\"{2}\" >", FormName, Method, Url));
for (int i = 0; i < _inputValues.Keys.Count; i++)
_httpContext.Response.Write(string.Format("<input name=\"{0}\" type=\"hidden\" value=\"{1}\">", HttpUtility.HtmlEncode(_inputValues.Keys[i]), HttpUtility.HtmlEncode(_inputValues[_inputValues.Keys[i]])));
_httpContext.Response.Write("</form>");
_httpContext.Response.Write("</body></html>");
_httpContext.Response.End();
这在 webforms 版本中工作正常,但在 MVC 版本中不起作用。没有错误,一切看起来都工作正常。但是,处理会继续,执行会从服务层(此方法所在的层)返回到控制器,并发出以下重定向:
return RedirectToRoute("CheckoutCompleted");
在修改服务器端的响应方面,MVC 的工作方式与 Webform 不同吗?我已经尝试了以下代码,并且可以确认 worldpay 确实受到了攻击,并且正在发送我期望的响应:
_httpContext.Response.Clear();
var webClient = new WebClient();
var responseBytes = webClient.UploadValues(Url, "POST", _inputValues);
var response = Encoding.UTF8.GetString(responseBytes);
_httpContext.Response.Write(response);
_httpContext.Response.End();
注意:在上面的示例中,HttpContext 被注入到服务中。通过使用 HttpContext.Current
更新:
可以实现相同的结果进行更多挖掘后,我发现如果我从任何控制器写入响应流并结束响应,我会得到一个空白(0 长度响应) ) 屏幕。以下是导致上述问题的家庭控制器上的索引操作。相同的代码,在我创建的一次性项目中,运行得很好......
public ActionResult Index()
{
Response.Write("test");
Response.End();
return View(_storeInformationSettings);
}
I am using Nopcommerce which has recently been upgraded to use MVC3 - previously it used webforms. I am attempting to connect to Worldpay's (payment gateway) hosted site. The process is a little convoluted but essentially a form needs to be submitted to Worldpay and the user is then redirected to their hosted site to fill in their credit card details etc.
Nopcommerce takes care of this using a Post method which, on the server side, builds the form that needs to be posted and replaces the httpcontext response with built out HTML
_httpContext.Response.Clear();
_httpContext.Response.Write("<html><head>");
_httpContext.Response.Write(string.Format("</head><body onload=\"document.{0}.submit()\">", FormName));
_httpContext.Response.Write(string.Format("<form name=\"{0}\" method=\"{1}\" action=\"{2}\" >", FormName, Method, Url));
for (int i = 0; i < _inputValues.Keys.Count; i++)
_httpContext.Response.Write(string.Format("<input name=\"{0}\" type=\"hidden\" value=\"{1}\">", HttpUtility.HtmlEncode(_inputValues.Keys[i]), HttpUtility.HtmlEncode(_inputValues[_inputValues.Keys[i]])));
_httpContext.Response.Write("</form>");
_httpContext.Response.Write("</body></html>");
_httpContext.Response.End();
This works fine in the webforms version but does not work in the MVC version. There is no error, and everything appears to work correctly. However, processing continues and execution returns from the service layer (in which this method is located) to the controller and the following redirect is issued:
return RedirectToRoute("CheckoutCompleted");
Does MVC work differently to webforms with regard to modifying the response on the server side? I have tried the following code and can confirm that worldpay is indeed being hit and is sending the response I would expect:
_httpContext.Response.Clear();
var webClient = new WebClient();
var responseBytes = webClient.UploadValues(Url, "POST", _inputValues);
var response = Encoding.UTF8.GetString(responseBytes);
_httpContext.Response.Write(response);
_httpContext.Response.End();
Note: in the above examples the HttpContext is injected into the service. The same result is achieved by using the HttpContext.Current
Update:
Doing a little more digging I see that if i write to the response stream from any controller and end the response I get a blank (0 length response) screen. Below is the index action on the home controller which causes said issue. The same code, in a throwaway project I created, works perfectly...
public ActionResult Index()
{
Response.Write("test");
Response.End();
return View(_storeInformationSettings);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果更改代码的第三个片段,您可以将 Response.Write 和 Response.End 保留在控制器之外。
HttpContext.Current.ApplicationInstance.CompleteRequest(); 为我解决了这个问题。另请参阅关于此的一篇好文章 有关 Response.End 和 Response.Close 的 MSDN 博客
If you change your third snippet of the code you can leave the Response.Write and Response.End out of your controller.
HttpContext.Current.ApplicationInstance.CompleteRequest(); did the trick for me. See also a nice post about this MSDN Blog about Response.End and Response.Close