markpsmith
markpsmith

Reputation: 4918

POSTing to my ASP.NET MVC app from 3rd party site

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

Answers (4)

ltiong_dbl
ltiong_dbl

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

Darin Dimitrov
Darin Dimitrov

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

Jason Yost
Jason Yost

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

Xharze
Xharze

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

Related Questions