Pass ViewModel to JSONresult in controller - model-view-controller

My application was working but I was asked to change how message are displayed by using the JSONResponseFactory. But when I try that my ViewModel is empty going back to the JSonResult (which used to be ActionResult). I've been told I may have to serialize the form fields. Here are some present code excerpts:
cshtml:
function SubmitForm() {
$.ajaxSetup({ cache: false });
$.post('#Url.Action("StoreLevelPlanning", "StoreLevelPlanning")', { actionType: "Submit"})
.done(function (data) {
if (data.Success == true) {
CreateInformationMessage(data.Message, 'window.location.href = "#Url.Action("storemanagement", "AccountListing")";');
}
else {
CreateErrorMessage(data.Message);
}
});
}
Controller:
public JsonResult StoreLevelPlanning_Post(string actionType) // actionType is Save or Submit
{
// message to return to the view on success
string successMessage = "";
var model = new VM_StoreLevelPlanning();
TryUpdateModel(model);
try
{
if (ModelState.IsValid)
{
model.buttonPressed = actionType;
repo.UpdateCLPCategoryAndRemark(model);
//Render different message depending on ActionType
if (actionType == "Save")
{
successMessage = "Your plan was saved. You will now be directed to the Listing Screen";
}
else if (actionType == "Submit")
{
successMessage = "Your plan has been submitted. You will now be directed to the Listing Screen.";
}
else
{
//return RedirectToAction("storemanagement", "AccountListing");
// need to revisit to figure out if this can be removed
throw new Exception("Else case happened");
}
}
else
{
if (actionType == "Save")
{
// TODO : change this to throw an error so that the ErrorLog class is utilized
throw new Exception("Your plan was not saved. Please retry.");
}
else
{
// TODO : change this to throw an error so that the ErrorLog class is utilized
throw new Exception("Your plan was not submitted. Please retry.");
}
}
}
catch (Exception e)
{
return Json(JsonResponseFactory.ErrorResponse(e.Message));
}
return Json(JsonResponseFactory.SuccessResponse(successMessage));
}
I'm open to any suggestions since I'm new to MVC. The idea is to put out a successful save message and redirect the user to the Listing page. But he way I changed the code now the view model is empty. It does not use a form collection. The data is in a list in the view model.
Thank you in advance...

Related

Ajax Error 500: A circular reference was detected

I'm trying to update my view with new information, so when it is sent to the controller for saving, the information gets passed.
The same method works fine when creating an object (Create-View) but throws an ajax error 500: A circular reference was detected while serializing an object of type 'System.Data.Entity.DynamicProxies.Gutscheine_', when editing an existing object (Edit-View).
Here's my ajax-call:
function onCloseButtonClick(s) {
$.ajax({
type: "POST",
url: "#Url.Action("UpdateGutscheinEdit")",
data: { sBild: document.getElementById(s).value, bIcon: true },
success: function (response) {
document.getElementById("sBild").value = response.sBild;
document.getElementById("bIcon").value = response.bIcon;
document.getElementById("fileToUpload").value = "";
popupIconAuswaehlen.Hide();
},
error: function (jqxhr, status, exception) {
alert(jqxhr.status); //throws 500
alert('Exception', exception);
}
})
}
And here's the method:
public ActionResult UpdateGutscheinEdit(string sBild, bool bIcon)
{
Gutscheine currentGutschein = Session["CurrentGutscheinEdit"] as Gutscheine;
if (!string.IsNullOrEmpty(sBild))
{
currentGutschein.sBild = sBild;
currentGutschein.bIcon = bIcon;
}
Session["CurrentGutscheinEdit"] = currentGutschein;
return Json(currentGutschein);
}
The Edit-(get)-method is a standard one:
public ActionResult Edit(string id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Gutscheine gutscheine = db.Gutscheine.Find(id);
if (gutscheine == null)
{
return HttpNotFound();
}
if(Session["CurrentGutscheinEdit"] == null)
{
Session["CurrentGutscheinEdit"] = gutscheine;
}
return View(Session["CurrentGutscheinEdit"] as Gutscheine);
}
Circular reference gives some hint, but I'm pretty new to all this, so it doesn't help me much in figuring out the problem.
If you have any ideas how to fix this, please let me know. Any help is appreciated!
Adding db.Configuration.ProxyCreationEnabled = false; before getting the object from the database did the trick.
Finished code: (I also removed some stuff at the end which screwed something else up)
public ActionResult Edit(string id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
db.Configuration.ProxyCreationEnabled = false;
Gutscheine gutscheine = db.Gutscheine.Find(id);
if (gutscheine == null)
{
return HttpNotFound();
}
Session["CurrentGutscheinEdit"] = gutscheine;
return View(Session["CurrentGutscheinEdit"] as Gutscheine);
}
Big thanks to the commenter that provided the link!

How do i use the AJAX request in JSP

I have created a registration page in JSP and I wanted to validate it with AJAX. So far I have written a piece of code that creates a request object(AJAX).
validate.js
window.onload=initPage;
function initPage() {
document.getElementById("username").onblur = checkUsername;
document.getElementById("register").disabled = true;
}
function createRequest() {
try {
request = new XMLHttpRequest();
} catch (tryMS) {
try {
request = new ActiveXObject("Msxml2.XMLHTTP");
} catch (otherMS) {
try {
request = new ActiveXObject("Microsoft.XMLHTTP");
} catch (failed) {
request = null;
}
}
}
return request;
}
function checkUsername() {
document.getElementById("username").className="thinking";
request=createRequest();
if(request==null)
alert("Unable To Fetch Request");
else
{
var name=document.getElementById("username").value;
var userName=escape(name);
var url="checkName.jsp?username="+userName;
request.onreadystatechange=showUserNameStatus;
request.open("GET", url, true);
request.send(null);
}
}
The problem that I'm into is the url. I don't know how to validate that username in checkName.jsp. Actually the scenario is if the userName is validated then user can register himself and if the username is already registered, then server should force the user to choose different username.
function showUserNameStatus() {
if(request.readyState==4)
{
if(request.status==200)
{
if(request.responseText=="okay")
{
document.getElementById("username").className="approved";
document.getElementById("register").disabled = false;
}
else
{
document.getElementById("username").className = "denied";
document.getElementById("username").focus();
document.getElementById("register").disabled = true;
}
}
}
}
If I understand, you have a registration page jsp , in which you are posting an AJAX call to validate the user , if the user is valid then you want to go ahead else you would like to throw back stating the user is already present ,choose a new one .
Instead of posting a call to the jsp ,what I will suggest is you can post the same to a servlet/controller/action class (whichever standard framework you are referring to) and then return back the response to the ajax call.

ASP.NET MVC Ajax Error returning view instead of ajax

I'm making an ASP.NET MVC call to a method via AJAX and the error throws an exception. I'd like the message of the exception to be passed back to the client, and I'd prefer not to have to catch the exception. Something like this:
[HttpPost]
public ActionResult AddUser(User user) {
if (UserIsValid(user)) {
return Json(new { resultText = "Success!" });
}
throw new Exception("The user was invalid. Please fill out the entire form.");
}
I'm seeing in my firebug response an HTML page
<!DOCTYPE html>
<html>
<head>
<title>"The user was invalid. Please fill out the entire form."</title>
.....
I'd like to not be forced to use a try catch block to do this. Is there a way to automatically get the jQuery $(document).ajaxError(function () {} to read in this exception message? Is this bad practice? Can I override the controller OnException? Or do I have to try/catch and return JSON?
Something like this would be nice:
$(document).ajaxError(function (data) {
alert(data.title);
});
You can do this with a custom filter:
$(document).ajaxError(function(event, jqxhr) {
console.log(jqxhr.responseText);
});
-
[HttpPost]
[CustomHandleErrorAttribute]
public JsonResult Foo(bool isTrue)
{
if (isTrue)
{
return Json(new { Foo = "Bar" });
}
throw new HttpException(404, "Oh noes...");
}
public class CustomHandleErrorAttribute : HandleErrorAttribute
{
public override void OnException(ExceptionContext filterContext)
{
var exception = filterContext.Exception;
var statusCode = new HttpException(null, exception).GetHttpCode();
filterContext.Result = new JsonResult
{
JsonRequestBehavior = JsonRequestBehavior.AllowGet, //Not necessary for this example
Data = new
{
error = true,
message = filterContext.Exception.Message
}
};
filterContext.ExceptionHandled = true;
filterContext.HttpContext.Response.Clear();
filterContext.HttpContext.Response.StatusCode = statusCode;
filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
}
}
Somewhat inspired by this blogpost: http://www.prideparrot.com/blog/archive/2012/5/exception_handling_in_asp_net_mvc
Rather than handle an exception that was raised by the server, why not have a flag in the JSON response?
[HttpPost]
public ActionResult AddUser(User user) {
if (UserIsValid(user)) {
return Json(new { success = true, resultText = "Success!" });
}
return Json(new { success = false, resultText = "The user was invalid. Please fill out the entire form." });
}

Scorm module launch window to be able to resize

I get the metadata and manifest file from people then when I launch it the window the window is too small or to big. In my Scrom controller I make provision for it to be resized and the new values be saved.
[HttpGet]
[NoCache]
public JsonResult ToggleLaunchResize(int scormModuleId)
{
var module = ZincService.ScormService.GetScormModule(scormModuleId);
if (module != null)
{
try
{
module.LaunchResize = !module.LaunchResize;
ZincService.ScormService.UpdateScormModuleSettings(module);
ZincService.SaveChanges();
return Json(new { hasLaunchResize = module.LaunchResize ? "Yes" : "No" }, JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{
Logger.Error(ex, "Error toggling HasLaunchResize property for scorm module with Id " + scormModuleId);
return Json(new { hasLaunchResize = "unkown" }, JsonRequestBehavior.AllowGet);
}
}
else
return Json(new { success = false }, JsonRequestBehavior.AllowGet);
}
If I select yes, why can I not resize the window?
Im a noob so dont know how this all works yet.
please help?
thanks

not able to navigate using RedirectToAction

I am notable to naviagate to another page using Redirect ie when result is false, then i would like to navigate to exception page which is not happening.
public ActionResult IsLoginExsit(CustomerDO loginData)
{
if (!string.IsNullOrEmpty(loginData.UserName) && !string.IsNullOrEmpty(loginData.Password))
{
bool result = Businesss.Factory.BusinessFactory.GetRegistrations().IsLoginExist(loginData.UserName, loginData.Password);
if (result)
{
CustomerDO custInfo = new CustomerDO();
JsonResult jsonResult = new JsonResult();
jsonResult.Data = loginData;
custInfo = Businesss.Factory.BusinessFactory.GetRegistrations().GetCustInfoByUserName(loginData.UserName);
SessionWrapper.SetInSession("CustomerID", custInfo.Id);
SessionWrapper.SetInSession("CustomerFirstName", custInfo.FirstName);
SessionWrapper.SetInSession("CustomerLastName", custInfo.LastName);
return jsonResult;
}
else
{
return RedirectToAction("UnAuthorized", "Exceptions");
}
}
return View();
}
You seem to be invoking this action using AJAX. If you want to redirect this should be done on the client side in the success callback of this AJAX call using window.location.href. So for example you could adapt your action so that in case of error it returns a JSON object containing the url to redirect to:
else
{
return Json(new { errorUrl = Url.Action("UnAuthorized", "Exceptions") });
}
and then inside your AJAX success callback:
success: function(result) {
if (result.errorUrl) {
window.location.href = result.errorUrl;
} else {
...
}
}

Resources