I'm building my first website using C# and Twitter Bootstrap, and I get the "Server cannot append header after HTTP headers have been sent" error in a Post while finding a validation issue and a TempData["ErrorMessage"]
needs to be displayed after a return View(model)
. The specific error occurs on the html line @Html.AntiForgeryToken()
. The error does not occur if the message is set and returned to the View outside of the validation.
I've tried: changing the return View(model)
to a RedirectToAction ("Action", new { id = model.id })
and Redirect ("/Controller/Action/" + model.id.ToString())
, which work if the line is outside the validation, but fails when inside the conditional validation; setting the AntiForgeryConfig.SuppressXFrameOptionsHeader
to true inside the Application_start
; and calling HttpContext.Response.Clear()
before setting the TempData and returning to the View. I haven't tried manipulating cookies yet because I'm unsure of how to specifically address the anti-forgery token.
All I want to do is return to the View with the error/validation message displayed on the page instead of as a pop-up message box, and none of the above methods has worked. Does anyone know why this goal works outside the validation but not inside of it? Many thanks in advance!
//Any return and message works correctly if done here
try
{
//Various other validations using values pulled from database
if (model.NewString.Length > 50 || model.NewString.Length < 7)
{
//This throws the error
TempData["ErrorMessage"] = "Please enter a value of valid length.";
return View(model);
}
}
catch
{
TempData["ErrorMessage"] = "There has been an error.";
return RedirectToAction("Index");
}
EDIT: here is the Action as-is per Amit's request.
[HttpPost]
[ValidateAntiForgeryToken]
[Authorize (Roles = "Administrator, Owner, Director, Manager")]
[RequireSsl]
public ActionResult CreateCustomer (CreateCustomerModel model)
{
dbEntities db = new dbEntities();
var CurrentBusinessID = 0;
var CurrentPosition = "";
var CurrentUserID = 0;
try
{
if (Session["CurrentUserID"] != null)
{
CurrentUserID = (int)Session["CurrentUserID"];
CurrentBusinessID = (int)Session["CurrentBusinessInfoID"];
CurrentPosition = (string)Session["CurrentPosition"];
}
else
{
Response.Redirect("/Account/Logon");
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
Response.Redirect("/Account/Logon");
}
try
{
var account = db.uspGetAccount(model.AccountID).FirstOrDefault();
AccountsModel thisAccount = new AccountsModel()
{
AccountID = model.AccountID,
BusinessID = account.BusinessID
};
if (thisAccount.BusinessID != CurrentBusinessID)
{
Response.Redirect("/Home/Dashboard");
}
if (model.Name == null || model.Name == "")
{
TempData["ErrorMessage"] = "Please enter a name.";
return View(model);
}
if (model.NewString.Length > 50 || model.NewString.Length < 7)
{
//This throws the error
TempData["ErrorMessage"] = "Please enter a value of valid length.";
return View(model);
}
db.AddCustomer(model.Name, model.NewString);
}
catch
{
TempData["ErrorMessage"] = "There has been an error.";
return RedirectToAction("Index");
}
return RedirectToAction("Accounts");
}
This issue was solved by changing the Reponse.Redirect("/Home/Dashboard")
inside the if
statement within the try
statement containing the validation. Changing this line to return RedirectToAction("Accounts")
solved the problem, although I'm not sure why.
if (thisAccount.BusinessID != CurrentBusinessID)
{
Response.Redirect("/Home/Dashboard");//Solve the problem by replacing this
}