I am looking for a way to validate two fields on ASP View page. I am aware that usual way of validating form fields is to have some #model ViewModel object included on a page, where the properties of this model object would be annotated with proper annotations needed for validation. For example, annotations can be like this:
[Required(ErrorMessage = "Please add the message")]
[Display(Name = "Message")]
But, in my case, there is no model included on a page, and controller action that is being called from the form receives plane strings as method arguments.
This is form code:
#using (Html.BeginForm("InsertRssFeed", "Rss", FormMethod.Post, new { #id = "insertForm", #name = "insertForm" }))
{
<!-- inside this div goes entire form for adding rssFeed, or for editing it -->
...
<div class="form-group">
<label class="col-sm-2 control-label"> Name:</label>
<div class="col-sm-10">
<div class="controls">
#Html.Editor("Name", new { htmlAttributes = new { #class = "form-control", #id = "add_rssFeed_name" } })
</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label"> URL:</label>
<div class="col-sm-10">
<div class="controls">
#Html.Editor("Url", new { htmlAttributes = new { #class = "form-control", #id = "add_rssFeed_Url" } })
</div>
</div>
</div>
</div>
</div>
<!-- ok and cancel buttons. they use two css classes. button-styleCancel is grey button and button-styleOK is normal orange button -->
<div class="modal-footer">
<button type="button" class="button-styleCancel" data-dismiss="modal">Close</button>
<button type="submit" class="button-styleOK" id="submitRssFeed">Save RSS Feed</button>
</div>
}
You can see that form is sending two text fields (Name and Url) to the RssController action method, that accepts these two string parameters:
[HttpPost]
public ActionResult InsertRssFeed(string Name, string Url)
{
if (!String.IsNullOrEmpty(Name.Trim()) & !String.IsNullOrEmpty(Url.Trim()))
{
var rssFeed = new RssFeed();
rssFeed.Name = Name;
rssFeed.Url = Url;
using (AuthenticationManager authenticationManager = new AuthenticationManager(User))
{
string userSid = authenticationManager.GetUserClaim(SystemClaims.ClaimTypes.PrimarySid);
string userUPN = authenticationManager.GetUserClaim(SystemClaims.ClaimTypes.Upn);
rssFeedService.CreateRssFeed(rssFeed);
}
}
return RedirectToAction("ReadAllRssFeeds", "Rss");
}
If the page would have model, validation would be done with #Html.ValidationSummary method, but as I said I am not using modelview object on a page.
Is there a way to achieve this kind of validation without using ModelView object, and how to do that? Thanks.
If you are looking for server side validation you can use something like below using
ModelState.AddModelError("", "Name and Url are required fields.");
but you need to add
#Html.ValidationSummary(false)
to your razor view inside the Html.BeginForm section, then code will looks like below.
[HttpPost]
public ActionResult InsertRssFeed(string Name, string Url)
{
if (String.IsNullOrEmpty(Name.Trim()) || String.IsNullOrEmpty(Url.Trim()))
{
ModelState.AddModelError("", "Name and URL are required fields.");
return View();
}
var rssFeed = new RssFeed();
rssFeed.Name = Name;
rssFeed.Url = Url;
using (AuthenticationManager authenticationManager = new AuthenticationManager(User))
{
string userSid = authenticationManager.GetUserClaim(SystemClaims.ClaimTypes.PrimarySid);
string userUPN = authenticationManager.GetUserClaim(SystemClaims.ClaimTypes.Upn);
rssFeedService.CreateRssFeed(rssFeed);
}
return RedirectToAction("ReadAllRssFeeds", "Rss");
}
If you are looking for only client side validation, then you have to use client side validation library like Jquery.
http://runnable.com/UZJ24Io3XEw2AABU/how-to-validate-forms-in-jquery-for-validation
Edited section for comment
your razor should be like this.
#using (Html.BeginForm("InsertRssFeed", "Rss", FormMethod.Post, new { #id = "insertForm", #name = "insertForm" }))
{
#Html.ValidationSummary(false)
<div class="form-group">
<label class="col-sm-2 control-label"> Name:</label>
<div class="col-sm-10">
<div class="controls">
#Html.Editor("Name", new { htmlAttributes = new { #class = "form-control", #id = "add_rssFeed_name" } })
</div>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label"> URL:</label>
<div class="col-sm-10">
<div class="controls">
#Html.Editor("Url", new { htmlAttributes = new { #class = "form-control", #id = "add_rssFeed_Url" } })
</div>
</div>
</div>
</div>
</div>
<!-- ok and cancel buttons. they use two css classes. button-styleCancel is grey button and button-styleOK is normal orange button -->
<div class="modal-footer">
<button type="button" class="button-styleCancel" data-dismiss="modal">Close</button>
<button type="submit" class="button-styleOK" id="submitRssFeed">Save RSS Feed</button>
</div>
}
Hope this helps.
Related
The resource cannot be found.
Requested URL: /Home/Home/Signup_User
However it should be /Home/Signup_User
where Home is the controller and Signup_User is the function in Home Controller.I have checked the spelling its correct.
My Sign Up Form as follows.
<form action="~/Home/Signup_User" method="post" enctype="multipart/form-data">
#Html.AntiForgeryToken()
<div class="row">
<div class="large-6 columns">
<label>
Enter Name
#Html.EditorFor(model => model.username, new { htmlAttributes = new { #class = "form-control" } })
</label>
</div>
<div class="large-6 columns">
<label>
Enter Age
#Html.EditorFor(model => model.age, new { htmlAttributes = new { #class = "form-control" } })
</label>
</div>
<div class="large-6 columns">
<label>
Enter Email Address
#Html.TextBoxFor(model => model.email, new { #class = "large-12", placeholder = "xyz#gmail.com", type = "email" })
</label>
</div>
<div class="large-6 columns">
<label>
Enter Password
#Html.PasswordFor(model => model.password, new { })
</label>
</div>
</div>
<br />
<hr />
<button type="submit" class="button tiny right" style="margin-left:5px;color:white;">Submit</button>
Cancel }
<a class="close-reveal-modal" aria-label="Close">×</a>
</form>
FormExtensions (with Controller and ActionName)
#using (Html.BeginForm("Signup_User", "Home", FormMethod.Post))
{
}
FormExtensions (with Controller , ActionName and Area )
#using (Html.BeginForm("Signup_User", "Home", FormMethod.Post, new { area = "AreaName" }))
{
}
Try replacing
action="~/Home/Signup_User"
with
action="#Url.Action("Signup_User", "Home")"
You just need to add Controller name slash action name, no need to add ~
Refer following code for Solution 1:
<form action="/Home/Signup_User" method="post" enctype="multipart/form-data">
//Add rest of your code
</form>
Else, use MVC's built in HTML helper to render the form and put your rest of the code into same.
#using (Html.BeginForm("Signup_User", "Home", FormMethod.Post))
{
// Add your rest of code
}
Above code will generate empty tag.
It seems you are using relative path in action URL . that's why Home Added twice like this.
/Home/Home/Signup_User
Asp.net MVC come up with beautiful Form Extensions.Just you need to specify Controller Name, Action Method Name and Area name if any.
for e.g.
#using (Html.BeginForm("actionName", "controllerName", new {area = "AreaName"}))
In your case
ActionName :"Signup_User"
ControllerName:"Home"
Assuming, you don't have no area defined. replace your piece code with below snippet. it will resolve your issue.
CODE:
#using (Html.BeginForm("Signup_User", "Home"))
#Html.AntiForgeryToken()
<div class="row">
<div class="large-6 columns">
<label>
Enter Name
#Html.EditorFor(model => model.username, new { htmlAttributes = new { #class = "form-control" } })
</label>
</div>
<div class="large-6 columns">
<label>
Enter Age
#Html.EditorFor(model => model.age, new { htmlAttributes = new { #class = "form-control" } })
</label>
</div>
<div class="large-6 columns">
<label>
Enter Email Address
#Html.TextBoxFor(model => model.email, new { #class = "large-12", placeholder = "xyz#gmail.com", type = "email" })
</label>
</div>
<div class="large-6 columns">
<label>
Enter Password
#Html.PasswordFor(model => model.password, new { })
</label>
</div>
</div>
<br />
<hr />
<button type="submit" class="button tiny right" style="margin-left:5px;color:white;">Submit</button>
Cancel }
<a class="close-reveal-modal" aria-label="Close">×</a>
</form>
One reason this could occur is if you don't have a start page set under your web project's properties. So do this:
Right click on your mvc project
Choose "Properties"
Select the "Web" tab
Select "Specific Page"
Assuming you have a controller called HomeController and an action method called Index, enter "home/index" in to the text box corresponding to the "Specific Page" radio button.
Now, if you launch your web application, it will take you to the view rendered by the HomeController's Index action method.
I'm working on an application that uses a View Model to pass data to a view, however when I attempt to save changes the user makes to the data and post it back to the controller for processing and storing in a database, I'm getting null values for everything in my view model. I've tried various other questions on here and none of the answers I've found have been able to solve this issue. I think it has something to do with the my use of a ListBox to display some of the data, but I'm fairly new to ASP.net MVC 5 and am not quite sure what I need to be doing here.
Below is the code for my view model, the relevant sections from the controller, and the view.
View Model
public class OrganizationViewModel
{
public Organization Organization { get; set; }
public IEnumerable<SelectListItem> RelatedContacts { get; set; }
}
Sending Data from Controller to View
[HttpGet]
public ActionResult Edit(Organization organization)
{
IEnumerable<SelectListItem> contactsList = GetContacts(organization);
var viewModel = new OrganizationViewModel()
{
Organization = organization,
RelatedContacts = contactsList
};
return View("Edit", viewModel);
}
Receiving Data from View
[HttpPost]
public ActionResult SaveOrganization(OrganizationViewModel organizationViewModel)
{
organizationViewModel.Organization.Id = (int)TempData["Id"];
organizationViewModel.Organization.LastEdited = DateTime.Today;
organizationViewModel.Organization.DateAdded = (DateTime)TempData["DateAdded"];
TempData.Clear();
if (ModelState.IsValid)
{
organizationRepository.SaveOrganization(organizationViewModel.Organization);
return RedirectToAction("Index", "Organization");
}
IEnumerable<SelectListItem> contactsList = GetContacts(organizationViewModel.Organization);
var viewModel = new OrganizationViewModel()
{
Organization = organizationViewModel.Organization,
RelatedContacts = contactsList
};
return View("Edit", viewModel);
}
The Edit View
<div class="panel">
<div class="panel-heading">
<h3>Editing #(Model.Organization.Name)</h3>
</div>
#using (Html.BeginForm("SaveOrganization", "Organization", FormMethod.Post))
{
<div class="panel-body">
#Html.HiddenFor(m => Model.Organization.Name)
<div class="row">
<div class="col-md-3 form-group">
<label>Organization Name</label>
#Html.TextBox("Name", null, new { #class = "form-control" })
</div>
<div class="col-md-3 form-group">
<label>Address</label>
#Html.TextArea("Address", null, new { #class = "form-control" })
</div>
</div>
<div class="row">
<div class="col-md-3 form-group">
<label>Related Contacts</label>
#Html.ListBox("RelatedContacts", Model.RelatedContacts, new { #class = "form-control", size = 10 })
</div>
<div class="col-md-3 form-group">
<label>Custom Fields</label>
<br />
<input type="button" value="Add New Field" class="btn btn-default" />
</div>
</div>
<div class="row">
<div class="col-md-12 form-group">
<label>Notes</label>
#Html.TextArea("Notes", null, 10, 500, new { #class = "form-control", #style = "width: 100%; max-width: 100%;" })
</div>
</div>
</div>
<div class="panel-footer">
<input type="submit" value="Save" class="btn btn-primary" />
#Html.ActionLink("Cancel and return to List", "CancelEditOrAdd", null, new { #class = "btn btn-default" })
</div>
}
Answering my own question for anyone who stumbles across this and wants to see the exact changes I made based on #Stephen Muecke's comments.
Changed all the #html.something()s into #html.somethingfor()s for fixed the issue with not receiving postback data for the Organization in the View Model, and then I created a new property in the view model to correspond with the selected index in the ListBox, which now reads #Html.ListBoxFor(m => m.SelectedIndexes, Model.RelatedContacts, ...). I'm now getting all the proper postback data and can relate the selected index to the Organization's related contacts.
Edit: Also changed my View Model to contain the properties of my Organization class and not an actual Organization object itself as a property.
I have two buttons but I'm only able to validate one. When the user clicks add and the entire form is not filled out then they get error message but if they click finish instead of giving error messages, it goes to another page but I want to give the error before going to that page. This is what I have so far for one:
#model student.Models.Student
<h2>Student Record</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Issue</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.studentNumber, htmlAttributes: new { #class = "col-md-2" })
#Html.EditorFor(model => model.studentNumber, new { htmlAttributes = new { #readonly = "readonly", #id = "reqnum", #class = "form-control" } })
</div>
<div class="form-group">
#Html.LabelFor(model => model.Name, htmlAttributes: new { #class = "col-md-2" })
#Html.ValidationMessageFor(model => model.name, "", new { #class = "text-danger" })
</div>
<div class="form-group">
#Html.Label("Processed by:", htmlAttributes: new { #class = "col-md-2" })
#Html.DropDownListFor(model => model.processedbyDetails.employeeNum, new SelectList(ViewBag.StoresReps, "Value", "Text"), new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.processedbyDetails.employeeNum, "", new { #class = "text-danger" })
</div>
#* -- MANY OTHER INPUTS -- *#
<div class="form-group">
<div class="col-md-offset-4 col-md-12">
<input type="submit" value="Add" name="Add" class="btn btn-default" width="89" />
<input type="button" value="Finish" name="Issue" margin="50px" onclick="location.href='#Url.Action("ViewIssue", "Issue")' " class="btn btn-default" />
<input type="button" value="Cancel" name="Cancel" margin="50px" onclick="location.href='#Url.Action("Cancel", "Issue")' " class="btn btn-default" />
</div>
</div>
</div>
}
Edit
#{
ViewBag.Title = "Student Item";
}
<!-- JS includes -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<script src="//ajax.aspnetcdn.com/ajax/jquery.validate/1.11.1/jquery.validate.min.js"></script>
<script src="//ajax.aspnetcdn.com/ajax/mvc/4.0/jquery.validate.unobtrusive.min.js"></script>
<script type="text/javascript">
<script type="text/javascript">
function onFinishClick() {
if ($('form').valid()) {
location.href = '#Url.Action("ViewIssue", "Issue")';
}
return false;
}
</script>
<input type="button" value="Finish" name="Issue" margin="50px" onclick="onFinishClick()" class="btn btn-default" />
You're using MVC, so just annotate your ViewModel and submit the form with the built in functionality that the framework supplies for you.
public class Student
{
[StringLength(100)]
[DisplayName("Student Name")]
[Required(ErrorMessage = "Please enter a Student Name")]
public string Name { get; set; }
[StringLength(100)]
[DisplayName("Student Number")]
[Required(ErrorMessage = "Please enter a Student Number")]
public string StudentNumber { get; set; }
// etc...
}
Your form should also have the name of the Action you're trying to POST to...
#using (Html.BeginForm("AddOrFinish", "HomeController", FormMethod.Post, new { role = "form" }))
You can't validate against the data annotations on your viewmodel in MVC from a button that's not of type submit (well, maybe you can, but probably more work).
You should then mark both buttons as type submit, then interrogate the name of the button that was clicked once it is sent over.
<div class="form-group">
<div class="col-md-offset-4 col-md-12">
<input type="submit" value="Add" name="add" class="btn btn-default" width="89" />
<input type="submit" value="Finish" name="issue" margin="50px" class="btn btn-default" />
<input type="button" value="Cancel" name="Cancel" margin="50px" onclick="location.href='#Url.Action("Cancel", "Issue")' " class="btn btn-default" />
</div>
</div>
Then in your controller, create a method with this signature. Since you have two submit buttons, the values of the button will be sent along in the request and you can interrogate it. It will look something like this...
[HttpPost]
public ActionResult AddOrFinish(Student model, string add, string issue)
{
if (!ModelState.IsValid)
{
return RedirectToAction("PageImOnNow", model);
}
if (!string.IsNullOrEmpty(add))
{
// do your add logic
// redirect to some page when user clicks "Add"
return RedirectToAction("WhateverPageYouWant");
}
else
{
// do your finish logic
// redirect to ViewIssue page when user clicks "Finish"
return RedirectToAction("ViewIssue");
}
}
More information here -
Handling multiple submit buttons on a form in MVC
Best Practices for ViewModel validation in MVC
Here's the view which I'm using to enter the multiline article
I wish that you can also told me how to save the text properties such as bold italic too because it makes me very confused.
#model WEBSITI.Models.article
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
#using (Html.BeginForm( "Create", null, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div class="form-group">
#Html.LabelFor(model => model.bodyofarticle, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.bodyofarticle, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.bodyofarticle, "", new { #class = "text-danger" })
</div>
<input type="file" id="file" name="file" />
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
When a form is submitted, the asp.met mvc framework will inspect the request body to see whether it has any potentially dangerous content as HTML markup(Think about script injection). If it detects any dangerous content,the Request Validation module will throw an error. This is by design
To explicitly allow the form posting with Html tags inside the property value, you may decorate your specific property with the AllowHtml attribute
public partial class article
{
[AllowHtml]
public string bodyofarticle { set; get; }
//other properties here
}
This will tell the framework to exclude this property from the above request validation.
I suggest you follow PascalCasing while writing C# code ( Ex : Article instead of article)
I want to retrieve data from a view, it should work like this:
User fill a form available on the webpage
User clicks SEARCH button
Some function(s) collect the data and display them in another view
I tried all the basic tutorials and tips on others stackoverflow question but it still doesn't work. I don't know what I'm doing wrong...
Here's my code from the view:
section id="roomSearch">
<div class="banner">
<div class="banner-info">
<div class="container">
<div class="details-1">
#using (Html.BeginForm("UploadRoomSearchData", "HomeController", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div class="col-md-10 dropdown-buttons">
<div class="col-md-3 dropdown-button">
#Html.AntiForgeryToken()
<div class="input-group">
#Html.TextBoxFor(m => m.YourName, new { #class = "form-control has-dark-background", #placeholder = "Imię" })
#Html.ValidationMessageFor(m => m.YourName, "", new { #class = "text-danger" })
<!--<input class="form-control has-dark-background"
name="slider-name" id="slider-name" placeholder="Imię" type="text" required="">-->
</div>
</div>
<!---strat-date-piker---->
<link rel="stylesheet" href="~/Content/jquery-ui.css" />
<script src="~/Scripts/jquery-ui.js"></script>
<script>
$(function () {
$("#datepicker,#datepicker1").datepicker();
});
</script>
<!---/End-date-piker---->
<div class="col-md-3 dropdown-button">
<div class="book_date">
<form>
<input class="date" id="datepicker" type="text" value="Przyjazd" onfocus="this.value = '';" onblur="if (this.value == '') {this.value = 'Przyjazd';}">
<!-- #Html.TextBoxFor(m => m.CheckIn, new { #class = "date" })
#Html.ValidationMessageFor(m => m.CheckIn, "", new { #class = "datefield" })-->
</form>
</div>
</div>
<div class="col-md-3 dropdown-button">
<div class="book_date">
<form>
<input class="date1" id="datepicker1" type="text" value="Wyjazd" onfocus="this.value = '';" onblur="if (this.value == '') {this.value = 'Wyjazd';}">
<!--#Html.TextBoxFor(m => m.CheckOut, new { #class = "date1" })
#Html.ValidationMessageFor(m => m.CheckOut, "", new { #class = "datefield" })-->
</form>
</div>
</div>
<div class="col-md-3 dropdown-button">
<div class="section_1">
<select id="country" onchange="change_country(this.value)" class="frm-field required">
<option value="null">Dwuosobowy</option>
<option value="null">Jednoosobowy</option>
<option value="AX">Apartament</option>
<option value="AX">Gościnny</option>
</select>
</div>
</div>
<div class="clearfix"> </div>
</div>
<div class="col-md-2 submit_button">
<form >
<input type="submit" value="SZUKAJ">
<!-- <p> #Html.ActionLink("SZUKAJ", "Book1", "Home")</p>-->
</form>
</div>}
And here's my code in the controller. For now I try to retrieve only a name, to see if it's working.
[HttpPost]
public ActionResult UploadRoomSearchData(FormCollection form)
{
string name = Request["YourName"].ToString();
StringBuilder sbRoom = new StringBuilder();
sbRoom.Append("<b>Amount :</b> " + name + "<br/>");
//return RedirectToAction("Book1");
return Content(sbRoom.ToString());
}
I also tried something like this:
foreach(var v in form)
{
Write.Response("name:" + v);
}
I tried your code and it seems to work.
First I have the controller method to display the form
public ActionResult CreatePerson()
{
Person model = new Person();
return View(model);
}
Then the form:
#model RetrieveDataFromaView.Models.Person
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Person</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.YourName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.YourName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.YourName, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="submit" class="btn btn-default" />
</div>
</div>
</div>
}
Which does a post to the controller method
[HttpPost]
public ActionResult CreatePerson(FormCollection formCollection)
{
string name = Request["YourName"].ToString();
StringBuilder sbRoom = new StringBuilder();
sbRoom.Append("<b>Amount :</b> " + name + "<br/>");
return Content(sbRoom.ToString());
}
This returns a view with only the content of the StringBuilder.
Maybe you are looking for RedirectToAction?
Hello you have this line inside the form:
#Html.AntiForgeryToken()
You can remove it or add the corresponding attribute to use it:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult CreatePerson(FormCollection formCollection)
{
///Your code here
}
Basically this is a token generated for the server to avoid requests from forms not generated by the server.
You have many ways of retrieving data from a form Post in ASP.NET MVC.
Using a Model
Usually, forms are created by specifying a Model type in the Razor view. You can use that type to retrieve the data. ASP.NET MVC will parse the body and populate the object in parameter for you.
Ex:
Controller:
public class HomeController: Controller
{
[HttpGet]
public ActionResult Index()
{
return View(new Person());
}
[HttpPost]
public ActionResult Index(Person p)
{
//Just for the sake of this example.
return Json(p);
}
}
Razor view
#model WebApplication2.Models.Person
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<title>title</title>
</head>
<body>
<div>
#using (Html.BeginForm("Index", "Home", FormMethod.Post))
{
#Html.AntiForgeryToken()
<div>
#Html.LabelFor(m => m.FirstName): <br/>
#Html.TextBoxFor(m => m.FirstName)
</div>
<div>
#Html.LabelFor(m => m.LastName): <br/>
#Html.TextBoxFor(m => m.LastName)
</div>
<input type="submit" value="Submit" />
}
</div>
</body>
</html>
Using a FormsCollection
The FormsCollection object allows you to access the raw values of a form. It acts as a Dictionary for the Forms value. This is useful, especially when you have a dynamic model to parse, or if you just plain don't know about the Model type.
It's also pretty straightforward to use.
[HttpPost]
public ActionResult Index(FormCollection form)
{
var dict = form.AllKeys.ToDictionary(key => key, key => form[key]);
return Json(dict);
}
PS: I saw you are using Request[key]. It may just be me, but this call just looks like Dark magic, where you get data from who knows where (it uses the Query String, the cookies, the Request body, etc. It seems like it could be really problematic in some cases in the future. I much prefer knowing exactly where the data comes from. But that may just be me.
Conclusion
In conclusion, use the Model approach if you know exactly what should be in the Form. Use the FormCollection approach if you really need to. That's pretty much it.
Good luck.