I've built a page, where master and details(pictures, aso) are shown on one page. However, if the submitt button for the second form is clicked, the form is not submitted, if validations in the first form fail. If I correct the values, the HttpPostedFileBase uploadFile is null.
The page looks like this:
#model app1.Models.MasterModel
#{
ViewBag.Title = "Edit";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#using (Html.BeginForm(new { #class = "form-inline col-lg-12" }))
{
#Html.AntiForgeryToken()
<div>
<h4>MasterModel</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.Id)
<div class="row">
#*Master properties*#
<div class="col-md-4 col-lg-4">
<div class="form-horizontal">
<div class="form-group">
#Html.LabelFor(model => model.Title, htmlAttributes: new { #class = "control-label col-md-3" })
<div class="col-md-8">
#Html.EditorFor(model => model.Title, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Title, "", new { #class = "text-danger" })
</div>
</div>
#* aso... *#
</div>
</div>
}
#* Master Details *#
<div class="col-md-4 col-lg-4">
#using (Html.BeginForm("NewPic", "Master", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<input name="uploadFile" type="file" />
<input type="submit" value="Upload File" /> <!-- First Button, does not work -->
<div class="container-fluid">
#foreach (app1.Models.PicModel b in Model.Pics)
{
var base64 = Convert.ToBase64String(b.DbPic);
var imgSrc = String.Format("data:image/gif;base64,{0}", base64);
<img src="#imgSrc" width="200" height="200" />
}
</div>
#Html.ActionLink("Upload", "NewPic", new { id = Model.Id }) <!-- Second Button, does not work either -->
<label class="control-label col-md-4 col-lg-4" for="Title">Picer</label>
}
</div>
</div>
<div>
<div class="form-group">
<div class="col-md-offset-2 col-md-12 col-lg-12">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
The controller looks like this:
public ActionResult NewPic(int id, HttpPostedFileBase uploadFile)
{
// uploadFile is null
}
You forgotten to put [HttpPost] before NewPic method. So NewPic method will be considered as [HttpGet] so it will not work.
[HttpPost]
public ActionResult NewPic(int id, HttpPostedFileBase uploadFile)
{
// uploadFile is null
}
And also give proper Id to both form as follow so it would be easy to work with this both while client side validation.
Form 1
#using (Html.BeginForm(new {id = "Form1", #class = "form-inline col-lg-12" }))
Form 2
#using (Html.BeginForm("NewPic", "Master", FormMethod.Post, new { id = "Form2", enctype = "multipart/form-data" }))
For more information visit here
Related
I am using two viewbags to get the same list(List of tags) on get request these viewbags are showing list as a dropdown but when I submit the page (post request) they are binding the 0 values(no matter what I select from the dropdown list) with the object in the controller but when I used only the single dropdown list it binding its value with an object in the controller?
[HttpGet]
public ActionResult CreateNewTotalizerTag()
{
//This is RawTag List
var RawTaglist1 = cRTu.RawTagsList();
ViewBag.RawTaglist1 = new SelectList(RawTaglist1, "Real_Tag_Id", "R_Tag_Name");
//This is RawTag List
var RawTaglist2 = cRTu.RawTagsList();
ViewBag.RawTaglist2 = new SelectList(RawTaglist2, "Real_Tag_Id", "R_Tag_Name");
return View();
}
//Controller
[HttpPost]
public ActionResult CreateNewTotalizerTag(RawTagVM rawTagVM)
{
return View(rawTagVM);
}
#using (Html.BeginForm("CreateNewTotalizerTag", "TotalizerTags", FormMethod.Post))
{
#Html.HiddenFor(x=>x.Real_Tag_Id)
<div class="container-fluid">
<div class="row">
<div class="col-md-3">
</div>
<div class="col-md-6">
<!-- general form elements disabled -->
<div class="card card-warning">
<div class="card-header" style="background-color:#343a40">
<h3 class="card-title" style="color:white">Create Totalizer Tag</h3>
</div>
<!-- This form is to create Raw tag totalizer onPrem or onCloud -->
<div class="card-body">
<form role="form">
<div class="row">
<div class="col-sm-6">
<div class="form-group">
<div class="custom-control custom-switch">
#Html.CheckBoxFor(m => m.Is_Cloud_Totalizer, new { #class = "custom-control-input", id = "Is_Cloud_Totalizer" })
<label class="custom-control-label" for="Is_Cloud_Totalizer">Is Cloud Totalizer?</label>
</div>
</div>
</div>
</div>
<!-- On Cloud Inputs starts here -->
<div id="oncloud_totalizer" style="display:none">
<div class="row">
<div class="col-sm-6">
<div class="form-group">
<label>Enter Tag Name</label>
#Html.EditorFor(m => m.R_Tag_Name, new { htmlAttributes = new { #class = "form-control" } })
#*#Html.ValidationMessageFor(model => model.R_Tag_Name, "", new { #class = "text-danger" })*#
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label>Select Raw Tag</label>
#Html.DropDownListFor(m => m.Real_Tag_Id_Cloud, (IEnumerable<SelectListItem>)ViewBag.RawTaglist1, "Select Raw Tag", new { #class = "form-control", id = "Raw_Tag_List1" })
</div>
</div>
</div>
</div>
<!-- On Prem Inputs starts here -->
<div class="row" id="onPrem_totalizer">
<div class="col-sm-6">
<div class="form-group">
<label>Select Raw Tag</label>
#Html.DropDownListFor(m => m.Real_Tag_Id, (IEnumerable<SelectListItem>)ViewBag.RawTaglist2, "Select Raw Tag", new { #class = "form-control", id = "Raw_Tag_List2" })
</div>
</div>
</div>
<div class="form-group">
<center><button type="submit" class="btn btn-primary">Create Totalizer</button></center>
</div>
</form>
</div>
<!-- /.card-body -->
</div>
<!-- /.card -->
<!-- general form elements disabled -->
<!-- /.card -->
</div>
</div>
</div>
}
<script>
$(document).ready(function () {
// Initialize select2
//$("#Raw_Tag_List1").select2();
//$("#Raw_Tag_List2").select2();
//$("#Source_Tag_List").select2();
$("#Is_Cloud_Totalizer").change(function () {
if (this.checked) {
$("#oncloud_totalizer").show();
$("#onPrem_totalizer").hide();
}
else {
$("#onPrem_totalizer").show();
$("#oncloud_totalizer").hide();
}
});
});
</script>
You could assign the viewbag properties on postback aswell. Viewbag properies are used in the view (cshtml) for rendering the page, the resulting rendered HTML page that is sent to the client does not know them, and also they are not sent back to the server together with form data on post back.
//Controller
[HttpPost]
public ActionResult CreateNewTotalizerTag(RawTagVM rawTagVM)
{
var RawTaglist1 = cRTu.RawTagsList();
ViewBag.RawTaglist1 = new SelectList(RawTaglist1, "Real_Tag_Id", "R_Tag_Name");
//This is RawTag List
var RawTaglist2 = cRTu.RawTagsList();
ViewBag.RawTaglist2 = new SelectList(RawTaglist2, "Real_Tag_Id", "R_Tag_Name");
return View(rawTagVM);
}
You might try to assign the drop down a list of SelectListItem
ViewBag.RawTaglist1 = RawTaglist1.Select(x => new SelectListItem()
{
Value = x.Real_Tag_Id.ToString(),
Text = x.R_Tag_Name
}).ToList();
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 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.
I have the following view:
#model GRCWebApp.ViewModels.NewClubInterestsViewModel
#{
ViewBag.Title = "Add Club Interests";
}
<div class="col-md-10 col-offset-md-1">
<h2 class ="text-success">Add Club Interests for #Html.DisplayFor(model => model.Name)</h2>
</div>
#using (Html.BeginForm("NewInterests", "Club", FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
<div class="row">
<div class="col-md-8">
<div class="well bs-component">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(x => Model.ClubId)
<div class="form-group">
<div class="col-md-10 col-md-offset-1">
<h3>Tick the areas your club is interested/runs events in</h3>
</div>
</div>
<div class="col-md-offset-1">
#for (int i = 0; i < Model.ClubTypeInterests.Count(); i++)
{
<div>
#Html.HiddenFor(x => Model.ClubTypeInterests[i].InterestId)
#Html.CheckBoxFor(x => Model.ClubTypeInterests[i].selected)
#Html.LabelFor(x => Model.ClubTypeInterests[i].InterestName, Model.ClubTypeInterests[i].InterestName)
</div>
}
</div>
<div class="form-group">
<div class="row">
<div class="col-md-offset-1 col-md-12">
<input type="submit" name="Submit" value="Next" class="btn btn-success btn-lg" /> to setup Online membership
<input type="submit" name="Submit" value="Complete" class="btn btn-warning btn-sm" /> to just provide online event entries
</div>
</div>
</div>
</div>
</div>
</div>
</div>
}
#using (Html.BeginForm("AddInterest", "Club"))
{
#Html.AntiForgeryToken()
<hr />
<div class="row">
<div class="col-md-8">
<div class="well bs-component">
<div class="form-group">
<div class="col-md-12 col-md-offset-1">
<h3>Not listed? - Add extras here</h3>
</div>
</div>
#Html.HiddenFor(model => model.ClubTypeId)
#Html.HiddenFor(model => model.ClubId)
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-inline">
<div class="form-group">
<div class="row col-md-offset-1 col-md-11">
<div class="col-md-4">
#Html.LabelFor(model => model.InterestName, htmlAttributes: new { #class = "control-label" })
#Html.EditorFor(model => model.InterestName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.InterestName, "", new { #class = "text-danger" })
</div>
<div class="col-md-5">
#Html.LabelFor(model => model.Description, htmlAttributes: new { #class = "control-label" })
#Html.EditorFor(model => model.Description, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Description, "", new { #class = "text-danger" })
</div>
<input type="submit" value="Add" class="btn btn-info" style="margin-top: 22px" />
</div>
</div>
</div>
</div>
</div>
</div>
}
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
Overtime the page loads the Validation message shows for InterestName in the second form AddInterest.
The Get method for the whole form is:
[HttpGet]
public ActionResult NewInterests(NewClubInterestsViewModel model, int id)
{
//Find the Club and then pass its id to the ViewModel
var club = db.Clubs.Find(id);
//model.ClubId = club.ClubId ;
//Interests List
IEnumerable<Interest> allExistingInterests;
//Generate a list of the interests that apply to that type of club
using (ApplicationDbContext context = new ApplicationDbContext())
{
allExistingInterests = context.Interests
.Where(s => s.ClubTypeId == club.ClubTypeId)
.OrderBy(s => s.InterestName)
.ToList();
}
IEnumerable<int> clubInterestIds = club.ClubInterests.Select(x => x.InterestId).ToList();
//Generate the ViewModel with the appropriate Interests
var viewModel = new NewClubInterestsViewModel
{
ClubId = club.ClubId,
Name = club.Name,
ClubTypeId = club.ClubTypeId,
ClubTypeInterests =
allExistingInterests.Select(
x => new ClubInterestsViewModel { InterestId = x.InterestId, InterestName = x.InterestName, selected = clubInterestIds.Contains(x.InterestId) }).ToArray()
};
return View(viewModel);
}
What do I need to do to stop the validation message showing on load?
Remove the NewClubInterestsViewModel model parameter from your GET method. It should be just
public ActionResult NewInterests(int id)
The first step in the model binding process is that instances of your parameters are initialized and then its properties are set based on form values, route values, query string values etc. In your case there are no values to set, so the properties of your model are their defaults, but because you have validation attributes on your properties, validation fails and errors are added to ModelState which are then displayed in the view.
I am creating a page in Asp.Net MVC where a user can upload a file, along with details about the file from textboxes.
For this I use a viewmodel, and a very simple method configuration. The page is populated correctly by the [Get] Method, and the user can choose the file and enter the details, but once the 'Submit' button is clicked, and the [Post] method is called, the viewmodel is completely null.
I have done my research on this and have tried:
adding enctype="multipart/form-data"
simply using the file as a separate parameter
To no avail.
Here is my controller methods:
public ActionResult FileComment(int id)
{
//set up [get] view
return View("FileComment", obj);
}
//THIS METHOD's VIEWMODEL ALWAYS NULL
[HttpPost]
public ActionResult FileComment(CalibrationCommentViewModel file)
{
//save file to database
return View("Edit", new { id = file.id });
}
Here is part of my view:
#using (Html.BeginForm("FileComment", "Calibration", FormMethod.Post, new { enctype = "multipart/form-data", #data_ajax = "false" }))
{
#Html.HiddenFor(m => m.ID)
<div class="container">
<h4>Add File for #Model.ID</h4>
<hr />
<div class="row">
<div class="col-md-1">g
#Html.LabelFor(model => model.file, htmlAttributes: new { #class = "control-label" })
</div>
<div class="col-md-2">
#Html.TextBoxFor(model => model.file, new { type = "file" })
</div>
<div class="col-md-9"></div>
</div>
<br />
<div class="row">
<div class="col-md-1">
#Html.LabelFor(model => model.attachmentType, htmlAttributes: new { #class = "control-label" })
</div>
<div class="col-md-2">
#Html.DropDownListFor(model => model.attachmentType, Model.attachTypeList, new { #class = "form-control" })
</div>
<div class="col-md-9"></div>
</div>
<br />
<div class="row">
<div class="col-md-1">
#Html.LabelFor(model => model.Date, htmlAttributes: new { #class = "control-label" })
</div>
<div class="col-md-2">
#Html.EditorFor(model => model.Date)
</div>
<div class="col-md-9"></div>
</div>
<br />
<div class="row">
<div class="col-md-1">
#Html.LabelFor(model => model.description, htmlAttributes: new { #class = "control-label" })
</div>
<div class="col-md-2">
#Html.TextAreaFor(model => model.description, new { cols=35, #rows=3})
</div>
<div class="col-md-9"></div>
</div>
<br />
<div class="row">
<div class="col-md-1"></div>
<div class="col-md-2">
<button type="submit" onclick="JavascriptFunction()">Add to #Model.ID</button>
</div>
<div class="col-md-9"></div>
</div>
</div>
}
Change
public ActionResult FileComment(CalibrationCommentViewModel file)
to
public ActionResult FileComment(CalibrationCommentViewModel model)
your view has no reference to view model at the top the view something like this
#model Nameofyourproject.Models.CalibrationCommentViewModel