MVC POST Complex Object is NULL - asp.net-mvc

The Inner Object ExtraData is NULL after Form POST. I am unable to pass the Object to the Controller. Need help to figure out what is wrong here.
My Models
public class TestModel
{
public int ClaimNumber { get; set; }
public string Key { get; set; }
public string SaveMessage { get; set; }
public bool UserAuthorizedEdit { get; set; }
public ExtraDataModel EData { get; set; }
}
public class ExtraDataModel
{
public int ID { get; set; }
public string Code { get; set; }
public string Desc { get; set; }
}
My View
<h2>View1</h2>
#using (Html.BeginForm("SaveDetails", "SaveData", Model, FormMethod.Post, new { #id = "RenderProviderVForm", target = "_blank" }))
{
<table>
<tr>
<td> #Html.TextBoxFor(model => model.ClaimNumber)</td>
</tr>
<tr>
<td> #Html.DisplayFor(model => model.Key)</td>
</tr>
<tr>
<td> #Html.TextBoxFor(model => model.SaveMessage)</td>
</tr>
<tr>
<td> #Html.TextBoxFor(model => model.EData.ID)</td>
</tr>
<tr>
<td> #Html.TextBoxFor(model => model.EData.Code)</td>
</tr>
<tr>
<td> #Html.TextBoxFor(model => model.EData.Desc)</td>
</tr>
<tr>
<td>
<button type="submit" class="link-button" value="submit">#Model.ClaimNumber</button>
</td>
</tr>
</table>
}
My Controller
[HttpPost]
public void SaveDetails(TestModel tm)
{
if (ModelState.IsValid)
{
//Save Code
}
else
{
System.Diagnostics.Debug.Write(ModelState);
}
}
The Error on the ModelState says:
System.InvalidOperationException: The parameter conversion from type 'System.String' to type 'MvcApplication2.Models.ExtraDataModel' failed because no type converter can convert between these types.
at System.Web.Mvc.ValueProviderResult.ConvertSimpleType(CultureInfo culture, Object value, Type destinationType)
at System.Web.Mvc.ValueProviderResult.UnwrapPossibleArrayType(CultureInfo culture, Object value, Type destinationType)
at System.Web.Mvc.ValueProviderResult.ConvertTo(Type type, CultureInfo culture)
at System.Web.Mvc.ValueProviderResult.ConvertTo(Type type)
at System.Web.Mvc.DefaultModelBinder.ConvertProviderResult(ModelStateDictionary modelState, String modelStateKey, ValueProviderResult valueProviderResult, Type destinationType)}
I now got this exception:
The parameter conversion from type 'System.String' to type 'MvcApplication2.Models.ExtraDataModel' failed because no type converter can convert between these types.
Here is the generated HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>View1</title>
<link href="/Content/site.css" rel="stylesheet"/>
<script src="/Scripts/modernizr-2.6.2.js"></script>
</head>
<body>
<h2>View1</h2>
<form action="/SaveData/SaveDetails?ClaimNumber=123456&Key=40e686ca-1176-4d45-a1dd-33b79b3a9764&SaveMessage=Save%20Me&UserAuthorizedEdit=True&EData=MvcApplication2.Models.ExtraDataModel" id="RenderProviderVForm" method="post" target="_blank"><table>
<tr>
<td> <input data-val="true" data-val-number="The field ClaimNumber must be a number." data-val-required="The ClaimNumber field is required." id="ClaimNumber" name="ClaimNumber" type="text" value="123456" /></td>
</tr>
<tr>
<td> <input id="Key" name="Key" type="text" value="40e686ca-1176-4d45-a1dd-33b79b3a9764" /></td>
</tr>
<tr>
<td> <input id="SaveMessage" name="SaveMessage" type="text" value="Save Me" /></td>
</tr>
<tr>
<td> <input data-val="true" data-val-number="The field ID must be a number." data-val-required="The ID field is required." id="EData_ID" name="EData.ID" type="text" value="888888" /></td>
</tr>
<tr>
<td> <input id="EData_Code" name="EData.Code" type="text" value="CD" /></td>
</tr>
<tr>
<td> <input id="EData_Desc" name="EData.Desc" type="text" value="DVD" /></td>
</tr>
<tr>
<td>
<button type="submit" class="link-button" value="submit">123456</button>
</td>
</tr>
</table>
</form>
<script src="/Scripts/jquery-1.8.2.js"></script>
</body>
</html>
Now if i have to Edit and Post only ExtraDataModel values on the form, what modifications should I have to do.

Related

Sending table datas to Controller without using ajax

I have a table in view which is static in nature.I am trying to post data to Controller without using Jquery Ajax. Is it possible?How can I retrieve all these data in Action "bulk_insert". I am able to send this bulk data to controller using jquery ajax but I am unable to send it directly.
My view :
#using entity_framework.Models
#{
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div class="container">
<h1>Static data</h1>
<div>
#using (Html.BeginForm("bulk_insert", "Form", FormMethod.Post, new { enctype = "multipart/form-data", id = "postForm" }))
{
<table id="myTable" class="table table-striped">
<thead>
<tr>
<td>Menu Item Id</td>
<td>Menu Item Name</td>
<td>Menu Qty</td>
<td>Menu Rate</td>
<td>Total</td>
</tr>
</thead>
<tbody>
<tr>
<td><input type="hidden" name="menu_item_id[0]" value="1" /><span>1</span></td>
<td><input type="hidden" name="menu_item_name[0]" value="chaumin" /><span>chaumin</span></td>
<td><input type="hidden" name="data[0].rate" value="100" /><span>100</span></td>
<td><input type="hidden" name="data[0].qty" value="2" /><span>2</span></td>
<td><input type="hidden" name="data[0].total" value="200"><span>200</span></td>
</tr>
<tr>
<td><input type="hidden" name="data[1].menu_item_id" value="2" /><span>2</span></td>
<td><input type="hidden" name="data[1].menu_item_name" value="Mo:Mo" /><span>Mo:Mo</span></td>
<td><input type="hidden" name="data[1].rate" value="100" /><span>100</span></td>
<td><input type="hidden" name="data[1].qty" value="2" /><span>2</span></td>
<td><input type="hidden" name="data[1].total" value="200"><span>200</span></td>
</tr>
</tbody>
</table>
<input type="submit" value="Submit" />
}
</div>
I am just testing with static data right now,but I need to do it with dynamic data i.e, When a user clicks a button, a row gets added using javascript .So,I didn't use Htmlhelper. My model:
public class tabledata
{
public int menu_item_id { get; set; }
public string menu_item_name { get; set; }
public string rate { get; set; }
public string qty { get; set; }
public string total { get; set; }
}
I don't know how can I get table datas from form but my Controller method:
[HttpPost]
public ActionResult bulk_insert(IEnumerable<tabledata> data)
{
//How can I get table datas here
}

MVC ModelState.IsValid not working

I am using below code to validate my model, but when I click on the 'Save Employee' button on the CreateEmployee view, the page is returning to CreateEmployee view without a validation messages.
Model
public class Employee
{
[Key]
public int EmployeeId { get; set; }
[Required(ErrorMessage="Enter First Name")]
public string FirstName { get; set; }
[Required(ErrorMessage="Enter Last Name")]
[StringLength(6,ErrorMessage="Last Name should not contain more than 6 characters")]
public string LastName { get; set; }
public int Salary { get; set; }
}
View
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
#*<meta name="viewport" content="width=device-width" />*#
<title>CreateEmployee</title>
<script type="text/javascript">
function ResetForm() {
document.getElementById("txtFirstName").value = "";
document.getElementById("txtLastName").value = "";
document.getElementById("txtSalary").value = "";
}
</script>
</head>
<body>
<div>
<form action="SaveEmployee" method="post">
#Html.ValidationSummary()
<table>
<tr>
<td>First Name:</td>
<td>
<input type="text" id="txtFirstName" name="FirstName" value="" /></td>
</tr>
<tr>
<td colspan="2" align="right">#Html.ValidationMessage("FirstName")</td>
</tr>
<tr>
<td>Last Name:</td>
<td>
<input type="text" id="txtLastName" name="LastName" value="" /></td>
</tr>
<tr>
<td colspan="2" align="right">#Html.ValidationMessage("LastName")
</td>
</tr>
<tr>
<td>
<input type="submit" value="SaveEmployee" />
</td>
</tr>
</table>
</form>
</div>
</body>
</html>
Controller
public ActionResult SaveEmployee(Employee e,string BtnSubmit)
{
switch (BtnSubmit)
{
case "Save Employee":
if (ModelState.IsValid)
{
EmployeeBuisnessLayer objEBL = new EmployeeBuisnessLayer();
objEBL.SaveEmployee(e);
return RedirectToAction("Index");
}
else
{
return RedirectToAction("CreateEmployee");
}
case "Cancel":
return RedirectToAction("Index");
}
return new EmptyResult();
}
Don't redirect. You will lose modelstate. You need to let the method run to completion and pass the model back to the view.
Controller
[HttpPost]
public ActionResult CreateEmployee(Employee e, string BtnSubmit) {
switch (BtnSubmit) {
case "SaveEmployee":
if (ModelState.IsValid) {
EmployeeBuisnessLayer objEBL = new EmployeeBuisnessLayer();
objEBL.SaveEmployee(e);
return RedirectToAction("Index");
}
case "Cancel":
return RedirectToAction("Index");
default:
return new EmptyResult();
}
return View(e);
}
Your Form also needs to post to the CreateEmployee
View
<form action="CreateEmployee" method="post">

How to upload form contents with a file to database?

This is my code,i have also tried strongly typed view but i it does not create an upload field
#Model
namespace master_layout.Models
{
[Table("Candidates")]
public class Candidate
{
[Key]
public int CandidateID { get; set; }
public string FirstName { get; set; }
public string LastName{get;set;}
public DateTime Date{get;set;}
public string EmailID{get;set;}
public long ContactNumber{get;set;}
public long AlternateContactNumber{get;set;}
public int RecruitmentStatusID{get;set;}
public DateTime CreatedOn{get;set;}
public DateTime LastUpdatedOn{get;set;}
public byte[] Resume { get; set; }
}
public class CandidateContext : DbContext
{
public DbSet<Candidate> Candidates { get; set; }
}
The following is my controller code
Controller:
namespace proedit1.Controllers
{
public class HomeController : Controller
{
CandidateContext db = new CandidateContext();
public ActionResult Index()
{
return View(db.Candidates.ToList());
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Candidate candidate)
{
if (ModelState.IsValid)
{
db.Candidates.Add(candidate);
db.SaveChanges();
return RedirectToAction("Index", "Home");
}
return View(candidate);
}
}
}
View:
#using (Html.BeginForm("Newcandidate", "CandidatesController", FormMethod.Post, new { EncType="multipart/form-data"}))
{
<table class="navbar-form">
<tr>
<th>First Name<input type="text" placeholder="Your First Name" class="margin"/></th>
</tr>
<tr>
<th>Last Name<input type="text" placeholder="Your Last Name"/></th>
</tr>
<tr>
<th>Date of Birth <input type="date" name="db" /></th>
</tr>
<tr>
<th>E-Mail ID<input type="email" placeholder="abc#yourserviceprovider.com" /></th>
</tr>
<tr>
<th>Contact No<input type="tel" placeholder="04426506555 or 98414981414" min="8" maxlength="10"/></th>
<tr>
<tr>
<th>Alternate No <input type="tel" placeholder="04426506555 or 98414981414" min="8" maxlength="10"/></th>
<tr>
<th>Created On <input type="date" /></th>
<tr>
<th>Updated On <input type="date" /></th>
</tr>
<tr>
<th> <input type="file" placeholder="your resume in ms.word format" accept="application/msword" name="NamebtnUpload"/>
</th></tr>
</table>
<div class="row">
<div class="span4">
<input type="submit" class="btn-success" value="UPLOAD" name="Submit"/>
<input type="reset" class="btn-warning" name="Reset" />
</div>
</div>
}
I am a newbie in MVC pls provide me with the correct code to upload details to my database
There is a solution which are you looking for:
MVC 4 Razor File Upload
Create new view model for your 'view'. Don't use entity model, please.

submit form as object parameter

So I have this form on my Index.cshtml view (Some data removed to shorten length),
I want to be able to submit it to the action "/Estimate/Index" defined as,
public ActionResult CreateEstimate(Estimate Est);
It creates the object just fine by serializing the data and submitting, my problem is that sub-object data is not inserted (and I understand that it doesn't cause it doesn't know how), I was curious if there was a way to tell it how to correctly create the objects in a simple/automated manner.
I've tried giving the NetUplift a different name,
Ex. name="NetUplift.Value" but this results in an internal server error (code 500).
Form in razor view - Index.cshtml
<form id="form-create-estimate">
<table id="table-create-estimate" class="table">
<tbody>
<tr>
<td class="td-header">ID</td>
<td id="td-id"><input name="ID" type="text" value="" /></td>
</tr>
<tr>
<td class="td-header">Name</td>
<td id="td-name"><input name="Name" type="text" value="" /></td>
</tr>
<tr>
<td class="td-header">Job Difficulty</td>
<td id="td-jobdifficulty"><input name="JobDifficulty" type="text" value="" /></td>
</tr>
<tr>
<td class="td-header">Type</td>
<td id="td-type"><input name="Type" type="text" value="" /></td>
</tr>
<tr>
<td class="td-header Unit">Net Uplift</td>
<td id="td-netuplift">
<input name="NetUplift" class="Unit" title="in PSF" type="number" value="" />
#*<input name="NetUplift.DataType" type="hidden" value="System.Int32" />
<input name="NetUplift.UnitOfMeasure" type="hidden" value="psf" />*#
</td>
</tr>
<tr>
<td class="td-header Unit">Joist Spacing</td>
<td id="td-joistspacing"><input name="JoistSpacing" class="FeetInch" title="in Feet' Inch''" type="text" value="" /></td>
</tr>
</tr>
<tr>
<td class="td-header">Drawing Location</td>
<td id="td-drawinglocation"><input name="DrawingLocation" type="text" value="" /></td>
</tr>
<tr>
<td><input id="button-submit-estimate" type="button" value="Create" /></td>
<td><input id="button-cancel-estimate" type="button" value="Cancel" /></td>
</tr>
</tbody>
</table>
</form>
Ajax Submit Script
// Do an Ajax Post to Submit the newly created Estimate.
function CreateEstimate() {
// Serialize the Form.
var Estimate = $("#form-create-estimate").serialize();
// Send the Serialized Form to the Server to be processed and returned
// as an updated page to asynchronously update this page.
// I guess instead of returning this entire page we could make the action
// return just a table row with the Estimate's Data, then append it to the table
// of estimates. It'll be saved to the list of estimates too so there won't be
// a chance to the lists on the Client and list on the server to be different.
$.ajax({
url: "/Estimate/CreateEstimate/",
datatype: "json",
data: Estimate,
contenttype: "application/json",
success: function (Data, Success) {
if (Data.Estimate !== undefined) {
// Create a Html Table Row from the Estimate.
// Append the Row to the Table.
// Hide the Dialog.
} else {
alert("No Error Occured; however, the Creation of the Estimate was unsuccessful. Please Try Again.");
}
},
error: function (xhr, ajaxOptions, thrownError) {
alert("An Error Occured. \n" + thrownError + "\n" + xhr.status);
}
});
}
Estimate Class
public class Estimate
{
public Int32 ID { get; set; }
public String JobDifficulty { get; set; }
public String Type { get; set; }
public String Name { get; set; }
public Unit NetUplift { get; set; }
public Unit JoistSpacing { get; set; }
public String DrawingLocation { get; set; }
}
Unit Class
public class Unit
{
public String Value { get; set; }
public Type DataType { get; set; }
public String UnitOfMeasure { get; set; }
public Unit(Type DataType, String Value, String UnitOfMeasure)
{
this.Value = Value;
this.DataType = DataType;
this.UnitOfMeasure = UnitOfMeasure;
}
}
Currently the action CreateEstimate(Estimate Est) recieves the data submitted except for sub-object values such as Unit (Estimate.NetUplift). How do I tell it to map NetUplift to Estimate.NetUplift.Value, and the two commented out input fields to NetUplift.DataType/NetUplift.UnitOfMeasure?
Is there a way to have the server just know that it should be mapped that way or do I have to do it before sending the form to the server?
You could try this:
$.fn.serializeToObject = function () {
var o = {};
var a = this.serializeArray();
$.each(a, function () {
if (o[this.name] !== undefined) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
} else {
o[this.name] = this.value || '';
}
});
return o;
};
var estimate = $("#form-create-estimate").serializeToObject();

How to Update Database on ButtonClick in ASP.NET MVC architecture

Hi i am looking to capture values from my view and update the entered values in to my database .
My view looks like following :
#using Kendo.Mvc.UI
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Facility</title>
</head>
<body>
<div>
<p>Create a new Facilty</p>
<table width="100px">
<tr>
<td>
<label for="TenantId">TenantID:</label>
</td>
<td>
<input id="TextTenantId" type="text" />
</td>
</tr>
<tr>
<td>
<label for="FacilityID">FacilityID:</label>
</td>
<td>
<input id="TextFacilityID" type="text" />
</td>
</tr>
<tr>
<td>
<label for="FacilityGroupID">FacilityGroupID:</label>
</td>
<td>
<input id="TextFacilityGroupID" type="text" />
</td>
</tr>
<tr>
<td>
<label for="FacilityName">FacilityName:</label>
</td>
<td>
<input id="TextFacilityName" type="text" />
</td>
</tr>
<tr>
<td>
<label for="FacilityAddressLine1">FacilityAddressLine1:</label>
</td>
<td>
<input id="TextFacilityAddressLine1" type="text" />
</td>
</tr>
<tr>
<td>
<label for="FacilityAddressLine2">FacilityAddressLine1:</label>
</td>
<td>
<input id="TextFacilityAddressLine2" type="text" />
</td>
</tr>
<tr>
<td>
<label for="FacilityAddressLine3">FacilityAddressLine1:</label>
</td>
<td>
<input id="TextFacilityAddressLine3" type="text" />
</td>
</tr>
<tr>
<td>
<label for="CityId">CityId:</label>
</td>
<td>
<input id="TextCityId" type="text" />
</td>
</tr>
<tr>
<td>
<label for="StateId">StateId:</label>
</td>
<td>
<input id="TextStateId" type="text" />
</td>
</tr>
<tr>
<td>
<label for="CountryId">CountryId:</label>
</td>
<td>
<input id="TextCountryId" type="text" />
</td>
</tr>
<tr>
<td>
<label for="Zipcode">Zipcode:</label>
</td>
<td>
<input id="TextZipcode" type="text" />
</td>
</tr>
<tr>
<td>
<label for="PhoneNo">PhoneNo:</label>
</td>
<td>
<input id="TextPhoneNo" type="text" />
</td>
</tr>
<tr>
<td>
<label for="Status">Status:</label>
</td>
<td>
<input id="TextStatus" type="text" />
</td>
</tr>
<tr>
<td>
<label for="EmailId">EmailId:</label>
</td>
<td>
<input id="TextEmailId" type="text" />
</td>
</tr>
<tr>
<td>
<label for="Website">Website:</label>
</td>
<td>
<input id="TextWebsite" type="text" />
</td>
</tr>
<tr>
<td>
<input id="Submit1" type="Submit" value="submit" />
</td>
</tr>
</table>
</div>
</body>
</html>
My model looks like :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace AmanoMockUp.Models
{
public class FacilityModels
{
public int TenantId { get; set; }
public int FacilityId { get; set; }
public int FacilityGroupId { get; set; }
public string FacilityName { get; set; }
public string FacilityAddressLine1 { get; set; }
public string FacilityAddressLine2 { get; set; }
public string FacilityAddressLine3 { get; set; }
public int CityId { get; set; }
public int StateId { get; set; }
public int CountryId { get; set; }
public string Zipcode { get; set; }
public int PhoneNo { get; set; }
public bool status { get; set; }
public string EmailId { get; set; }
public string Website { get; set; }
public DateTime CreationDate { get; set; }
}
}
now i need to update the values entered in the view in the various textfields onto my database on the submission of my button
<input id="Submit1" type="Submit" value="submit" />
Where should i write the buttonclick event should it be on the controller or the model or should i create a whole new controller for the same .Please help !!
I have searched but i couldnt find anything related to my issue .
Thanx in advance !!
How about having your view strongly typed against your model and having the form submit the values to an action method that does the work? do some searching on Html.BeginForm for pointers on having a form call a specific action on submission and just about any basic MVC tutorial for strongly typing a view to a model.
database calls should be in the controller.
in the controller create another action with the [HttpPost] attribute but with the same name. it will take the model as its parameter. then complete the database logic and save changes and return the view.
look at the example here
http://www.c-sharpcorner.com/UploadFile/krishnasarala/select-insert-update-and-delete-with-Asp-Net-mvc/

Resources