Reputation: 4918
I'm testing a payment provider (SagePay) and as part of a process, their server POSTs to my site and expects a response. I can't get this to work using MVC.
I set up a classic asp test reponse page and added it to my MVC app:
<%
Response.Buffer = True
response.Clear()
response.contenttype="text/plain"
response.write "Status=OK" & vbCRLF
response.write "RedirectURL=http://www.redirectsomewhere.co.uk" & vbCRLF
response.End()
%>
This work fine.
However, when I try to do the same with MVC, it doesn't work:
Controller:
[HttpPost]
public ActionResult TestCallback()
{
return View();
}
View:
@{
Response.Buffer = true;
Response.Clear();
Response.ContentType = "text/plain";
Response.Write("Status=OK" + System.Environment.NewLine);
Response.Write("RedirectURL=http://www.redirectsomewhere.co.uk" + System.Environment.NewLine);
Response.End();
}
The error message is a generic error from the payment provider so is no real help, but I have narrowed the error down to the point at which the page renders.
I can browse to both pages fine (i need remove the HttpPost attribute from the MVC controller method for this), and both pages display identical data.
This is the MVC url that the payment provider is POSTing to:
http://myipaddress/CA_UAT/Token/TestCallback
This is the classic asp URL that works fine:
http://myipaddress/CA_UAT/Token/TestCallback.asp
I created a 'Token' directory for the asp page so the urls would match for testing purposes.
What am I doing wrong?
UPDATE
In response to Hari's comment, I installed a Firefox plugin called 'Header Spy' which gives me this information:
Response HTTP/1.1 200 OK
Source: Response
HttpHeader:Server
Request:User-Agent Cookie
Response:Response Date Set-Cookie
Both pages show the same info.
Upvotes: 3
Views: 1760
Reputation: 3216
I wonder if sagepay is expecting a file extension..ie doing some kind of URL validation on heir side. Do you know if your Action is being invoked?
Also try adding a route that makes your mvc URL look like "TestCallback.asp".
Upvotes: 0
Reputation: 1039000
Try like this:
[HttpPost]
public ActionResult TestCallback()
{
var sb = new StringBuilder();
sb.AppendLine("Status=OK");
sb.AppendLine("RedirectURL=http://www.redirectsomewhere.co.uk");
return Content(sb.ToString(), "text/plain");
}
or in a more MVCish way:
View model:
public class ResponseViewModel
{
public string Status { get; set; }
public string RedirectUrl { get; set; }
}
and then a custom action result:
public class StatusActionResult : ContentResult
{
private readonly ResponseModel _model;
public StatusActionResult(ResponseModel model)
{
_model = model;
}
public override void ExecuteResult(ControllerContext context)
{
var response = context.HttpContext.Response;
response.ContentType = "text/plain";
response.Write(string.Format("Status={0}{1}", _model.Status, Environment.NewLine));
response.Write(string.Format("RedirectURL={0}", _model.RedirectUrl));
}
}
and finally your controller action:
[HttpPost]
public ActionResult TestCallback()
{
var model = new ResponseModel
{
Status = "OK",
RedirectUrl = "http://www.redirectsomewhere.co.uk"
};
return new StatusActionResult(model);
}
Upvotes: 0
Reputation: 4937
You don't need to return an action result in order to send just plain text back to the screen. The simplest way of accomplishing this is to return a string value. Replace the code in your controller with what is below.
[HttpPost]
public string TestCallback()
{
string result = "Status=OK";
result += System.Environment.NewLine;
result += "RedirectURL=http://www.redirectsomewhere.co.uk";
result += System.Environment.NewLine;
return result;
}
This will return no other response that what you have in the string. By using an ActionResult and View you are likely returning markup from the master view.
Upvotes: 1
Reputation: 2733
Instead of writing the response in the view, I would write it in the action method like this:
[HttpPost]
public ActionResult TestCallback()
{
Response.Buffer = true;
Response.Clear();
Response.ContentType = "text/plain";
Response.Write("Status=OK" + System.Environment.NewLine);
Response.Write("RedirectURL=http://www.redirectsomewhere.co.uk" + System.Environment.NewLine);
Response.Flush();
return new EmptyResult();
}
When returning EmptyResult you will ensure that MVC doesn't append anything to the response.
Upvotes: 0