I'm working on small mvc application, and on one point I need a value from my Controller's Method, and my plan is to store that value in a ViewBag and get it on a View, so I did next:
ViewBag.SuccessBody = "This is a test";
And on my Razor View what I did was next:
<input id="customInput" type="hidden" value='@(ViewBag.SuccessBody)' />
//For testing purpose I tried with example below also ..
<input id="customInputAgain" type="hidden" class="form-control" value="@(ViewBag.SuccessBody)">
And when View loads I tried to get a value so I wrote this:
<script>
$(document).ready(function () {
var customVal = $("#customInput").val();
var customValAgain = $("#customInputAgain").val();
alert(customVal);
alert(customValAgain);
});
</script>
I even tried adding a
alert(customVal.value);
alert(customValAgain.value);
But it is not working also, so looks like I am not retrieving values from my Controller/ViewBag that is reason why alert allways show empty space - nothing.
EDIT :
I am setting this ViewBag value on a Edit of my article, acttualy on a [HttpPost] EDIT
, so when user clicks Save Changes [HttpPost] EDIT
method is invoked and when data is probably inserted in a database I am setting ViewBag value and redirecting user to same [HttpGet] Edit method. Here is how that does looks:
[HttpPost]
public ActionResult Edit(ArticleEditViewModel model)
{
if (ModelState.IsValid)
{
//Rest of the code
ViewBag.SuccessBody = "This is a test";
return RedirectToAction("Edit/" + product.Id, "Article");
}
else
{
return View("NotFound");
}
return View(model);
}
As you can see guys I defined ViewBag but I can not get the value on a View which should be stored in a input control..
Maybe the issue is because I defined a ViewBag in a HttpPost Action method and not in HttpGet where from I'm "opening the view" ?
I would use .attr()
as I prefer explicitly knowing what I'm targeting:
var customVal = $("#customInput").attr("value");
As for the server-side, make sure that ViewBag.SuccessBody
is actually declared and returns something.
public ActionResult FooAction()
{
ViewBag.SuccessBody = "This is a test";
return View();
}
Also make sure that you're returning ViewBag.SuccessBody
from the correct action method, to it's corresponding view.
Update
Based on your edit: you're redirecting to a different action (the Edit [HttpGet]
one), so obviously ViewBag.SuccessBody
is not defined there. Why not just pass a bool? editSuccess
parameter to your [HttpGet]
Edit method, indicating whether the edit was successful or not?
[HttpGet]
public ActionResult Edit(int id, bool? editSuccess)
{
if (editSuccess.HasValue)
{
if (editSuccess)
{
// edit was successful here
ViewBag.SuccessBody = "Yay! :)";
}
else
{
// edit was unsuccessful here
ViewBag.SuccessBody = "No! :(";
}
}
// other stuff
return View();
}
Your [HttpPost]
action then becomes:
[HttpPost]
public ActionResult Edit(ArticleEditViewModel model)
{
if (ModelState.IsValid)
{
// ...
RedirectToAction("Edit", new { id = product.Id, editSuccess = true });
}
else
{
// ...
}
}
Using this approach you can specify when the edit might have failed as well, by setting editSuccess
to false
. If you're simply interested in passing whatever value back to the view, then skip all the editSuccess
parts and simply return ViewBag.SuccessBody
from the [HttpGet]
action, instead of the [HttpPost]
one.
Aside: Obviously, as editSuccess
is optional and you're only setting ViewBag.SuccessBody
to something when editSuccess
actually has a value, you can do this check in the view to determine whether to output something or not in the HTML:
@if (!string.IsNullOrEmpty(ViewBag.SuccessBody))
{
// not empty, do something
}