Accessing HTML Form data in MVC controller - asp.net-mvc

I have this problem. I need to access data that the user inputs via the statement during the controller method.
Here's my code, maybe this will make it more clear:
// client side
#using (Html.BeginForm())
{
if (competitorList.Count > 0 && eventList.Count > 0)
{
foreach (Event evt in eventList)
{
<table>
<tr><th>#evt.activity.Name</th></tr>
<tr>
<th>Name</th>
<th>Email</th>
<th>Score</th>
<th>New Score</th>
<th>Update</th>
</tr>
#foreach (Results res in resultList)
{
if (res.EventID == evt.id)
{
string competitorName = Person.getUserByEmail(res.CompetitorEmail).FirstName + Person.getUserByEmail(res.CompetitorEmail).LastName;
<tr>
<td>#competitorName</td>
<td>#res.CompetitorEmail</td>
<td>#res.Score</td>
<td><form action="EventResults"><input type="text" name="score" id="score" /></form></td>
<td>#Html.ActionLink("Update", "UpdateResults", "Competition", new { compId = evt.competitionId, evtId = res.EventID, email = res.CompetitorEmail }, null)</td>
</tr>
}
}
</table>
<hr />
}
}
else
{
<p>There are currently no competitors invited to participate</p>
}
}
// controller
public ActionResult UpdateResults(FormCollection form, int compId, int evtId, string email)
{
////// this returns 0.0 /////
double score = Convert.ToDouble(form["score"]);
BINC.Models.Results.UpdateResults(evtId, email, score);
List<Event> CompetitionEvents = Event.getEventsByCompetitionId(compId);
ViewBag.CompetitionEvents = CompetitionEvents;
List<Competitor> Competitors = Competitor.getCompetitors(compId);
ViewBag.Competitors = Competitors;
List<Results> Results = Competition.getCompetitorResultsPairings(CompetitionEvents, Competitors);
ViewBag.Results = Results;
ViewBag.Competition = Competition.getCompetitionById(compId);
return View("EventResults");
}
What you see in the controller method doesn't work; I assume it's because the page wasn't actually "submitted"? I really want to use a link instead of a submit button though. Can someone give me a hand?

give it the ActionType like [HttpPost],[HttpGet],[HttpDelete]
[HttpPost]
public ActionResult UpdateResults(FormCollection form, int compId, int evtId, string email)
{
//Code
}

If you want to use a link, you are using a GET request not a post request.
Your options using a link are either make it an ajax request (see my prior answer at MVC3 Html.ActionLink Post)
or use javascript to post the form:
How can I use an anchor tag to submit a form with jquery
$(document).ready(function(){
$("a").click(function(){
$("#requestNew").submit();
});
});
or using $("#yourHrefId") if you want to refer by id rather than all hrefs.

Related

MVC How to load a view and a partial view from one controller

I have a controller that returns a view that has a table in that view that's populated with information about orders
public class HomeController : Controller
{
public IActionResult OrderTracking()
{
List<WebOrder> orderList = SuperDAL.GetWebOrders();
foreach(WebOrder order in orderList)
{
order.Parts = SuperDAL.GetPartsForWebOrder(order.ID);
}
return View(orderList);
}
}
OrderTracking View
#model List<WebOrder>
<table id="orderTable" class="orderTable">
<thead>
<tr>
<th>Priority</th>
<th>Web Order Number</th>
<th>Order Number</th>
<th>Company</th>
<th>Status</th>
<th>Due Date</th>
<th>Date Received</th>
<th>Customer</th>
<th>Order Cost</th>
</tr>
</thead>
<tbody>
#foreach (var webOrder in Model)
{
<tr data-ID="#webOrder.ID">
#*The tds with data-date are storing the date contained
within the tds in ISO date format. This value is
being pulled in JavaScript to avoid having
messy string formating in JS for date comparisons*#
<td class="#webOrder.getPriority().ToLower()">#webOrder.getPriority()</td>
<td>#webOrder.WebOrderNumber</td>
<td>#webOrder.ExternalOrderNumber</td>
<td>#webOrder.CompanyName</td>
<td>#webOrder.getOverallStatus()</td>
<td data-date="#webOrder.dueDateISOFormat()">#webOrder.getDueDate()</td>
<td data-date="#webOrder.dateReceivedISOFormat()">#webOrder.DateReceived</td>
<td>#webOrder.CustomerName</td>
<td>#webOrder.OrderCost</td>
</tr>
}
</tbody>
#*The Order Modal*#
<div id="orderModal" class="modal">
#*Modal Content*#
</div>
Each row in the table has a click event handler that when fired will send an ajax call to a controller to return a partial view with detailed information about the order.
$.ajax({
type: "POST",
url: "/WebOrder/Details/",
data: { 'id': orderID },
dataType: "html",
success: function (response) {
$("#orderModal").html(response);
//modal.style.display = "block";
//Does more stuff
},
failure: function (response) {
alert(response.responseText);
},
error: function (response) {
alert(response.responseText);
}
});
public class WebOrderController : Controller
{
[HttpPost]
public IActionResult Details(int id)
{
WebOrder webOrder = SuperDAL.GetWebOrder(id);
webOrder.Parts = SuperDAL.GetPartsForWebOrder(webOrder.ID);
return PartialView("ModalPartial", webOrder);
}
}
The partial view returned from the Details controller is put in the orderModal div in the OrderTracking view.
By default, in my CSS I have that div hidden. When a row is clicked in the table, in the success part of the ajax call I unhide the div which is styled as a modal that pops up over the current page displaying more information about the order that was selected. The success section also applies other events to the modal.
Now the problem I'm trying to tackle is I would like to be able to display the modal with the partial view by just navigating in the URL bar to the OrderTracking controller and have it pull up the OrderTracking View as well as the modal and partial view. The URL would be something along the lines of domain/Home/OrderTracking/5 , where 5 would be the id of the order.
The reason for this is the end goal is to be able to have a qr code that will pull up an order when scanned by a qr reader, so the qr code would contain the url with the order number.
At the moment I'm having a hard time trying to conceptualize how I would achieve this. There are a few ways I have thought about being able to accomplish this by I don't believe they are right.
One way I thought about achieving this is to have an overloaded OrderTracking controller that uses a GET request. That controller will call the Details controller as well as returning the OrderTracking view, but while possibly do-able it most likely isn't the correct way to do it.
Another issue is that with the URL approach I cant fire off jQuery or JavaScript from the controller like I can in the ajax call that sets event handlers and other things. One way I though about dealing with this is to include a $(document).ready function in the partial view.
Let me know if I need to clarify anything.
A simple way to do this is to pass the orderID to your View and trigger the click event of the respective order in the table. This will trigger your post request and show the modal with the Partial View. i.e
Create a ViewModel:
public class OrderViewModel{
public int? OrderID { get; set; }
public List<WebOrder> Orders { get; set; }
}
Change your Action:
public class HomeController : Controller
{
public IActionResult OrderTracking(int? orderID)
{
List<WebOrder> orderList = SuperDAL.GetWebOrders();
foreach(WebOrder order in orderList)
{
order.Parts = SuperDAL.GetPartsForWebOrder(order.ID);
}
return View(new OrderViewModel(){ OrderID = orderID, Orders = orderList});
}
}
Trigger click event:
<script>
$(function(){
if(#Model.OrderID !=null){
//trigger click event
}
})
</script>
If you want to do so,you can add the partial view directly in the View,And like Siddanth says,pass OrderId to your view.So that you even don't need click button to add the partial view.You can change like this:
OrderModel:
public class OrderModel
{
public WebOrder SelectedOrder { get; set; }
public List<WebOrder> Orders { get; set; }
}
Controller:
public IActionResult OrderTracking(int? orderId)
{
OrderModel orderModel = new OrderModel();
List<WebOrder> orderList = SuperDAL.GetWebOrders();
foreach (WebOrder order in orderList)
{
order.Parts = SuperDAL.GetPartsForWebOrder(order.ID);
}
orderModel.Orders = orderList;
orderModel.SelectedOrder = new WebOrder();
if (orderId != null)
{
WebOrder webOrder = SuperDAL.GetWebOrder(id);
orderModel.SelectedOrder = webOrder;
}
return View(orderModel);
}
change Web
Order:
public int? ID { get; set; }
View:
<div id="orderModal" class="modal" >
#await Html.PartialAsync("ModalPartial", #Model)
</div>
<script type="text/javascript">
$(function () {
if (#Model.SelectedOrder.ID!=null) {
$("#orderModal").modal("show");
}
})
</script>

Why is my ViewData list null? MVC 4

I have two models, question and answer. I want to insert a list of answers thru ViewModel to a question but it seems in my post method my list is getting null. That might be a bad implementation as well, because I am returning a model of my question back when I post something and I guess my List is just getting null. How could I fix this?
Edit: I remade the controller and the view based on comments you gave me: Thats how it looks now, but seems my Answer List to be Empty again.
ViewModel:
public class ViewModel
{
public IEnumerable<Answer> Answers { get; set; }
public Question Question { get; set; }
}
Controller:
[Authorize]
public ActionResult Create()
{
ViewModel vm = new ViewModel();
ViewBag.BelongToTest = new SelectList(db.Tests, "TestId" , "TestTitle").FirstOrDefault();
vm.Question = new Question { Question_Text = String.Empty };
vm.Answers = new List<Answer> { new Answer { CorrectOrNot = false, AnswerText = "", OpenAnswerText = "" } };
return View(vm);
}
//
// POST: /Question/Create
[HttpPost]
[Authorize]
public ActionResult Create(ViewModel vm)
{
if (ModelState.IsValid)
{
vm.Question.BelongToTest = (from t in db.Tests
join m in db.Members on t.AddedByUser equals m.MemberId
where m.UserID == WebSecurity.CurrentUserId &&
t.AddedByUser == m.MemberId
orderby t.TestId descending
select t.TestId).FirstOrDefault();
db.Questions.Add(vm.Question);
db.SaveChanges();
if (vm.Answers != null)
{
foreach (var i in vm.Answers)
{
i.BelongToQuestion = vm.Question.QuestionId;
db.Answers.Add(i);
}
}
db.SaveChanges();
ViewBag.Message = "Data successfully saved!";
ModelState.Clear();
}
ViewBag.BelongToTest = new SelectList(db.Tests, "TestId", "TestTitle", vm.Question.BelongToTest);
vm.Question = new Question { Question_Text = String.Empty };
vm.Answers = new List<Answer> { new Answer { CorrectOrNot = false, AnswerText = "", OpenAnswerText = "" } };
return View("Create" , vm);
}
View:
#model MvcTestApplication.Models.ViewModel
#using MvcTestApplication.Models
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
#{
ViewBag.Title = "Create";
}
#using (Html.BeginForm("Create", "Question", FormMethod.Post)) {
<h2>Create</h2>
<table>
<tr>
<th>Question Name</th>
</tr>
<tr>
<td>#Html.EditorFor(model=>model.Question.Question_Text)</td>
</tr>
</table>
<table id="dataTable">
<tr>
<th>Correct?</th>
<th>Answer text</th>
<th>Open Answer</th>
</tr>
#foreach(var i in Model.Answers)
{
<tr>
<td>#Html.CheckBoxFor(model=>i.CorrectOrNot)</td>
<td>#Html.EditorFor(model=>i.AnswerText)</td>
<td>#Html.EditorFor(model=>i.OpenAnswerText)</td>
</tr>
}
</table>
<input type="button" id="addNew" value="Add Answer"/>
<input type="submit" value="Create" />
}
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
<script lang="javascript">
$(document).ready(function () {
//1. Add new row
$("#addNew").click(function (e) {
e.preventDefault();
var $tableBody = $("#dataTable");
var $trLast = $tableBody.find("tr:last");
var $trNew = $trLast.clone();
var suffix = $trNew.find(':input:first').attr('name').match(/\d+/);
$trNew.find("td:last").html('Remove');
$.each($trNew.find(':input'), function (i, val) {
// Replaced Name
var oldN = $(this).attr('name');
var newN = oldN.replace('[' + suffix + ']', '[' + (parseInt(suffix) + 1) + ']');
$(this).attr('name', newN);
//Replaced value
var type = $(this).attr('type');
if (type.toLowerCase() == "text") {
$(this).attr('value', '');
}
// If you have another Type then replace with default value
$(this).removeClass("input-validation-error");
});
$trLast.after($trNew);
// Re-assign Validation
var form = $("form")
.removeData("validator")
.removeData("unobtrusiveValidation");
$.validator.unobtrusive.parse(form);
});
// 2. Remove
$('a.remove').live("click", function (e) {
e.preventDefault();
$(this).parent().parent().remove();
});
});
</script>
}
For the ModelBinder to bind to a List the HTML form must be sequentially indexed.
Your
<td>#Html.CheckBoxFor(model=>a.CorrectOrNot)</td>
<td>#Html.EditorFor(model=>a.AnswerText)</td>
<td>#Html.EditorFor(model=>a.OpenAnswerText)</td>
is creating something that will be bound to an individual answer. You need to render HTML that will be bound to a List, something like
#for (int i = 0; i < ((List<Answer>)ViewData["Answers"]).Count; i++)
{
<tr>
<td>#Html.CheckBoxFor(model=>((List<Answer>)ViewData["Answers"])[i].CorrectOrNot)</td>
<td>#Html.EditorFor(model=>((List<Answer>)ViewData["Answers"])[i].AnswerText)</td>
<td>#Html.EditorFor(model=>((List<Answer>)ViewData["Answers"])[i].OpenAnswerText)</td>
</tr>
}
Also, this looks pretty awful casting ViewData all over the place. It would generally be better, if you plan to keep this approach creating a real view model. You could pass that model to the view and it could wrapper both question and answer collections.
EDIT:
You still need to have a sequential index against your list which your edited implementation is not supplying. Something like
#for (int i = 0; i < Model.Answers.Count; i++)
{
<tr>
<td>#Html.CheckBoxFor(model=> Model.Answers[i].CorrectOrNot)</td>
<td>#Html.EditorFor(model=> Model.Answers[i].AnswerText)</td>
<td>#Html.EditorFor(model=> Model.Answers[i].OpenAnswerText)</td>
</tr>
}
ViewData is relevant when going from the controller to the view. It won't post back.
You should relay on the (model / parameter) binding that will take care of passing List<Answer> answerList for you
ViewData is only to transfer the data between the view and controller. You can use session to transfer the data between the controller
Thanks for the comments. They really helped me out. It was all correct that you say but there was something that was missing. My IEnumerable in the ViewModel simply does not allow me to index my values, instead using IList helped me out to index everything as it is supposed to be and everything works.

why model posted to action Display in view?

have 2 action with same name.(AddNewUser) one of them work with HttpGet and another with HttpPost.
[HTTPGet]
public ActionResult AddNewUser()
{
User user = Utilities.SessionProvider.GetCurrentUser();
if (user.ID_User == 0)
return Redirect("Apps.kosarfci.ir");
RoleType role = (RoleType)RoleDeterminer.RoleDeterminate();
if (role != RoleType.Center)
{
return RedirectToAction("Restriction");
}
return View("VNewUser");
}
[HttpPost]
public ActionResult AddNewUser(VMNewUser InModel)
{
User user = Utilities.SessionProvider.GetCurrentUser();
if (user.ID_User == 0)
return Redirect("Apps.kosarfci.ir");
RoleType role = (RoleType)RoleDeterminer.RoleDeterminate();
if (role != RoleType.Center)
{
return RedirectToAction("Restriction");
}
IUserBL centerUserBL = new CenterUserBL();
InModel.User.UserName = InModell.User.NationalCode;
InModel.User.Password = InModell.User.PersonalCode;
bool confirmedBL = centerUserBL.AddUser(InModel.User);
_msgList.Add(new Message() { MsgType = MessageType.Success, MsgContent = MessageProvider.GetMessage(MessageContent.Submit_Success_NewUser) });
ViewBag.Message = _msgList;
return View("VNewUser");
}
AddNewUser() ,return a form with input entry and then form submited to AddNewUser(VMNewUser InModel). but after that a form with filled entry with posted model is displayed. i expect that a form with blank input entry display because i dont send pre-filled model(VMNewUser) in to the view.
why?
--VMNewUser--
#model PersonManagement.Views.User.VMNewUser
<style>
table{
font-family:Tahoma;
}
</style>
#using (Html.BeginForm("AddNewUser", "User", FormMethod.Post))
{
<table>
<tr>
<td>name</td>
<td>#Html.TextBoxFor(f=>f.User.FirstName)</td>
</tr>
<tr>
<td>family</td>
<td>#Html.TextBoxFor(f=>f.User.LastName)</td>
</tr>
<tr>
<td>personalcode</td>
<td>#Html.TextBoxFor(f=>f.User.PersonalCode)</td>
</tr>
<tr>
<td>nationalcode</td>
<td>#Html.TextBoxFor(f=>f.User.NationalCode)</td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="create" style="font-family:Tahoma;float:left" /></td>
</tr>
</table>
}
The main reason for sending back the populated model is to prevent the user from having to re-populate the form if there is an error processing the request server-side. It also provides the client with information about what fields failed and if there are any particular error messages that should be displayed.
It's recommended you use the PRG pattern therefore if the request is successful, you would redirect the user to a new page. In your case, you could redirect the user back to AddNewUser action which would present the user with the empty form again e.g.
return RedirectToAction("AddNewUser");
Way 1:
In your HttpPost method return to Action instead of returning view like this:
return RedirectToAction("AddNewUser");
Way 2:
or simply return View() without passing Model object which means null model and the fields will not be populated obviously:
return View();
Way 3 :
you can also do like this, if Model is valid save data and return View with empty fields, otherwise return view with populated data to user.
Like this :
[HttpPost]
public ActionResult AddNewUser(VMNewUser InModel)
{
if(ModelState.IsValid)
{
User user = Utilities.SessionProvider.GetCurrentUser();
if (user.ID_User == 0)
return Redirect("Apps.kosarfci.ir");
RoleType role = (RoleType)RoleDeterminer.RoleDeterminate();
if (role != RoleType.Center)
{
return RedirectToAction("Restriction");
}
IUserBL centerUserBL = new CenterUserBL();
InModel.User.UserName = InModell.User.NationalCode;
InModel.User.Password = InModell.User.PersonalCode;
bool confirmedBL = centerUserBL.AddUser(InModel.User);
_msgList.Add(new Message() { MsgType = MessageType.Success, MsgContent = MessageProvider.GetMessage(MessageContent.Submit_Success_NewUser) });
ViewBag.Message = _msgList;
return View();
}
else
{
return View(InModel);
}
}

I cannot get just the selected values from dropdownlists in my view back in my controller

I hava a view where I have a list of links, being each link a region where the companies has offices.
Everytime I select a region, I get a list of processes. For every process, I get a dropdowlist from where to choose a owner of the process and a list of checkboxs of tests to choose.
In my controller, I get string[] OwnerId as the values selected in the dropdowlists.
The thing is, I get all values from all dropdowlists, not just those that were selected. How can I get just the ones I selected??
This is my view
#using CTTModel
#using TestingTool.ViewModels
#model TestRunModel
#{
ViewBag.Title = "Create";
}
<h2>
Create</h2>
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<fieldset>
<legend>Regions</legend>
#foreach (Region region in Model.Regions)
{
#Html.ActionLink(#region.Name, "Create", new { id = region.Id })<br />
}
<div class="editor-field">
#foreach (ProcessModel process in Model.Processes)
{
<h1>#process.Name</h1>
**List<User> users = ViewBag.Users;
<select id="OwnerId" name="OwnerId" >
#foreach (User user in users)
{
<option value="#user.Id">#user.Name</option>
}
</select>**
<table>
<tr>
#{
int cnt = 0;
foreach (TestModel testModel in process.Tests)
{
if (cnt++ % 3 == 0)
{
#: </tr> <tr>
}
#: <td>
<input type="checkbox"
name="selectedTests"
value="#testModel.Id/#testModel.ProcessId/#testModel.RegionId"
#(Html.Raw(testModel.Active ? "checked=\"checked\"" : "")) />
#testModel.Name #:: #testModel.Description
#:</td>
}
#: </tr>
}
</table>
}
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
<fieldset>
<legend>Test Screen</legend>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
And this is my controller. The Create Post does nothing yet, I'm trying to get the right values first.
//
// GET: /TestPreparation/Create
public ActionResult Create(int id = 1)
{
TestRunModel testRunModel = new TestRunModel();
foreach (Region region in _db.Regions)
{
testRunModel.Regions.Add(region);
}
TestRun testRun = _db.TestRuns.OrderByDescending(x => x.Id).First();
foreach (TestRunProcessRegion region in testRun.GetProcessesForRegion(_db.Regions.Single(i => i.Id == id)))
{
ProcessModel process = new ProcessModel
{
Code = region.ProcessRegion.Process.Code,
Description = region.ProcessRegion.Process.Description,
Name = region.ProcessRegion.Process.Name,
Process = region.ProcessRegion.Process.Id
};
foreach (SubProcess subProcess in region.ProcessRegion.Process.SubProcesses)
{
foreach (Risk risk in subProcess.Risks)
{
foreach (Test test in risk.Tests)
{
TestModel testModel = new TestModel
{
Id = test.Id,
Name = test.Name,
Description = test.Description,
ProcessId = region.ProcessRegion.Process.Id,
RegionId = region.ProcessRegion.Id
};
process.Tests.Add(testModel);
}
}
}
testRunModel.Processes.Add(process);
}
var users = new List<User>();
foreach (User user in _db.Users)
{
users.Add(new User
{
Id = user.Id,
Name = user.Name,
});
}
ViewBag.Users = users;
return View(testRunModel);
}
//
// POST: /TestPreparation/Create
[HttpPost]
public ActionResult Create(string[] OwnerId, string[] selectedTests, string[] processes)
{
if (ModelState.IsValid)
{
//_db.TestRunStatus.Add(testrunstatus);
//_db.SaveChanges();
return RedirectToAction("Index");
}
return View();
}
The reason why you are not getting any data back is because the method signature of your Post Action needs to be
public ActionResult Create(string OwnerId ...) //preferably int depending on what OwnerId is
This is because you only select one item out of the drop down box. So if you use this signature as opposed to string[], the Model binder will pass the selected value back to your action.
Having said this, it is better practice and the "MVC Way" to use,
Html.DropDownFor(x => x.UserID) it really makes things easier :)
This applies to all html input controls:
http://www.asp.net/mvc/tutorials/getting-started-with-aspnet-mvc3/cs/examining-the-edit-methods-and-edit-view
UPDATE
I think the best thing to do would be to add an OwnerID to the ProccessModel class.
Becuase ProccessModel looks to be IEnumberable<ProccessModel> Processes contained in the ViewModel you can get the Model to Bind in the following way using the defult MVC model binder.
Phil Haack has bloged about binding to lists here:
http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx
Adapting from Phil's post I think you will have to do something like this:
<% for (int i = 0; i < Model.Processes.Count; i++) { %>
<%: Html.SelectListFor(model => model.Processes[i].OwnerID, (IEnumerable<SelectListItem>)ViewBag.Users) %>
<% } %>
Change the ViewBag.User to:
var users = _db.Users.Select(x => new SelectListItem(){
text = x.Name,
value = x.Value
});
Modify the Post Action:
[HttpPost]
public ActionResult Create(TestRunModel model)
{
foreach(var process in model.Porcesses)
{
process.OwnerID // This should be a user selected value
}
// code removed for brevity
}
I could help with getting the TestModel values if you like but I need to do some work now ;)

Ajax form not submitted when there are HTML tags in the input field

I've started playing with Ajax and found a (hopefully) little problem I can't seem to find an answer to.
I generate a list of Ajax forms on my page, the code looks like this
using (Ajax.BeginForm("FixTranslation", new { translationId = errorGroup.Key.Id }, new AjaxOptions { UpdateTargetId = "targetCell_" + errorList.Key.Id }))
{
<table>
<tbody>
<tr><td>#errorGroup.SourceText</td></tr>
<tr><td id="#("targetCell_" + errorGroup.Id)"><input type="text" name="text" id="#("target_" + errorGroup.Id)" value="#(errorGroup.TargetText.Replace(' ', (char)0x00A0))" /><input type="submit" value="Fix" /></td></tr>
#foreach (var error in errorGroup.Value)
{
<tr><td>#error.Description</td></tr>
}
</tbody>
</table>
}
In the controller I have this action:
public ActionResult FixTranslation(string projectId, int translationId, string text)
{
if (Request.IsAjaxRequest())
{
return Content("You entered: " + new HtmlString(text));
}
return RedirectToAction("GetProjectOverview", new { projectId = projectId });
}
This works fine when there are no angle brackets present in the input field, the form gets sent properly. But when there are some angle brackets (e.g. "This is text with <1>tags") in the input field, my action method does not get called at all.
Does anybody know why this is happening?
Thank you very much.
Solved. It was not specific to Ajax forms and the cause has been a request validation, which can be turned off in this way for a particular action method:
[ValidateInput(false)]
public ActionResult FixTranslation(string projectId, int translationId, string text)
{
...
}

Resources