How to extract fields' data from Ajax MVC action call? - ajax

Here's the code:
1) MVC controller:
public DiagramData GetDiagramData()
{
return new DataBindingHelper().GetData();
}
2) Data helper:
public class DataBindingHelper
{
public DiagramData GetData()
{
DiagramData diagramData = new DiagramData();
return diagramData;
}
}
public class DiagramData
{
public string From
{
get { return "Moscow"; }
}
public string To
{
get { return "Saint Petersburg"; }
}
public string Color
{
get { return "Red"; }
}
public int Thick
{
get { return 2; }
}
}
3) Java Script:
function initDataBinding() {
jQuery.ajax({
type: "GET",
//url: '#Url.Action("GetDiagramData", "Home")'
url: '/Home/GetDiagramData'
}).done(function (data) {
//data = JSON.stringify(data);
//alert(data.From);
});

If it's normal conroller it should be on server side:
public JsonResult GetDiagramData()
{
return Json(new DataBindingHelper().GetData(), JsonRequestBehavior.AllowGet);
}
On client side:
function initDataBinding() {
$.ajax({
type: "GET",
url: '/Home/GetDiagramData'
}).done(function (data) {
alert(data.From); //<- this line should work
});

Related

How to pass Dictionary<Guid,int> to an ASP.NET Core MVC action through an Ajax call?

I have this function:
reloadCartComponent() {
$.ajax({
url: "Products/UpdateCart",
data: {
o: "Roman"//what type of object will be bound to Dictionary<Guid, int> on the controller's side
},
success: function (data) {
$("#summary").html(data);
}
})
}
And this action method in my controller:
public IActionResult UpdateCart(Dictionary<Guid, int> quantityDictionary = null)
{
return ViewComponent(typeof(CartComponent), quantityDictionary);
}
The method is being called but I have no idea what object I should build on the script side that is going to be correctly converted into Dictionary<Guid, int> on the controller side.
Figured it out:
public IActionResult UpdateCart(Dictionary<Guid,int> productQuantitiyDictionary = null)
{
return ViewComponent(typeof(CartComponent), productQuantitiyDictionary);
}
reloadCartComponent() {
var dict = {};
dict["443597a5-9940-49a8-94d5-3c386e9e6fd1"] = 1;
dict["4b27e0b7-6617-4ba2-b8aa-94751b3d9a7a"] = 2;
$.ajax({
url: "Products/UpdateCart",
data: {
productQuantitiyDictionary : dict
},
success: function (data) {
$("#summary").html(data);
}
})
}

value is not pass from view to controller using ajax

I am performing an AJAX call using a function but my value did not pass through it.
function GoToUpdatePage(currentID) {
var SessionTegInfo = {};
SessionTegInfo.StockCode = document.getElementById("stocktxt").checked;
SessionTegInfo.StockCodeValue = document.getElementById("SearchValuestock").value;
SessionTegInfo.CurrentID = currentID;
$.ajax({
url: "#Url.Action("UpdateWithSessionStore", "MyMasterUpdate")",
data: JSON.stringify(SessionTegInfo),
type: "POST",
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function (data) {
},
error: function (data) {
}
});
}
Here is my code from server side
[HttpPost]
public IActionResult UpdateWithSessionStore([FromBody] MySessionClass SessionTegInfo)
{
.....
return RedirectToAction("Index", "MyUpdateController", new { id = SessionTegInfo.CurrentID });
}
Here are my class details
public class MySessionClass
{
public string StockCode { get; set; }
public string StockCodeValue { get; set; }
public string CurrentID { get; set; }
}

NullReferenceException showing for ValidateAntiForgeryToken in MVC 5

I'm trying to save data using ajax in MVC 5. When I'm posting form data without #Html.AntiForgeryToken(), it's working nicely. But it's showing me Object reference not set to an instance of an object error for using #Html.AntiForgeryToken(). Here is my ajax code:
$.ajax({
type: "POST",
url: "/Employees/Create",
data: data,
async: false,
success: function (result) {
if (result == 1) {
window.location.href = '/Employees';
}
else {
$('#error-span').html('Error in insert.');
}
},
error: function () {
alert('Failed');
}
});
Here is my controller method:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "Address,JoinDate,DoB,Gender,BloodGroup,Email,LastName,FirstName,Mobile,UpdateDate,UpdatedBy,Status,EmployeeType,CreatedBy,CreateDate,DesignationId")] EmpDetail empDetail)
{
try
{
Regex rgx = new Regex("[^a-zA-Z0-9 - .]");
empDetail.FirstName = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(rgx.Replace(empDetail.FirstName, "").ToLower()).Trim();
empDetail.LastName = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(rgx.Replace(empDetail.LastName, "").ToLower()).Trim();
empDetail.Email = empDetail.Email.ToLower().Trim();
empDetail.UpdateDate = DateTime.Now;
empDetail.CreatedBy = 234;
empDetail.CreateDate = DateTime.Now;
empDetail.UpdatedBy = 234;
empDetail.Status = 1;
if (ModelState.IsValid)
{
db.EmpDetails.Add(empDetail);
db.SaveChanges();
return Json(1);
}
else
{
return Json(2);
}
}
catch (Exception e)
{
return Json(e.Message);
}
}
This is happening because the data is being sent via JSON instead of HTML Form data. You should try to pass the token in the headers. For example:
View:
<script>
#functions{
public string TokenHeaderValue()
{
string cookieToken, formToken;
AntiForgery.GetTokens(null, out cookieToken, out formToken);
return cookieToken + ":" + formToken;
}
}
$.ajax("api/values", {
type: "post",
contentType: "application/json",
data: { }, // JSON data goes here
dataType: "json",
headers: {
'RequestVerificationToken': '#TokenHeaderValue()'
}
});
</script>
Controller:
void ValidateRequestHeader(HttpRequestMessage request)
{
string cookieToken = "";
string formToken = "";
IEnumerable<string> tokenHeaders;
if (request.Headers.TryGetValues("RequestVerificationToken", out tokenHeaders))
{
string[] tokens = tokenHeaders.First().Split(':');
if (tokens.Length == 2)
{
cookieToken = tokens[0].Trim();
formToken = tokens[1].Trim();
}
}
AntiForgery.Validate(cookieToken, formToken);
}
Source: https://www.asp.net/web-api/overview/security/preventing-cross-site-request-forgery-csrf-attacks

Model Binding and posting form via ajax

I want to post a form via ajax call also model will be passed into the action method, but want to get Model errors via json. How can I do this?
You could write a custom action filter:
public class HandleJsonErrors : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var modelState = (filterContext.Controller as Controller).ModelState;
if (!modelState.IsValid)
{
// if the model is not valid prepare some JSON response
// including the modelstate errors and cancel the execution
// of the action.
// TODO: This JSON could be further flattened/simplified
var errors = modelState
.Where(x => x.Value.Errors.Count > 0)
.Select(x => new
{
x.Key,
x.Value.Errors
});
filterContext.Result = new JsonResult
{
Data = new { isvalid = false, errors = errors }
};
}
}
}
and then put it into action.
Model:
public class MyViewModel
{
[StringLength(10, MinimumLength = 5)]
public string Foo { get; set; }
}
Controller:
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
[HttpPost]
[HandleJsonErrors]
public ActionResult Index(MyViewModel model)
{
// if you get this far the model was valid => process it
// and return some result
return Json(new { isvalid = true, success = "ok" });
}
}
and finally the request:
$.ajax({
url: '#Url.Action("Index")',
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify({
foo: 'abc'
}),
success: function (result) {
if (!result.isvalid) {
alert(result.errors[0].Errors[0].ErrorMessage);
} else {
alert(result.success);
}
}
});
Something like this?
$.ajax({
type: "POST",
url: $('#dialogform form').attr("action"),
data: $('#dialogform form').serialize(),
success: function (data) {
if(data.Success){
log.info("Successfully saved");
window.close();
}
else {
log.error("Save failed");
alert(data.ErrorMessage);
},
error: function(data){
alert("Error");
}
});
[HttpPost]
public JsonResult SaveServiceReport(Model model)
{
try
{
//
}
catch(Exception ex)
{
return Json(new AdminResponse { Success = false, ErrorMessage = "Failed" }, JsonRequestBehavior.AllowGet);
}

MVC Return Partial View as JSON

Is there a way to return an HTML string from rendering a partial as part of a JSON response from MVC?
public ActionResult ReturnSpecialJsonIfInvalid(AwesomenessModel model)
{
if (ModelState.IsValid)
{
if(Request.IsAjaxRequest()
return PartialView("NotEvil", model);
return View(model)
}
if(Request.IsAjaxRequest())
{
return Json(new { error=true, message = PartialView("Evil",model)});
}
return View(model);
}
You can extract the html string from the PartialViewResult object, similar to the answer to this thread:
Render a view as a string
PartialViewResult and ViewResult both derive from ViewResultBase, so the same method should work on both.
Using the code from the thread above, you would be able to use:
public ActionResult ReturnSpecialJsonIfInvalid(AwesomenessModel model)
{
if (ModelState.IsValid)
{
if(Request.IsAjaxRequest())
return PartialView("NotEvil", model);
return View(model)
}
if(Request.IsAjaxRequest())
{
return Json(new { error = true, message = RenderViewToString(PartialView("Evil", model))});
}
return View(model);
}
Instead of RenderViewToString I prefer a approach like
return Json(new { Url = Url.Action("Evil", model) });
then you can catch the result in your javascript and do something like
success: function(data) {
$.post(data.Url, function(partial) {
$('#IdOfDivToUpdate').html(partial);
});
}
$(function () {
$("select#ExamID").change(function (evt) {
var classid = $('#ClassId').val();
var StudentId = $('#StudentId').val();
$.ajax({
url: "/StudentMarks/ShowStudentSubjects",
type: 'POST',
data: { classId: classid, StudentId: StudentId, ExamID: $(this).val() },
success: function (result) {
$('#ShowStudentSubjects').html(result);
},
error: function (xhr) { alert("Something seems Wrong"); }
});
});
});

Resources