parsing json from asp.net mvc controller action to ajax.actionlink - asp.net-mvc

I am working on asp.net mvc application and I have added an actionlink like this:
<%= Ajax.ActionLink("Event Notifications", "processCallrecording", new { Id = ViewData["RecordingIDsEdit"] }, new AjaxOptions
{
OnSuccess = "StatusChanged",
HttpMethod = "POST"
})%>
My controller is like this:
[HttpPost]
public JsonResult ProcessCallRecording(int Id = 0)
{
int result = id;
return Json(new {NewStatus = result.ToString()});
}
My js function is like this:
function StatusChanged(data) {
alert("order #:" + data.NewStatus + "has a new status: "
+ data.NewStatus);
}
and I see undefined in alert. I am struggling for last 2 hours on this issue. Please suggest me what is wrong ?

Try this
<%= Ajax.ActionLink("Event Notifications", "processCallrecording", new { Id = Convert.ToInt32(ViewData["RecordingIDsEdit"]) }, new AjaxOptions
{
OnSuccess = "StatusChanged",
HttpMethod = "POST"
})%>
as you i have used viewData so you are missing Convert it into Int. also make sure i have added these script before action link.
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>

Related

How can I pass a parameter together with the Model?

Here's my View (Model ActivityViewModel):
#model GPMS.Models.ActivityViewModel
<div class="tab-pane" id="managepayments" role="tabpanel">
#{ Html.RenderPartial("_Payments", Model.Payments); }
</div>
Which render a Partial (Model IEnumerable<GPMS.Models.PaymentViewModel>):
#model IEnumerable<GPMS.Models.PaymentViewModel>
#using (Ajax.BeginForm("SavePayments", "Activities", new AjaxOptions { HttpMethod = "POST", UpdateTargetId = "DynamicContainer", InsertionMode = InsertionMode.Replace, OnBegin = "AjaxBeginFormOnBegin", OnComplete = "AjaxBeginFormOnComplete", OnSuccess = "AjaxBeginFormOnSuccess", OnFailure = "AjaxBeginFormOnFailure" }))
{
#Html.AntiForgeryToken()
<!-- My Form -->
}
Which send Ajax request to my Controller's Action:
public ActionResult SavePayments(IEnumerable<PaymentViewModel> payments)
{
if (ModelState.IsValid) {
// code; here I need ActivityViewModel.ID
}
}
The question is: how can I pass to that SavePayments also my activity ID stored in ActivityViewModel.ID? Can I do with routing?
I don't want to pass the whole ActivityViewModel to SavePayments, otherwise I need to take care of its required fields for the ModelState.IsValid check.
One option is to use the overload of Html.Partial to pass the ID using additionalViewData, then retrieve it in the partial view and add it as a route value in the form.
In the main view
#{ Html.RenderPartial("_Payments", Model.Payments, new ViewDataDictionary { { "ID", Model.ID} }); }
And in the partial
#using (Ajax.BeginForm("SavePayments", "Activities", new { id = ViewData["ID"] }, new AjaxOptions { ....
Then add a parameter in the POST method for the ID
public ActionResult SavePayments(int id, IEnumerable<PaymentViewModel> payments)

Viewbag is null in alert

i wrote behind code.
but Viewbag.message will show null in alert message .myvar is a variable.
i used breakpoint , myvar will set by Viewbag.message correctly. but it will be shown null in alert .
<script src="~/Scripts/jquery-1.7.1.js"></script>
<script src="~/Scripts/jquery.unobtrusive-ajax.js"></script>
#{string myvar = ViewBag.AlertMessage;}
#using (Ajax.BeginForm("action", "controller", new AjaxOptions { HttpMethod = "Post", OnSuccess = "Messsage" }))
{
<script type="text/javascript">
function Messsage() {
alert('#ViewBag.AlertMessage'); //infact, it shows alert('');
}
</script>
<script type="text/javascript">
function Messsage() {
alert('#myvar'); // should show "hello there"
}
</script>
#using (Ajax.BeginForm("AjaxAction", "Home", new AjaxOptions { HttpMethod = "Post", OnSuccess = "Messsage" }))
{
<script type="text/javascript">
function Messsage() {
alert("#ViewBag.AjaxMessage");
}
</script>
<input type="submit" value="Submit" />
}
is the ViewBag.AlertMessage being defined in the controller action ?
you can replace the data by
#{string myvar = "hello there !";}
<script type="text/javascript">
function Messsage() {
alert('#myvar'); // should show "hello there"
}
</script>
or define your viewbag item in the action method behind the result
public ActionResult Index() {
ViewBag.AlertMessage = "hello there !"
return View();
}
Try setting the value for ViewBag.AlertMessage in controller action that returns the view on which you have defined the Ajax.Begin form.
eg
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application.";
ViewBag.AlertMessage = "AjaxMessage.";
return View();
}
}
on Index view i have placed the following code, calling AjaxAction on Home Controller.
#using (Ajax.BeginForm("AjaxAction", "Home", new AjaxOptions { HttpMethod = "Post", OnSuccess = "Messsage" }))
{
<script type="text/javascript">
function Messsage() {
alert("#ViewBag.AjaxMessage");
}
</script>
<input type="submit" value="Submit" />
}

Contact Form Within Partial View

I have to admit, the transition from Web Forms to MVC is literally blowing my mind. I simply can not seem to wrap my head around how MVC functions as it compares to Web Forms, and I continue to hit roadblock after roadblock when trying to perform seemingly simple tasks. Couple this with a rudimentary knowledge of javascript/jquery, and I'm left scratching my head most days.
I have been working to transition a custom CMS that my company built from Web Forms to MVC. This CMS allows for the creation of pages and the manipulation of the site navigation, which resulted in the creation of a page model, along with related views and controllers.
While the client can edit 99% of the site, some elements are static and are loaded on demand on specific pages. For example, the Contact page exists within the CMS, but the site injects the actual contact form on demand.
When build in Web Forms, this contact form was simply a User Control, with its own logic for handing the postback. I thought the logical transition here would be the creation of a Partial View, but I have run into ridiculous amounts of difficulty in accomplishing this task. While I have been able to create the model, view and controller for this contact form, I simply can't seem to make it work correctly.
After literally 3 days of scouring Stack Overflow for advice, I completed nearly everything to make this work. However, I can't figure out how to perform a seemingly simple redirect from the Partial View to save my life. I have tried numerous approaches, including the one described at Doug.Instance, but haven't had any luck. Upon post, the partial view returns as an entire view, even though the controller uses 'return PartialView'. If I post it again, it returns as it originally displayed, as a partial view. In addition, my Redirect variable is not updating upon success, AND the OnSuccess javascript is not firing.
Below is my code. Please help me, because I'm running out of hair...
PAGE VIEW (SHORTENED FOR BREVITY)
...
#if (Model.ID == 8)
{
//LOAD CONTACT FORM
#Html.Action("Contact","ContactForm")
}...
CONTACT FORM PARTIAL VIEW (SHORTENED FOR BREVITY)
#model NCOWW.Models.ContactForm
<script src="#Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
<script type="text/javascript">
// Labels over the inputs.
window.addEvent("load", function () {
var myForm = document.id('contactForm');
myForm.getElements('[type=text], textarea').each(function (el) {
new OverText(el);
});
});
function FormComplete() {
if ($("#Redirect").val() != '') {
document.location = $("#Redirect").val();
}
}
</script>
#using (Ajax.BeginForm(new AjaxOptions { UpdateTargetId = "contactForm", OnSuccess = "FormComplete" }))
{
#Html.ValidationSummary(true)
<div id="contactForm">
#Html.HiddenFor(model => model.Redirect)
#Html.TextBoxFor(model => model.Name, new { tabindex = 1, #class = "half", Title = #Html.DisplayNameFor(model => model.Name) })
#Html.ValidationMessageFor(model => model.Name)
#Html.TextAreaFor(model => model.Comments, new { tabindex = 13, Title = #Html.DisplayNameFor(model => model.Comments) })
#Html.ValidationMessageFor(model => model.Comments)
<br />
<input type="submit" value="Submit" name="Submit" class="button" />
</div>
}
CONTACT FORM CONTROLLER (SHORTENED FOR BREVITY)
public ActionResult Contact(ContactForm c)
{
try
{
MailMessage message = new MailMessage();
message.IsBodyHtml = true;
message.From = new MailAddress(c.Email);
message.Body += "<b>Name:</b> " + c.FullName + "<br/><br/>";
message.Body += "<b>Questions/Comments:</b><br> " + c.Comments;
SmtpClient client = new SmtpClient();
client.Send(message);
c.Redirect = "/formsuccess";
return PartialView("contactForm", c);
}
catch
{
return PartialView();
}
}
the issue you have is common with ajax.
what you need to note is when ajax renders response it does not know about javascript you have returned.
you need to have some way of registering your javascript in order to get it triggered.
Now how to do this?
I have created one of ways, that works for me:
have javascript function on page that has reload.
function RedirectToLocation(url) {
//your javascript event here
}
your ajax call, I have ajax action link but begin form is almost the same
the part you are interested is AjaxOptions.
And event OnSuccess. this will get triggered when call is successful.
Example for link:
#Ajax.ActionLink("Comments", "AddComment", "Task", new { id =
Model.Task.TaskId, TaskStatus = (int)State.Closed },
new AjaxOptions { HttpMethod = "Get", UpdateTargetId = "showResults", OnSuccess = "RedirectToLocation" }, null)
And here you can read about ajax options more
Just point out issue in your code example for your action result
try
{
MailMessage message = new MailMessage();
message.IsBodyHtml = true;
message.From = new MailAddress(c.Email);
message.Body += "<b>Name:</b> " + c.FullName + "<br/><br/>";
message.Body += "<b>Questions/Comments:</b><br> " + c.Comments;
SmtpClient client = new SmtpClient();
client.Send(message);
c.Redirect = "/formsuccess";
return PartialView("contactForm", c);
}
catch
{
return PartialView(); <-- will render what, better will be if it renderes error mesasge partial view
}
try it by adding Action name in your PARTIAL VIEW
#using (Ajax.BeginForm("Action Name",new AjaxOptions { UpdateTargetId =
"contactForm", OnSuccess = "FormComplete" })) {
I was able to get this to work once I started rethinking about what I was actually trying to achieve. Instead of returning PartialView("contactForm", c);, I ended up returning Json(c);. I then parsed the returned Json and redirected from there. The final working code is as follows.
PAGE VIEW (SHORTENED FOR BREVITY)
...
#if (Model.ID == 8)
{
//LOAD CONTACT FORM
#Html.Action("Contact","ContactForm")
}...
CONTACT FORM PARTIAL VIEW (SHORTENED FOR BREVITY)
#model NCOWW.Models.ContactForm
<script src="#Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
<script type="text/javascript">
// Labels over the inputs.
window.addEvent("load", function () {
var myForm = document.id('contactForm');
myForm.getElements('[type=text], textarea').each(function (el) {
new OverText(el);
});
});
function FormComplete(result) {
if (result.Redirect != null && result.Redirect != '') {
document.location = result.Redirect;
}
}
</script>
#using (Ajax.BeginForm(new AjaxOptions { UpdateTargetId = "contactForm", OnSuccess = "FormComplete" }))
{
#Html.ValidationSummary(true)
<div id="contactForm">
#Html.HiddenFor(model => model.Redirect)
#Html.TextBoxFor(model => model.Name, new { tabindex = 1, #class = "half", Title = #Html.DisplayNameFor(model => model.Name) })
#Html.ValidationMessageFor(model => model.Name)
#Html.TextAreaFor(model => model.Comments, new { tabindex = 13, Title = #Html.DisplayNameFor(model => model.Comments) })
#Html.ValidationMessageFor(model => model.Comments)
<br />
<input type="submit" value="Submit" name="Submit" class="button" />
</div>
}
CONTACT FORM CONTROLLER (SHORTENED FOR BREVITY)
public ActionResult Contact(ContactForm c)
{
try
{
MailMessage message = new MailMessage();
message.IsBodyHtml = true;
message.From = new MailAddress(c.Email);
message.Body += "<b>Name:</b> " + c.FullName + "<br/><br/>";
message.Body += "<b>Questions/Comments:</b><br> " + c.Comments;
SmtpClient client = new SmtpClient();
client.Send(message);
c.Redirect = "/formsuccess";
return Json(c);
}
catch
{
//ERROR CATCH CODE
}
}

update div in ajax in asp.net mvc

i have written my codes by ajax as following : instead of updating div,has redirected to partial view.
according to update target id of ajax option is set,it cant update.
please help me
public class SearchController : Controller
{
public ActionResult search()
{
return View();
}
public PartialViewResult _search()
{
Thread.Sleep(3000);
ViewBag.message = "test";
return PartialView("_search");
}
}
#{
ViewBag.Title = "search";
}
<script src="../../Scripts/jquery-1.5.1.min.js" type="text/javascript"></script>
<h2>search</h2>
#Ajax.ActionLink("Click",
"_search",
new AjaxOptions
{
UpdateTargetId = "_search",
InsertionMode = InsertionMode.InsertAfter,
HttpMethod = "GET"
}
)
<div id="_search">
</div>
Make sure you have following scripts added into either of your view or masterview
jquery.unobtrusive-ajax.min.js
MicrosoftAjax.js
MicrosoftMvcAjax.js
try this
#Ajax.ActionLink("Click",
"_search",
null,
new AjaxOptions
{
UpdateTargetId = "_search",
InsertionMode = InsertionMode.InsertAfter,
HttpMethod = "GET"
}
)

Ajax.BeginForm show loadingElementId when OnBegin return false

Hello I'm having the same problem from this post:
Ajax.BeginForm not hiding loading element when onBegin fails but I have not found how to solve it yet.
Basically when I use Ajax.BeginForm with a OnBegin function and this function returns false, the loading elementID is still shown and it never hides again.
This is the code I'm testing it with:
function isValid() {
return false
}
<% using (Ajax.BeginForm("LogIn", "Security", new { ReturnUrl = Request["ReturnUrl"] }
, new AjaxOptions { UpdateTargetId = "resultErrors", OnBegin = "isValid", LoadingElementId = "updatePanel" }))
{ %>
I don't remember exactly the solution, i decided a long time ago that it was much better to write my own and plain Html to handle Ajax calls.
If you want you can post your code here and i can show you how to do it with JQuery.
Now if you want to stick with this solution you can still use JQuery to hide the element manually like this:
<% using (Ajax.BeginForm("LogIn", "Security", new { ReturnUrl = Request["ReturnUrl"] }
, new AjaxOptions { UpdateTargetId = "resultErrors", OnBegin = "isValid", LoadingElementId = "updatePanel" }))
{ %>
<script type="text/javascript" language="javascript" src="<%=Url.Content("~/Scripts/jquery-1.4.1.js") %>">//Jquery reference
</script>
<script type="text/javascript" language="javascript">
function isValid() {
if (true) // In case i whant to return true
{
return true;
}
else // I whant to return false
{
$('#updatePanel').hide(); // Manually hide the LoadingElementId
return false;
}
}
</script>

Resources