I have a simple .cshtml page and My problem is when I run this page alert is not shown. Here is the .cshtml page code:
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>ChartDataJSON</title>
<script type="text/javascript">
alert('hello');
</script>
</head>
<body>
<div>
<div id="chart1" ></div>
</div>
</body>
</html>
Also I have a controller class through which this view is generated. The lines written in that class are:
public class jqPlotController : Controller
{
//
// GET: /jqPlot/
public ActionResult Index()
{
return View();
}
public ActionResult ChartDataJSON()
{
var chartData = new List<jqplotModel>();
var point1 = new jqplotModel { Date = DateTime.Now.Date.ToString("yyyy-MM-dd h:mmtt"), Demand = Convert.ToDouble(1), Supply = Convert.ToDouble(3) };
var point2 = new jqplotModel { Date = DateTime.Now.AddDays(10).Date.ToString("yyyy-MM-dd h:mmtt"), Demand = Convert.ToDouble(2), Supply = Convert.ToDouble(4) };
var point3 = new jqplotModel { Date = DateTime.Now.AddDays(31).Date.ToString("yyyy-MM-dd h:mmtt"), Demand = Convert.ToDouble(6), Supply = Convert.ToDouble(6) };
var point4 = new jqplotModel { Date = DateTime.Now.AddDays(106).Date.ToString("yyyy-MM-dd h:mmtt"), Demand = Convert.ToDouble(4), Supply = Convert.ToDouble(2) };
chartData.Add(point1);
chartData.Add(point2);
chartData.Add(point3);
chartData.Add(point4);
return Json(chartData, JsonRequestBehavior.AllowGet);
}
}
Is this due to the “return” keyword in the controller class which stops alert pop up from appearing on the web page.
Has anybody faced this type of issue before. Can somebody help me in figuring out the problem?
Edit:
The view is added with respect to ChartDataJSON method of controller class.
Update: I have made following changes in view and the controller class is as mentioned above.
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>ChartDataJSON</title>
<script type="text/javascript">
$.ajax("/jqPlot/ChartDataJSON")
.done(function (data) {
// do something with the data.
alert("success");
})
</script>
</head>
<body>
<div>
<div id="chart1" ></div>
</div>
</body>
</html>
When returning JSON result you will not render out any Views (HTML markup). To return the HTML markup you must write this
return View("name of cshtml file without .cshtml");
where [name of view] is the name of the cshtml file you were referring to (without the .cshtml extension), and the model can be the data you want to use in the cshtml file.
To retrieve the data using ajax you can use this command as a example
$.ajax( "/jqPlot/ChartDataJSON" )
.done(function(data) {
// do something with the data.
alert( "success" );
})
Update:
To load the view you have to call an action that returns and renders the view. Lets say your view is named Index.cshtml and its full path is "Views/jqPlotController/Index.cshtml
Then all you have to do is call the URL of the action, http://[nameofdomain]/Index .
Then the view should be loaded and the javascript function trigger and call the action ChartDataJSON, which will return the JSON result and in this case the alert is triggered if the call to the action is successfull.
Related
i am new in MVC.I try to pass Current Date & Time by using Viewdata.But it does not get my code is here
namespace FirstHelloWorldProjct.Controllers
{
public class HelloWorldController : Controller
{
//
// GET: /HelloWorld/
public ActionResult Index()
{
ViewData["CurrentTime"] = DateTime.Now.ToString();
return View();
}
}
}
And my View Code here
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
</head>
<body>
<div>
This is Hello World...<br/>
The Current Date and time is <%= ViewData["CurrentTime"]%>
</div>
</body>
</html>
And output is here
This is Hello World...
The Current Date and time is <%= ViewData["CurrentTime"]%>
I think In Asp.net MVC we use Razor syntax as metion below.
you need to use #ViewData["CurrentTime"] instead of <%= ViewData["CurrentTime"]%>
how return razor code for layout of view instead of master page name
for example instead of
return View("Index", "_Layout");
use this code
return View("Index", #"
#using System.Diagnostics
#using iaumahallat.Helper
<!DOCTYPE html>
<html lang="en">
<head>
<title>#ViewBag.SiteTitle - #ViewBag.Title</title>
<meta name="description" content="#ViewBag.MetaDescription">
#Scripts.Render("~/bundles/modernizr")
</head>
<body>
#RenderBody()
#RenderSection("scripts", required: false)
</body>
</html>
");
One way is to use RazorEngine and parse the razor source code, then get the corresponding Html String to display it on the view or layout-
Razor.SetTemplateBase(typeof(HtmlTemplateBase<>));
string template =
#"<html>
<head>
<title>Hello #Model.Name</title>
</head>
<body>
Email: #Html.TextBoxFor(m => m.Email)
</body>
</html>";
var model = new PageModel { Name = "World", Email = "someone#somewhere.com" };
string result = Razor.Parse(template, model);
Then use result in the page of your interest.
I'm faking a form post using webclient like this:
public static string SendHttpRequest(string url, string method, List<WebParameter> paramaters)
{
using(WebClient client = new WebClient())
{
client.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
System.Collections.Specialized.NameValueCollection reqparm = new System.Collections.Specialized.NameValueCollection();
foreach (var param in paramaters)
{
reqparm.Add(param.name, param.value);
//reqparm.Add("param2", "escaping is already handled");
}
byte[] responsebytes = client.UploadValues(url, method, reqparm);
string responsebody = Encoding.UTF8.GetString(responsebytes);
return responsebody;
}
}
Its working well so far but the response is an html page. i want to embed this page inside my view.
My controller action looks like this
string response = SendHttpRequest(purl,"POST",param);
ViewBag.Response = response;
return View();
In my view when i called ViewBag.Response its showing me the raw html. This is not what i want. i want to display the page.
I'm thinking i can do this with an iframe but dont have idea how.
EDIT:
the expected response looks like this:
<!DOCTYPE html> <html> <head> <link rel='shortcut icon' type='image/x-icon' href='/test_paydirect/favicon.ico' /> <meta name="viewport" content="width=device-width, initial-scale = 1, maximum-scale=1, user-scalable=no" /> <title>WebPAY</title> <link href="/test_paydirect/Content/webpay?v=CSrAVoCR_RCkIRW_2W4qWDLY74gqncHw6gTHkYQDqPI1" rel="stylesheet"/> <script src="/test_paydirect/scripts/jquery?v=YDYC4uCmpbLIjqOyVNC_2sd9YbHnRonWjUni8iH6_Xo1"></script> </head> <body> <div id="outer-frame"> <div id="page-header"> <div id="account-header"> </div> </div> <!--page logo header starts--> <div id="page-logo-header" class=""> <div id="page
Have you tried this in your view?:
#Html.Raw(ViewBag.Response)
By default the string will be HTML encoded to prevent script injection.
I looked at the network tab on Chrome and found that my breeze api for metadata is not getting called and thus all my methods of createEntity etc are failing.
[HttpGet]
public string Metadata()
{
return _context.Metadata();
}
I have followed the todo example and have enabled CORS Support and just about everything, I can see the json metadata if i navigate to /api/breeze/metadata
I am using VS2012 Web Express and gotten all the packages thru nuget
dataservice.js
app.dataservice = (function (breeze) {
var serviceName = 'api/breeze'; // route to the same origin Web Api controller
var manager = new breeze.EntityManager(serviceName);
return {
createTodo: createTodo,
saveChanges: saveChanges
};
function createTodo(initialValues) {
return manager.createEntity('BreezeItem', initialValues);
}
function saveChanges() {
return manager.saveChanges()
.then(function () { alert('good') })
.fail(function () { alert('bad') })
}
})(breeze);
index.html
`
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1"/>
<title>Breeze Todos with KO</title>
</head>
<body>
<div id="applicationHost">
<header>
<h1>Breeze Todos</h1>
<h2>with Knockout</h2>
<form data-bind="submit: addItem">
<input type="text" data-bind="value: newBreeze, valueUpdate: 'afterkeydown'" placeholder="What needs to be done?">
</form>
</header>
</div>
<!-- 3rd party libraries -->
<script src="Scripts/jquery-1.8.3.js"></script>
<script src="Scripts/knockout-2.2.1.debug.js"></script>
<script src="Scripts/q.js"></script>
<script src="Scripts/breeze.debug.js"></script>
<script src="Scripts/breeze.savequeuing.js"></script>
<!-- App libraries -->
<script>app = {};</script>
<script src="app/dataservice.js"></script>
<script src="app/viewModel.js"></script>
</body>
</html>
viewmodel.js
app.viewModel = (function ( dataservice) {
var vm = {
newBreeze: ko.observable(""),
addItem: addItem
};
return vm; // done with setup; return module variable
//#region private functions
function addItem() {
var item = dataservice.createTodo(
{
BreezeName: vm.newBreeze()
}
);
dataservice.saveChanges().fail(addFailed);
vm.newTodo("");
function addFailed() {
console.log("Failed")
}
}
function extendItem(item) {
if (item.isEditing) return; // already extended
item.isEditing = ko.observable(false);
}
})(app.dataservice);
// Bind viewModel to view in index.html
ko.applyBindings(app.viewModel);
Breeze makes the metadata call under two conditions, either implicitly as part of the first query in an application or explicity via the EntityManager.fetchMetadata method. This means that if you are not performing a query as your first action, then you will need to make a 'fetchMetadata' call instead. Remember that this is an async call that returns a 'promise', just like a query, so you will need to perform any calls to your "createEntity" methods when the promise resolves (i.e. within the 'then' call.
<script src="../../Scripts/MicrosoftAjax.debug.js" type="text/javascript"></script>
<script type="text/javascript">
function loginOK()
{
var item = document.getElementById('statusLabel');
item.innerHTML = "OK";
document.getElementById('LoadImg').style.visibility = 'hidden';
}
function process()
{
var lab = document.getElementById('statusLabel');
lab.innerHTML = 'Checking...';
lab.style.color = 'Black';
document.getElementById('LoadImg').style.visibility = 'visible';
}
function fail()
{
var lab = document.getElementById('statusLabel');
lab.innerHTML = 'Login is being used';
lab.style.color = 'Red';
document.getElementById('LoadImg').style.visibility = 'hidden';
}
</script>
<div style="width:30%; float:left;">
<label for="Login">Login:</label>
<%= Html.TextBoxFor(model=>model.Login) %>
<%= Html.ValidationMessageFor(model=>model.Login) %>
<img id="LoadImg" alt="" src="../../Content/Images/ajax-loader.gif" style="visibility:hidden;"/>
<br />
<label id="statusLabel" />
<br />
<%=Ajax.ActionLink("CheckLogin","CheckLoginAvailability", "Account",
new AjaxOptions { UpdateTargetId = "statusLabel", OnBegin = "process", OnFailure = "fail", OnSuccess="loginOK"})%>
</div>
and, in the AccountController:
[AcceptVerbs(HttpVerbs.Post)]
public void CheckLoginAvailability(string login)
{
//do some job
}
And, FireBug says that /Account/CheckLoginAvailability is not found. Also, after callback that ActionLink is hidden. Why ?
You are talking about Ajax.BeginForm in your question but this is nowhere to be seen in the markup you provided. There are a couple of issues that I can see with your code:
Your action method doesn't return an ActionResult. Yeah I know, you will say that this is possible, right, but that's against any good practices, conventions and rendering your controllers unit-test friendly.
You are using Microsoft Ajax which will mix markup and javascript which IMHO is bad for multiple reasons: increasing bandwidth which of course leads to decreased performance, incapacity to externalize javascript into separate files in order to cache them by client browsers, having to write things like document.getElementById, innerHTML, style.color, style.visibility, etc... which is not guaranteed to work cross browser.
Here's what I would suggest you to improve this. While this doesn't answer your question, take it as an alternative approach.
As always the first thing to deal with is to define a model which in your case might look something like this:
public class LoginViewModel
{
public string Login { get; set; }
}
Of course you might wish to add other fields such as Password, but this is out of scope for the moment. The next step is to write a controller dealing with this model (in parallel you should be already setting a unit-test for the future controller to prepare the ground):
public class HomeController : Controller
{
public ActionResult Index()
{
// Simply return the Login form
return View(new LoginViewModel());
}
[HttpPost]
public ActionResult Index(LoginViewModel model)
{
// Deal with the actual authentication, etc...
throw new NotImplementedException();
}
[HttpPost]
public ActionResult CheckLoginAvailability(LoginViewModel model)
{
// TODO: query your datasource to determine whether
// model.Login is taken
// For this purpose we will suppose that it is taken
bool isLoginTaken = true;
// return a JSON object containing the result
return Json(new { IsLoginTaken = isLoginTaken });
}
}
The last part is to paint the screen:
<%# Page Language="C#" Inherits="System.Web.Mvc.ViewPage<SomeNs.Models.LoginViewModel>" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Login</title>
<!-- Use a separate CSS to avoid mixing markup with styling -->
<link rel="stylesheet" type="text/css" href="<%: Url.Content("~/content/site.css") %>" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
<!-- Always use HTML helpers when dealing with Urls -->
<script type="text/javascript" src="<%: Url.Content("~/scripts/login.js") %>"></script>
</head>
<body>
<% using (Html.BeginForm()) { %>
<%: Html.LabelFor(x => x.Login) %>:
<%: Html.TextBoxFor(x => x.Login) %>
<%: Html.ValidationMessageFor(x => x.Login) %>
<br/>
<!-- Always use HTML helpers when dealing with Urls -->
<img id="loadImg" alt="" src="<%: Url.Content("~/content/images/ajax-loader.gif") %>" style="display:none;" />
<br />
<div id="statusLabel"></div>
<br />
<!-- Give this link an id so that we can easily identify it from javascript -->
<%: Html.ActionLink("CheckLogin", "CheckLoginAvailability", "Home", null, new { id = "checkLogin" })%>
<input type="submit" value="Login" />
<% } %>
</body>
</html>
And the last part is to unobtrusively attach our javascript (using jQuery of course) in the login.js file:
// When the DOM is ready
$(function () {
// Attach a click handler to the checkLogin link
$('a#checkLogin').click(function () {
// When this link is clicked send an AJAX POST request
// to the address this link is pointing to
$.ajax({
type: 'POST',
url: this.href,
// Pass as parameter in the POST body the login
// entered by the user
data: { login: $('#Login').val() },
beforeSend: function () {
// show the spinner image before sending any AJAX request
// to inform the user of an ongoing activity
$('#loadImg').show();
},
complete: function () {
// hide the spinner image when the AJAX request completes
// no matter if it succeeded or not
$('#loadImg').hide();
},
success: function (result) {
// if the AJAX request succeeds
// query the IsLoginTaken property
// of the resulting JSON object
if (result.IsLoginTaken) {
// Show the status label with red if the login is taken
$('#statusLabel').html('Login is being used').css('color', 'red');
} else {
// Show the status label in black if the login is not taken
$('#statusLabel').html('OK').css('color', 'black');
}
}
});
return false;
});
});
As #SLaks says actions can return void but, I think the action signature is such that it is required to return an action result and you can return EmptyResult if you don't want to return anything.
see this http://www.asp.net/mvc/tutorials/asp-net-mvc-controller-overview-cs
try changing your AccountController to
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult CheckLoginAvailability(string login)
{
//do some job
return new EmptyResult();
}