pass a model from partial view to controller by ajax in mvc - asp.net-mvc

My controller is
public ActionResult AddCustomer(Customer SM)
{
DataAccessLayer.ConClass obj = new DataAccessLayer.ConClass();
obj.SaveCustumerDetails(SM);
ModelState.Clear();
return PartialView();
}
my model is
public class Customer
{
[DisplayFormat(ConvertEmptyStringToNull = false)]
public string Customer_id { get; set; }
[DisplayFormat(ConvertEmptyStringToNull = false)]
public string Customer_Contact_Person { get; set; }
[DisplayFormat(ConvertEmptyStringToNull = false)]
public string Customer_Contact_Person_Designation { get; set; }
[DisplayFormat(ConvertEmptyStringToNull = false)]
public string Customer_name { get; set; }
[DisplayFormat(ConvertEmptyStringToNull = false)]
public string Customer_Address1 { get; set; }
[DisplayFormat(ConvertEmptyStringToNull = false)]
public string Customer_Address2 { get; set; }
[DisplayFormat(ConvertEmptyStringToNull = false)]
public string Customer_City { get; set; }
[DisplayFormat(ConvertEmptyStringToNull = false)]
public string Customer_State { get; set; }
[DisplayFormat(ConvertEmptyStringToNull = false)]
public string Customer_Country { get; set; }
[DisplayFormat(ConvertEmptyStringToNull = false)]
public string Customer_PIN { get; set; }
[DisplayFormat(ConvertEmptyStringToNull = false)]
public string Customer_Phone1 { get; set; }
[DisplayFormat(ConvertEmptyStringToNull = false)]
public string Customer_Phone2 { get; set; }
[DisplayFormat(ConvertEmptyStringToNull = false)]
public string Customer_Email1 { get; set; }
[DisplayFormat(ConvertEmptyStringToNull = false)]
public string Customer_Email2 { get; set; }
}
Savecutomer is the name of the button .My partaial view code is
<script>
$('#SaveCustomer').click(
function () {
$.ajax({
type: "POST",
url: '#Url.Action("AddCustomer", "Customer")',
data: ' $("myform").serialize() ,
contentType: 'application/json; charset=utf-8',
dataType: 'json',
complete: function (data) {
},
});
});
</script>
My need is to save customer details when i click on savecustomer button I don't want to see the details on url. In this way url holds data. I need to avoid it.

The method you have shown is a GET but its parameter is Customer SM which means that the DefaultModelBinder will generate a query string for each property in your model. I'm guessing that (because this method returns a partial view) your calling it in the main view using #Html.Action() or ajax to load a form into the view.
Firstly you need to methods, one GET and one POST
public ActionResult AddCustomer()
{
// Initialize a new instance of your model and pass it to the view
Customer model = new Customer();
return PartialView(model);
}
[HttpPost]
public JsonResult AddCustomer(Customer SM)
{
DataAccessLayer.ConClass obj = new DataAccessLayer.ConClass();
obj.SaveCustumerDetails(SM);
return Json(true); // see notes below
}
Note if you have included #Html.AntiForgeryToken in the partial, then your will also need to add [ValidateAntiForgeryToken]
Next, delete the script from your partial view and add it to the main view (scripts should never be in partials). Then change the script to
$('#SaveCustomer').click(function() {
$.ajax({
type: "POST",
url: '#Url.Action("AddCustomer", "Customer")',
data: $('#myform').serialize(), // change this to include the #
dataType: 'json',
success: function (data) {
// do something?
},
});
});
Note this assumes your form has id="myform". Note also contentType has been removed (its not required unless you stringify the data). It can also be simplified to
$.post('#Url.Action("AddCustomer", "Customer")', $('#myform').serialize(), function(data) {
// do something
});
Side notes: Its not clear what you want to do in the success callback. I would suggest that in the POST method you use return Json(true); if the save was successful, otherwise return a HTTP error code. Then in the success call back you might do something like
if (data) {
// the save was successful so reset existing form controls
$('#myform').get(0).reset();
// maybe display a message indicating success
}
and similarly you could handle an error by displaying a message indicating the the customer could not be saved.

When i changed to
$('#SaveCustomer').click(
function () {
$.ajax({
type: "POST",
url: '#Url.Action("AddCustomer", "Customer")',
data: "{'Customer_Name' : '" + $('#Customer_Name').val() + "' ," +
" 'Customer_Adress1' : '" + $('#Customer_Address1').val() + "'}" ,
contentType: 'application/json; charset=utf-8',
dataType: 'json'
});
})
and change controller to
public ActionResult AddCustomer(string Customer_Name, string Customer_Address1)
{
DataAccessLayer.ConClass obj = new DataAccessLayer.ConClass();
obj.SaveCustomerDetails( Customer_Name, Customer_Address1);
ModelState.Clear();
return PartialView();
}
it worksss

Related

Ajax to C# controller: How to pass an Array of objects along with other data

I have the following code:
Class:
public class EngineGroup
{
public string CategoryName { get; set; }
public OemPart[] ArrOemParts { get; set; }
}
public class OemPart {
public string IdInDiagram { get; set; }
public string Sku { get; set; }
public string OemName { get; set; }
}
Controller:
public IActionResult Insert(EngineGroup eg){
}
JavaScript:
var formData = new FormData();
formData.append("CategoryName", groupEngineName);
formData.append("ArrOemParts", arrOemParts); // -- >>> this is an array of objects
$.ajax({
type: "POST",
data: formData,
url: "/Insert",
dataType: 'json',
contentType: false,
processData: false,
When I am sending the FormData to the controller, the array of objects is empty while the rest of the data is successfully passed to the controller.
I was trying to do JSON.stringify(formData) with no luck...
public class OemPart {
public string IdInDiagram { get; set; }
public string Sku { get; set; }
public string OemName { get; set; }
}
[HttpPost]
[IgnoreAntiforgeryToken(Order = 2000)]
public IActionResult InsertCategoryAndOemPart([FromBody] OemPart[] oemPart, string categoryName)
{
$.ajax({
type: "POST",
data: JSON.stringify(arrOemParts),
url: "/admin/engineGroup/InsertCategoryAndOemPart/?categoryName=" + categoryName
contentType: 'application/json; charset=utf-8'

How to post a json object from to an mvc action

I have a mvc action
[HttpPost]
public ActionResult EditUser(ApplicationUser model)
ApplicationUser class is:
public class ApplicationUser
{
public int UserId { get; set; }
[Required]
public string UserName { get; set; }
public byte[] HashedPassword { get; set; }
public bool IsActive { get; set; }
public bool IsVerified { get; set; }
}
In jquery side I am doing:
$.ajax({
method: 'POST',
url: '#Url.Content("~/UserAdmin/EditUser")',
dataType: "json",
data: ....How do I post the object...???
});
My question is how do I post the Json object to the method as I hit the break point but the object is null.
Use JSON.stringify to reliably convert your JS object to JSON data for sending across the wire
var user = {
UserId: '31750',
UserName: 'chugh97',
HashedPassword: '...',
IsActive: true,
IsVerified: true
};
...
dataType: 'json',
data: JSON.stringify(user),
...
Note - I would recommend making your HashedPassword a string type instead of a byte[], it would be easier to deal with that client-side.

fill model's fields before post

i pass a model to my view . and it's fields are hiddenfor.
and my tds are here(in this view)
how can i say when i click on button(submit-btn2) , first my java script codes execute . and then my filled model will be post ?
my Partialview :
#Html.HiddenFor(m => m.username)
#Html.HiddenFor(m => m.Tell)
#Html.HiddenFor(m => m.Name)
#Html.HiddenFor(m => m.Mobil)
#Html.HiddenFor(m => m.Lname)
<button class="btn btn-medium btn-general input-block-level" id="submit-btn2" type="submit">save</button>
//all tds are here in this page(this view)
// $(document).ready(function () {
//$('#submit-btn2').click(function () {
//$("#username").val($(".tdBuyername").val());
//$("#Tell ").val($(".tdPhone").val());
//$("#Name ").val($(".tdRecievername").val());
//$("#Mobil ").val($(".tdMobile").val());
//$("#Lname ").val($(".tdLname").val());
//});
// });
<script type="text/javascript">
$("#submit-btn2").click(function () { saveMyModel();});
function SaveMyModel()
{
var e = document.getElementById("id_purchase");
var str = e.options[e.selectedIndex].value;
var e2 = document.getElementById("id_spend");
var str2 = e.options[e.selectedIndex].value;
$.ajax({
url: '#Url.Action("Save", "Home")',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify({
jsonMyModel: {
username: $(".tdBuyername").val(),
Tell: $(".tdPhone").val(),
Name: $(".tdRecievername").val(),
Mobil: $(".tdMobile").val(),
Lname: $(".tdLname").val(),
id_purchase: $("# id_purchase ").val(str),
id_spend: $("# id_spend ").val(str2),
}
})
});
}
Mycontroller:
[HttpGet]
public ActionResult Customer()
{
var obj = new Project.Models.ModelClasses.ViewModelX();
return PartialView(obj);
}
[HttpPost]
public JsonResult Save(ViewModelX jsonMyModel)
{
var result = true;
if (ModelState.IsValid)
{
result= MyClass.Insert (jsonMyModel.Address, jsonMyModel.Cod,
jsonMyModel.idpurchase,
jsonMyModel.idspend, jsonMyModel.Lname,
jsonMyModel.Name, jsonMyModel.Tell, jsonMyModel.username);
}
else
{
}
return Json(result, JsonRequestBehavior.AllowGet);
}
MyClass:
public class ViewModelX
{
public Nullable< long > idpurchase { get; set; }
public Nullable<long> idspend { get; set; }
public string username { get; set; }
public string Name { get; set; }
public string Lname { get; set; }
public string Tell { get; set; }
public string Address { get; set; }
public string CodPosti { get; set; }
}
Just add the following to the end of your click handler:
$('#myForm').submit();
Where myForm is the id attribute of your form.
Assuming your controller action accepts a parameter matching the class that your view is typed to, the model binder should take care of it as usual.
Are you using a strongly typed model?
What you have described can be done in two ways.
Using AJAX to post your data without page reload.
Using normal form post to post data.
Using AJAX
Having assumed that your controller method is like:
[HttpPost]
public JsonResult Save(MyModel jsonMyModel)
{
//do saving stuff
}
where , your model MyModel looks like
public class MyModel()
{
public string Username { get; set;}
public string Tell { get; set;}
public string Name { get; set;}
public string Mobile { get; set;}
public string LastName { get; set;}
}
You can create the model that your controller method accepts using normal jquery or javascript and post it using AJAX as below:
$("#submit-btn2").click(function () { saveMyModel();});
function SaveMyModel()
{
$.ajax({
url: '#Url.Action("Method", "SomeController")',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify({
jsonMyModel: {
Username: $("#username").val(),
Tell: $("#Tell ").val(),
Name: $('#listviewlabel').val(),
Mobile: $("#Name ").val(),
LastName:$("#Lname ").val()
})
});
}
Using normal form post
You can directly google out this thing. You can even find this in your account controller.

View model absence in registration form

I have a partial view that contains a registration form with the following fields:
E-Mail
First Name
Last Name
Password
I am posting the form using jQuery Ajax without using View Model.
Question : Is it a good approach to not use View Model in his context ?
Question : Is my approach useless in case of unit test cases?
jQuery
$.ajax({
url: "#Url.Action("Action", "Controller", new { area = "Area" })",
type: "POST",
contentType: 'application/json; charset=utf-8',
dataType: "json",
data: JSON.stringify({mail : "mails", nam : nam ......}),
traditional: true,
success: function (data) {
alert("wsaved");
}
});
[HpPost]
public Actionresult abc(string mail, string nam, sring lasnam)
{
return Json(new {succss = ru});
}
Is it a good approach to not use View Model in his context ?
No, it will make validation much harder. Suppose that you wanted to validate that the email is not empty and is indeed a valid email address. If you used a view model, all you had to do is decorate the Email property on your view model with the correct validation attributes. With your approach you will now have to write a couple of useless lines of code in your controller action for that.
Here's how your view model might look like:
public class RegisterUserViewModel
{
[Required]
[RegularExpression("PUT YOUR REGEX TO VALIDATE AN EMAIL HERE")]
public string Email { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
[Required]
[RegularExpression("PUT YOUR REGEX TO ENFORCE SOME PASSWORD STRENGTH")]
public string Password { get; set; }
}
and now your controller action becomes:
[HttpPost]
public ActionResult Register(RegisterViewModel model)
{
if (!ModelState.IsValid)
{
// validation failed
var errors = ModelState
.Where(x => x.Value.Errors.Count > 0)
.Select(x => new
{
Key = x.Key,
Errors = x.Value.Errors.Select(e => e.ErrorMessage)
}
);
return Json(new { success = false, errors = errors });
}
return Json(new { success = true });
}
IF you are using an ApiController with MVC 4, then you can use a Model to bind to, which will use (by default) Newton Json.NET.
ResponseModel
[DataContact]
public class ResponseModel
{
[DataMember]
public string Status { get; set; }
}
ActionModel
[DataContact]
public class RegisterUserViewModel
{
[Required]
[DataMember(isRequired=true)]
public string Email { get; set; }
[DataMember]
public string FirstName { get; set; }
[DataMember]
public string LastName { get; set; }
[Required]
[DataMember(isRequired="true")]
public string Password { get; set; }
}
ApiController Action
[HttpPost]
public ReponseModel Register(RegisterActionModel actionModel)
{
if (this.ModelState == valid)
{
//do stuff
return new ResponseModel()
{
Status = "OK"
};
}
else
{
return new ResponseModel()
{
Status = "Invalid Data"
}
}
}

Returning JSON to an Action in MVC 3.0

I admit, I'm confused:
I'm trying to return a simple object that I've converted to JSON as follows:
viewModel.updateCoder = function (coder) {
var coderJson = ko.toJSON(coder);
var coderJsonString = ko.utils.stringifyJson(coderJson);
$.ajax({
url: "provider/UpdateCoder",
type: 'POST',
dataType: 'text',
data: coderJsonString,
contentType: 'text/csv',
success: function () { alert("Updated!"); }
});
My RouteTable entry looks like this:
routes.MapRoute(
"UpdateCoder",
"provider/UpdateCoder/{coderDTO}", // URL with parameters
new { controller = "Provider", action = "UpdateCoder", coderDTO = UrlParameter.Optional }
);
my Controler action looks like this:
[AcceptVerbs(HttpVerbs.Post)]
public string UpdateCoder( string coderDTO )
{
var rslt = "success";
//var coder = coderDTO.CoderDTOToCoder();
return rslt;
}
What I get in the UpdateCoder parameter ( string coderDTO ) is a null;
This is my fall-back position I'd rather send a JSON object (the coderJson) to the action but I get an error: "No parameterless constructor defined for this object." When I do that I'm changing the parameter type as follows:
[AcceptVerbs(HttpVerbs.Post)]
public string UpdateCoder( **CoderDTO coderDTO** )
{
var rslt = "success";
//var coder = coderDTO.CoderDTOToCoder();
return rslt;
}
along with: ValueProviderFactories.Factories.Add(new JsonValueProviderFactory()); in the Global.asax
the CoderDTO class looks like this:
public class CoderDTO
{
public Int32 Id { get; set; }
public String CoderCode { get; set; }
public String Sal { get; set; }
public String LName { get; set; }
public String FName { get; set; }
public String MI { get; set; }
public String Facility { get; set; }
public String Title { get; set; }
public Boolean? IsContract { get; set; }
public Boolean? IsInactive { get; set; }
public Boolean? IsDeleted { get; set; }
public String Comments { get; set; }
public String AlternateId { get; set; }
public int CasesCoded { get; set; }
public CoderDTO(Coder coder)
{
Id = coder.Id;
CoderCode = coder.CoderCode;
Sal = coder.Sal;
LName = coder.LName;
FName = coder.FName;
MI = coder.MI;
Facility = coder.Facility;
Title = coder.Title;
if (coder.IsContract != null) IsContract = coder.IsContract;
if (coder.IsInactive != null) IsInactive = coder.IsInactive;
if (coder.IsDeleted != null) IsDeleted = coder.IsDeleted;
Comments = coder.Comments;
AlternateId = coder.AlternateId;
}
public Coder CoderDTOToCoder()
{
var coder = new Coder
{
Id = Id,
CoderCode = CoderCode,
Sal = Sal,
LName = LName,
FName = FName,
MI = MI,
Facility = Facility,
Title = Title
};
coder.IsContract = IsContract ?? false;
coder.IsInactive = IsInactive ?? false;
coder.IsDeleted = IsDeleted ?? false;
coder.Comments = Comments;
coder.AlternateId = AlternateId;
return coder;
}
}
The coderJsonString looks like this:
{"Id":201,"CoderCode":"GP ","Sal":null,"LName":null,"FName":null,"MI":null,"IsContract":false,"IsInactive":false,"Comments":null,"CasesCoded":0,"isBeingEdited":false}
It's been a long day!! Thanks for any help, I'm having dinner!!
I found the answer to the question of why I can't return a JSON that deserializes to my CoderDTO object: My object did not have a parameterless public constructor. I had a constructor parameter of a Coder which populated the CoderDTO. I split that off into a separate method and that now works.
Thanks to a post by
StackOverflow - ASP.NET MVC 3 JSONP: Does this work with JsonValueProviderFactory?
I think that your best bet is trying to figure out why you can't deserialize to your DTO. You will need to at least add a default constructor to it.
public CoderDTO() { }
For your current situation with passing strings, I think that you would want to call it like:
viewModel.updateCoder = function (coder) {
var coderJson = ko.toJSON(coder);
var coderJsonString = ko.utils.stringifyJson({ coderDTO: coderJson });
$.ajax({
url: "provider/UpdateCoder",
type: 'POST',
dataType: 'text',
data: coderJsonString,
contentType: 'application/json; charset=utf-8',
success: function () { alert("Updated!"); }
});
So, basically you create an object with the parameter name and value and stringify it. The coderJson is double-encoded in this case.
Try changing your action to use JsonResult:
[AcceptVerbs(HttpVerbs.Post)]
public JsonResult UpdateCoder(CoderDTO coderDTO)
{
var rslt = "success";
//var coder = coderDTO.CoderDTOToCoder();
return Json(rslt);
}

Resources