I have an ASP MVC3 application that has several HttpPost ActionResult methods. During a debug session, the methods work fine. But when I publish and view the web app in the browser only the HttpPost methods fail. Firebug shows a "404 not found". Other non-HttpPost methods in the same controller work fine.
UPDATE:
1) The published url for the app is localhost/psp.
2) All the GET actions return URLs of http://localhost/psp/'controller'/'action'.
3) The POST actions are returning URLs of http://localhost/'controller'/'action'.
So this seems to be a routing problem. The only route I have in my Global.asax.cs file is:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Note that the Home controller does NOT contain any of the HttpPost actions. All POST methods that fail are in separate controller. I've tried to adjust this route to: psp/{controller}/{action}/{id}
but then receive a 403.14 error (FYI I am using IIS 7.5).
I'm baffled by why these HttpPost method work during debug but not in a published app. Here is one of the methods that get the 404 error after being published:
[HttpPost]
public ActionResult GetAreaSelTexResult(JSON_MapSelPars pars)
{
AreaSelTextResult myResult = new AreaSelTextResult();
using (var ctx = new prismEntities())
{
var q = from p in ctx.pPSPMapSummary_Sel(pars.areaType, pars.areaName, null, null,pars.goalCDL) select p;
// There should only be one record returned, so loop will iterate only once.
foreach (var k in q)
{
//Move procedure results to object
myResult.TopProjectName1 = k.TopProjectName1;
myResult.TopProjectName2 = k.TopProjectName2;
myResult.TopProjectName3 = k.TopProjectName3;
myResult.TopProjectSnapshotLink1 = k.TopProjectSnapshotLink1;
myResult.TopProjectSnapshotLink2 = k.TopProjectSnapshotLink2;
myResult.TopProjectSnapshotLink3 = k.TopProjectSnapshotLink3;
myResult.TotalProjectAmt = string.Format("{0:C}", k.TotalProjectAmt);
myResult.TotalProjectCount = k.TotalProjectCount;
}
}
// send object to partial view
return PartialView("GetAreaSelTexResult", myResult);
}
Here is the Partial View:
@model PAA.Models.AreaSelTextResult
<p>@Model.TotalProjectCount projects</p>
<p>@Model.TotalProjectAmt total</p>
<p>
<a href="@Model.TopProjectSnapshotLink1">@Model.TopProjectName1</a></p>
<p>
<a href="@Model.TopProjectSnapshotLink2">@Model.TopProjectName2</a></p>
<p>
<a href="@Model.TopProjectSnapshotLink3">@Model.TopProjectName3</a></p>
And here is the javascript that calls the HttpPost method and then loads the returned partial view into a div called "returnedProjData":
function retrieveSelectionSummary(selectionName, selectionType) {
$('#goalList input:checked').each(function () {
goals += $(this).attr('value') + ",";
});
var attr = { areaName: selectionName,
areaType: selectionType,
yearCDL: null,
goalCDL: null,
statusCDL: status
};
var json = JSON.stringify(attr);
$.ajax({
url: '/summary/GetAreaSelTexResult',
type: 'POST',
dataType: 'html',
data: json,
contentType: 'application/json; charset=utf-8',
success: function (result) {
$('#returnedProjData').html(result);
},
error: function () {
alert("Error.");
}
});
return attr;
}
Never hardcode urls like this:
url: '/summary/GetAreaSelTexResult',
Always use url helpers when generating urls:
url: '@Url.Action("GetAreaSelTexResult", "summary")',
The reason your code doesn't work when you deploy it in a virtual directory is because the url /summary/GetAreaSelTexResult
is no longer correct. You must take into account the virtual directory name now: /myappname/summary/GetAreaSelTexResult
. For this reason you should never hardcode your urls but always use url helpers to generate them.
And if this is in a separate javascript file where you cannot use server side helpers you could define a global variable in your view that will point to the correct url or use HTML5 data-* helpers on some DOM element that you are working with.
来源:https://stackoverflow.com/questions/9029714/asp-mvc3-httppost-action-not-found-after-publish