Ive been following an example from a book of how to use the ajax to load a partial view in an existing webpage, but cant get it working.
Chrome's element inspectors tells me that the file can not be found (404), but when i navigate to the page manaualy, it loads fine.
Here is my controller:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MvcApplication1.Controllers
{
public class HomeController : Controller
{
//
// GET: /Home/
public ActionResult Index()
{
ViewBag.Message = "Hello";
return View();
}
[HttpGet]
public PartialViewResult HelloWorld()
{
ViewBag.Message = "Hello World";
return PartialView();
}
}
}
Here is my main view:
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<title>index></title>
<script src="../../Scripts/jquery-1.8.3.js" type="text/javascript"></script>
<script src="../../Scripts/jquery.unobtrusive-ajax.min.js" type="text/javascript"></script>
</head>
<body>
<div>
<div id="divMessage">#ViewBag.Message</div>
#Ajax.ActionLink("Refresh", "HelloWorld", new AjaxOptions { HttpMethod = "POST", UpdateTargetId = "divMessage", InsertionMode = InsertionMode.Replace })
</div>
</body>
</html>
and here is my partial view:
#ViewBag.Message
Can anybody suggest any reasons why this is not working?
Thanks
You specify the Ajax call to be a POST, while the PartialView method is [HttpGet]
Change either the ajax call to "GET" or the method to [HttpPost]
You have to change your method
public PartialViewResult HelloWorld()
{
ViewBag.Message = "Hello World";
return PartialView();
}
to [HttpPost] , as your ajax call makes a Post call.
Or change your ajax call to make a GET call.
Related
I am new to ASP.NET MVC. I want to call a method of a controller which is not an action method in a view through $.ajax but I am getting error in browser console. I want to ask that is it not possible to call a method which is not action method through ajax.
Code for view
#{
ViewBag.Title = "About Us";
}
<script type="text/javascript">
function ajaxcall() {
$.ajax({
url: '/Home/ValidatePin',
type: 'Post',
success: function (result) {
alert(result.d);
}
})
}
</script>
<h2>About</h2>
<p>
Put content here.
<input type="button" onclick="ajaxcall()" value="clickme" />
</p>
Here is my code for method
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Services;
namespace MvcApplication1.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.Message = "Welcome to ASP.NET MVC!";
return View();
}
public ActionResult About()
{
return View();
}
[WebMethod]
public static string ValidatePin()
{
return "returned from controller class";
}
}
}
All public methods of a controller are actions, unless marked with the NonAction attribute.
The [WebMethod] attribute comes from ASP.NET web services (non MVC) and has no effect in an MVC controller.
Your ValidatePin method is not called because it's static. Action methods must be instance methods.
I have a class and create an instance and fill a property in my index but when I push the submit button in my view and return again to my index action the property of my class is null.
How can I save the data when I return to my action and retrieve it? Is it possible?
I used viewbag and viewdata in my index and fill theme but when returned to index action again all of theme were null :(
public class myclass
{
public string tp { get; set; }
}
public class HomeController : Controller
{
//
// GET: /Home/
myclass myc = new myclass();
public ActionResult Index()
{
myc.tp = "abc";
return View(myc);
}
}
View:
#model MvcApplication2.Controllers.myclass
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<title>Index</title>
</head>
<body>
#using (Html.BeginForm())
{
<input id="Submit1" type="submit" value="submit" />
}
</body>
</html>
simply use either GET or POST method in your Controller according to your form method like,
[HttpGet]
public ActionResult Index(string id)
{
myc.tp = id;
return View(myc);
}
In your HttpPost you can get the model and see it's properties if you provided input fields for the properties in your view.
[HttpPost]
public ActionResult Index(myclass myc)
{
//check the myc properties here
return View(myc);
}
Then in your View:
#using (Html.BeginForm())
{
#Html.TextBoxFor(m => m.tp)
I am new to MVC. using MVC 3.
I have PersonMaster Controller as below... having following two Actions.
public ActionResult TopTenPersons()
{
Thread.Sleep(2000);
var persons = DatabaseHelper.Instance.Database.Query<Person_Master>("select top(10) from person_master").ToList();
return View("_PersonGrid", persons);
}
public ActionResult Index()
{
var persons = DatabaseHelper.Instance.Database.Query<Person_Master>("select * from person_master").ToList();
return View("_PersonGrid",persons);
//return View();
}
Then, index.cshtml view is as follows..
#model System.Collections.Generic.ICollection<MyPracticeApp1.Models.Person_Master>
#section scripts{
<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>
}
<h2>Persons</h2>
<p>
#Ajax.ActionLink("Click to top 10 Persons","TopTenPersons", new AjaxOptions{
UpdateTargetId="tbl_person",
InsertionMode=InsertionMode.Replace,
HttpMethod="GET"
})
</p>
<div id="tbl_person">
#Html.Action("Index","PersonMaster");
</div>
..and partial view _PersonGrid.cshtml which is called above in index view is as follows...
#model System.Collections.Generic.ICollection<MyPracticeApp1.Models.Person_Master>
#{
var persongrid = new WebGrid(Model);
}
#persongrid.GetHtml()
....But problem is that it directly shows partial view. It is not rendering Ajax Actionlink of index view. So, where is the mistake?
Change TopTenPersons to return a Partial View, not a View
public ActionResult Index()
{
var persons = DatabaseHelper.Instance.Database.Query<Person_Master>("select * from person_master").ToList();
return PartialView("_PersonGrid",persons);
}
add layout=null to _PersonGrid.cshtml
seems like
#{
Layout = null;
}
when you add this code It is not rendering full view..
I am using Tinymce inside an asp.net mvc 3 Razor application. An Ajax.ActionLink loads the tinymce editor via a call to a controller action named "GetContent". The GetContent method loads a text file from the file system. All is well. But, after I save the tinymce text via an $.ajax call, the Ajax.ActionLink no longer fires the controller method. In other words, something in the $.ajax post breaks the Ajax.ActionLink on the client so that it no longer calls the GetContent controller action.
Interestingly, the Ajax.ActionLink still loads the tinymce editor, but from the browser cache. In the example below I have 2 links "FileOne" and "FileTwo", which load two different text files. Before I call $.ajax the links load the file from disk. After I call $.ajax the links load the last "FileOne" or "FileTwo" from the browser cache.
This is the view. The $.ajax post occurs inside the tiny_mce_save_click() function, which is wired to the tinymce save button click:
#model TestTinyMCE.Models.HomeModel
#{
ViewBag.Title = "Home Page";
}
#section JavaScript
{
<script src="#Url.Content("~/Scripts/tiny_mce/jquery.tinymce.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>
<script type="text/javascript">
$().ready(function () {
init_tiny_mce();
});
function init_tiny_mce() {
$('textarea.tinymce').tinymce({
// Location of TinyMCE script
script_url: '/Scripts/tiny_mce/tiny_mce.js',
//javascript function called when tinymce save button is clicked.
save_onsavecallback: "tiny_mce_save_click",
encoding: "xml",
theme: "advanced",
plugins: "save",
theme_advanced_buttons1: "save",
theme_advanced_toolbar_location: "top"
});
}
function tiny_mce_save_click(tinyMceInstance) {
$.ajax({
type: 'POST',
url: '/Home/SaveContent',
data: $('form').serialize(),
success: function (data, status, xml) {
$('#results').html(data);
},
error: function (xml, status, error) {
$('#results').html(error);
}
});
return false;
}
</script>
}
#using (Html.BeginForm())
{
<ul>
#foreach (string fileName in Model.FileList)
{
<li>#Ajax.ActionLink(fileName, "GetContent", new { FileName = fileName }, new AjaxOptions() { UpdateTargetId = "divContent" })</li>
}
</ul>
<div id="divContent">
#Html.Partial("GetContent", Model)
</div>
}
The partial view "GetContent" is:
#model TestTinyMCE.Models.HomeModel
#{
Layout = null;
}
<div id="divContent">
<fieldset id="fsContent">
<span id="results"></span><legend>Edit Content #Html.DisplayTextFor(m => m.FileName)</legend>
#Html.TextAreaFor(m => m.Content,
new Dictionary<string, object>{
{"class","tinymce"}, {"cols","80"}, {"rows","10"}}
)
#Html.HiddenFor(m => m.FileName)
</fieldset>
#if (#IsAjax)
{
<text>
<script type="text/javascript">init_tiny_mce();</script>
</text>
}
</div>
This is the controller. The GetContent method no longer gets called after the $.ajax post occurs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using TestTinyMCE.Models;
namespace TestTinyMCE.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
return View(new HomeModel());
}
public ActionResult GetContent(HomeModel homeModel)
{
if (!string.IsNullOrEmpty(homeModel.FileName))
{
string path = string.Format("~/App_Data/{0}.htm", homeModel.FileName);
string physicalPath = Server.MapPath(path);
if (!System.IO.File.Exists(physicalPath))
homeModel.Content = string.Format("The file '{0}' does not exist.", physicalPath);
else
homeModel.Content = System.IO.File.ReadAllText(physicalPath);
}
return View(homeModel);
}
[HttpPost]
[ValidateInput(false)]
public ActionResult SaveContent(HomeModel homeModel)
{
string path = string.Format("~/App_Data/{0}.htm", homeModel.FileName);
string physicalPath = Server.MapPath(path);
System.IO.File.WriteAllText(physicalPath, homeModel.Content);
ViewBag.Result = "The file was successfully saved.";
return View();
}
}
}
The problem is broswer caching. To prevent caching on the Ajax.ActionLink you must add AjaxOption HttpMethod = "POST". In the above code change ActionLink to
<li>#Ajax.ActionLink(fileName, "GetContent", new { FileName = fileName }, new AjaxOptions() { UpdateTargetId = "divContent", HttpMethod = "POST" })</li>.
See http://forums.asp.net/t/1681358.aspx?Disable+cache+in+Ajax+ActionLink+extension+method+in+asp+net+MVC
in my view:
<script src="../../Scripts/MicrosoftAjax.js" type="text/javascript"></script>
<script src="../../Scripts/MicrosoftMvcAjax.debug.js" type="text/javascript"></script>
<script src="../../jquery-1.4.1-min.js" type="text/javascript"></script>
<%= Ajax.ActionLink("Update", "Index", "Home", new AjaxOptions { UpdateTargetId = "time" })%>
<br />
<div id="time">
<% Html.RenderPartial("TimeControl"); %>
</div>
in my controller:
[HttpGet]
public ActionResult Index()
{
HomeModel model = new HomeModel(Request.Url.Host);
// Normal Request
if (!Request.IsAjaxRequest())
{
return View("Index", model);
}
// Ajax Request
return PartialView("TimeControl");
}
in my model:
public HomeModel()
{
Time = DateTime.Now;
}
i think everything is ok, but if iam clicking update link, time will be not updated.. why?
it schould be actual if i click update link
I suggest you do the following:
[HttpGet]
public ActionResult Index()
{
HomeModel model = new HomeModel(Request.Url.Host);
return View("Index", model);
}
[HttpPost]
public ActionResult Index()
{
HomeModel model = new HomeModel(Request.Url.Host);
// Ajax Request
return PartialView("TimeControl");
}
I think the problem might be that the AJAX request is a POST.
You may simply try to (1) remove [HttpGet] or (2) set the HttpMethod in the AjaxOptions to "GET".
Ajax.ActionLink("Update", "Index", "Home", new AjaxOptions { UpdateTargetId = "time", HttpMethod = "get" })
That should solve the problem.
(3) If it doesn't, check if you are using the correct overload. This should work:
Ajax.ActionLink("Update", "Index", "Home", null, new AjaxOptions { UpdateTargetId = "time" }), null)
Any of the options in my previous answers could solve your problem if the AJAX isn't working correctly with your application.
Buy in your example, you're also using something that wasn't quite clear to me.
You use a constructor overload that takes the url. And you use the default constructor to set the time. Is the constructor you use (the one that takes the url) also calling the parameterless constructor?
That constructor should do something like this:
public HomeModel(paramter.......) : this()
{
// Whatever...
}