AngularJS Controller not defined - c#

So I've been browsing other threads, however none of the fixes I've found have solved my issue. I hope some of the more experienced coders here will be kind enough to help me out, mods I'm sorry if it turns out I'm being stupid here.
So I've built an app in Angular for an asp.net web app, the angular module should be displaying data from an entity model and displaying it inside a div.
Right now the code is not working, and I have no errors. From what I've seen I suspect its the Booking-controller however I cannot fathom what's wrong.
Here's my code
_Layout.cshtml
` <!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>#ViewBag.Title - Web App</title>
#Styles.Render("~/Content/css")
#Styles.Render("~/Content/js")
#Scripts.Render("~/bundles/angular")
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/modernizr")
#Scripts.Render("~/bundles/bootstrap")
</head>
<body ng-app="BookingsApp">
//a bunch of navbar stuff and other content
#RenderSection("scripts", required: false)
</body>
</html>
`
HomeController.cs
`using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace WebApp.Controllers
{
public class HomeController : Controller
{
//More navigation stuff
public JsonResult GetAll()
{
List<Booking_form> Booking = new List<Booking_form>();
using (BookingEntities1 ed = new BookingEntities1())
{
Booking = ed.Booking_forms.ToList();
return new JsonResult { Data = Booking, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
}
}
}
}
Page where I expect booking to be displayed
#section scripts{
<script src="~/Content/Angular/BookingModule.js"></script>
<script src="~/Content/Angular/BookingController.js"></script>
<script src="~/Content/Angular/BookingService.js"></script>
<link href="~/Content/TableStyle.css" rel="stylesheet" />
}
<div ng-controller="BookingController">
<table>
<tr>
<th>Id</th>
<th>Class</th>
<th>Day</th>
</tr>
<tr></tr>
<tr ng-repeat="e in BookingList">
<td>{{e.BookingId}}</td>
<td>{{e.ClassName}}</td>
<td>
{{e.Day}}
</td>
</tr>
</table>
</div>
Angular Module
var app = angular.module('BookingsApp',[]);
Angular Service
app.service('BookingService', function ($http) {
this.getBookings=function () {
return $http.get('/HomeController/GetAll');
}
});
Angular Controller
`app.controller('BookingController',function($scope,BookingService) {
function getBookingList() {
BookingService.getBookings().then(function (emp) {
$scope.BookingList = emp.data;
}, function (error) {
alert('Failed to fetch data');
});
}
});
`
I'd prefer to have a div on the page displaying the info with the ng-app="BookingApp" line, however this caused the BookingController reference to cause errors.
Any help would be greatly appreciated.
Edit:
Having looked again through browser console this message appears for all 3 angular scripts:
`Resource interpreted as Stylesheet but transferred with MIME type application/javascript: "http://localhost:49532/Content/Angular/BookingModule.js".
Solved, had to do a complete rebuild and make use of the service factory. For anyone else encountering this issue, see the provided link for a tutorial.
http://www.infragistics.com/community/blogs/dhananjay_kumar/archive/2015/05/13/how-to-use-angularjs-in-asp-net-mvc-and-entity-framework-4.aspx
note this solution will not work if solution uses multiple tables with foreign key dependencies.

Related

Extremely Long TTFB on ASP.net running on IIS

I am currently building a website of the creation of custom computers however I have the problem that my TTFB is very slow when running on my home IIS server. I have multiple websites running on this server and this is the only one with a 20-30s TTFB.
I have used webpagetest.org to test my website and am getting this water fall image.
However I then tester my website on debug using VS and chrome's own Dev Tools and my water fall here give me 1 second. I was wondering how to diagnose and test for the issues either on the server or in my page that may be causing this.
Here is a snippet of my home page code for anyone wondering-
Controller:
namespace ComputerSite.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
Layout (The only part of the page without static content):
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>#ViewBag.Title - Computers for you!</title>
#Styles.Render("~/Content/boot")
#Scripts.Render("~/bundles/modernizr")
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/jqueryval")
#Scripts.Render("~/bundles/ajaxgroup")
#Scripts.Render("~/bundles/bootstrap")
#Scripts.Render("~/bundles/datatables")
#Scripts.Render("~/bundles/tawk")
#if (Request.IsAuthenticated)
{
string text = UserHelper.GetUserEmail(User.Identity.Name), key = "MY APIKEY";
System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
Byte[] textBytes = encoding.GetBytes(text);
Byte[] keyBytes = encoding.GetBytes(key);
Byte[] hashBytes;
using (System.Security.Cryptography.HMACSHA256 hash = new System.Security.Cryptography.HMACSHA256(keyBytes)) { hashBytes = hash.ComputeHash(textBytes); }
string hashTxt = BitConverter.ToString(hashBytes).Replace("-", "").ToLower();
<script type="text/javascript">
Tawk_API.onLoad = function(){
Tawk_API.setAttributes({
'name' : '#User.Identity.Name',
'email': '#UserHelper.GetUserEmail(User.Identity.Name)',
'hash': '#hashTxt'
}, function (error) {});
};
</script>
}
#RenderSection("scripts", required: false)
</head>
<body>
#{ Html.RenderPartial("_navBar"); }
<div class="container body-content">
#RenderBody()
<hr />
<footer>
<p>© #DateTime.Now.Year - Building computer for you by you!</p>
</footer>
</div>
</body>
</html>
As requested I created a brand new ASP.net website and debugged it, from this I got a waterfall with a load time of 270 ms and TTFB of 12ms

ASP.NET-MVC not rendering View

I've a menu list displayed in the browser as a list of anchor tags. When a user clicks I'm passing its id to controller using ajax as following:
<!DOCTYPE html>
<script type="text/javascript">
$(document).on('click', 'a', function () {
var Url = $(this).attr("href");
$.ajax({
type: 'POST',
url:Url,
contentType: 'application/json; charset:utf-8',
data: JSON.stringify({ id: this.id })
})
});
</script>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<link href="/Content/bootstrap.css" rel="stylesheet">
<title>ShopOnline</title>
</head>
<body>
<div id="soContainer">
<div id="soCategories">
<div class="container">
<ul class="list-inline">
<li>
Everything
<ul id="catUL">
#foreach (var c in Model.CategoriesWithCount)
{
<li>
<a id="#c.Key" href ="#Url.Action("ListOfBrandNames","Home")">#c.Key</a>
(#c.Value)
</li>
}
</ul>
</li>
</ul>
<ul class="list-inline" id="topMenu">
<li>Bought Before</li>
<li>Specials</li>
</ul>
</div>
</div>
</div>
</body>
</html>
Now this id is passed down to the following action method as parameter to get a list of string(i.e., brand names) to send to a View as:
[HttpPost]
public ActionResult ListOfBrandNames(string id)
{
var result = db.Items.Where(x => x.Category.Name.Equals(id)).Select(x => x.BrandID).ToList();
var ListOfBrands = db.Brands.Where(t => result.Contains(t.BrandID)).ToList();
var brandNanes = ListOfBrands.Select(f => f.Name.ToString()).ToList();
return View(brandNanes);
}
Above code successfully passes desired list of string to following View as:
#model List<string>
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>ListOfBrandNames</title>
</head>
<body>
<table>
<tr>
#foreach (var i in Model)
{
<td>
#i.ToString();
</td>
}
</tr>
</table>
</body>
</html>
for loop in View successfully runs for all elements in the list but program is breaking with a 404 Error in the browser when the list ends in the for loop. Am I calling the View incorrectly or something?
You're making two separate requests when you click on a link. First is your AJAX request, which is succeeding. But, since you're clicking on a link, you're also making a standard GET request when your browser tries to follow that link. This second request is failing, because GET is not allowed on that controller action.
You could cancel the default request in your JavaScript code:
$(document).on('click', 'a', function (e) {
e.preventDefault();
// the rest of your code...
});
Or you could maintain your current pattern of using # in your links and store the URL in something other than href. Something like:
<a id="#c.Key" href="#" data-href="#Url.Action("ListOfBrandNames","Home")">#c.Key</a>
and in your JavaScript:
var Url = $(this).data("href");
Or perhaps replace the link entirely with a button (which would be more semantically correct I suspect):
<button type="button" id="#c.Key" data-href="#Url.Action("ListOfBrandNames","Home")">#c.Key</button>
That way it wouldn't have a default action (be aware of any <form> tags involved as well of course) but would just be used to invoke a client-side operation, which is what you're doing in the code anyway.
Either way is up to you, but the main point is that you need to prevent the browser from making the GET request to your POST-only action.
it looks like you are using an a tag to do what you should be doing with a button tag.
you can just use a button tag instead of an a tag, you may have to use some css to make it look like an a tag
2.you dont have to put the URL in the href property of the a tag if you dont actually want to you use it like a regular a tag.
for example you can place it in the data-href attribute
<a id="#c.Key" data-href ="#Url.Action("ListOfBrandNames","Home")">#c.Key</a>
...
var Url = $(this).attr("data-href");
this will prevent the a tag from trying to navigate to that url when you click on it.
note that this may course the cursor icon to change, you can fix that by setting href="#" or style="cursor:pointer"

Error loading hubs. Ensure your hubs reference is correct, e.g. <script src='/signalr/js'></script>

There are two pages: Login.aspx and Profile.aspx, which are built using HTML and AngularJS.
The login.aspx page uses ng-view to get the template of Login-view or Signup View.
The code used is:
<head>
<title></title>
<base href="/Login.aspx" />
<link href="StyleSheet/Login_css.css" rel="stylesheet" />
<script src="JscriptVendors/angular.min.js"></script>
</head>
<body ng-app="JouralApp_login">
<div ng-view></div>
<script src="Jscript_Angular/Model.js"></script>
<script src="Jscript_Angular/Controllers/LoginPageController.js"></script>
<script src="JscriptVendors/angular-route.min.js"></script>
<script src="JscriptVendors/angular-animate.min.js"></script>
<script src="JscriptVendors/jquery.min.js"></script>
</body>
The views are stored in Template folder with the names as: loginTemplate.html, and signupTemplate.html.
The module used for handling the login.aspx page is:
var app_login = angular.module('JouralApp_login', ['ngRoute','ngAnimate']);
var app_profile = angular.module('GameApp', []);
app_login.config(['$routeProvider', '$locationProvider', function ($routeProvider, $locationProvider) {
$locationProvider.html5Mode(true);
$routeProvider
.when('/login', {
templateUrl: 'Jscript_Angular/Templates/loginTemplate.html',
controller: 'loginController'
})
.when('/signup', {
templateUrl: 'Jscript_Angular/Templates/signupTemplate.html'
}).otherwise({
redirectTo:'/login'
})
}]);
Now a created my Profile.aspx, with the HTML code as:
<head>
<script src="Scripts/angular.js"></script>
</head>
<body ng-app="app_profile">
<div ng-controller="chatController">
<div>
<div ng-repeat="chat in messages">{{chat}}</div>
<div>
<input type="text ng-model="message" />
<input type="button" ng-click="newMessage()" />
</div>
</div>
</div>
<script src="Jscript_Angular/Model.js"></script>
<script src="Scripts/jquery-1.6.4.js"></script>
<script src="Scripts/jquery.signalR-2.2.0.js"></script>
<script src="signalr/hub"></script>
<script src="Jscript_Angular/Controllers/ChatController.js"></script>
</body>
Every thing was working fine until I try to integrate SignalR into my project.
I made two classes:
CLASS 1:
[assembly: OwinStartup(typeof(Startup))]
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.MapSignalR();
}
}
CLASS 2:
public class ChatHub : Hub
{
public void SendMessage(string name, string message)
{
Clients.All.broadcastMessage(name, message);
}
}
I also made the following controller in order to access my javascript function:
app_profile.controller('chatController',['$scope', function ($scope) {
$scope.name = 'Guest';
$scope.message = '';
$scope.messages = [];
$scope.chatHub = null;
$scope.chatHub = $.connection.chatHub;
$.connection.hub.start();
$scope.chatHub.client.broadcastMessage = function (name, message) {
var newMessage = name + " " + message;
$scope.messages.push(newMessage);
$scope.$apply();
};
$scope.newMessage = function () {
$scope.chatHub.server.sendMessage($scope.name, $scope.message);
$scope.message = '';
}
}]);
Now when I try to access my profile page, it show the error
angular.js:13550 Error: SignalR: Error loading hubs. Ensure your hubs reference is correct, e.g. .
Also when i try to access, localhost:5136/signalr/hubs, it redirects me to my login page, i.e: localhost:5136/login
I think the problem is that, it cannot access the hub which I created because of the routing which i did using angularJS for the login page.
Please help me find the solution.

From as partial view in layout page. MVC 5

I have a Partial View in my Layout page which contain a Form. The partial view open as popup. After submitting form I have to return back to the current page with opened popup and a success message should appear there but I am not able to return back to the right view.
My Layout Page
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>#ViewBag.Title || Midas WebSite</title>
#Styles.Render("~/Content/css")
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/jqueryui")
#Scripts.Render("~/bundles/site")
#Scripts.Render("~/bundles/modernizr")
<script type="text/javascript" language="javascript">
/* Superior Web Systems */
function displayHideBox(boxNumber) {
if (document.getElementById("LightBox" + boxNumber).style.display == "none") {
$("#LightBox" + boxNumber).fadeIn();
$("#grayBG").fadeIn();
} else {
$("#LightBox" + boxNumber).fadeOut();
$("#grayBG").fadeOut();
}
}
</script>
</head>
<body>
<div id="grayBG" class="grayBox" style="display:none;"></div>
<div id="LightBox1" class="box_content" style="display:none;">
<div onclick="displayHideBox('1'); return false;" class="close">X</div>
#Html.Action("ActionToBindPartialView", "ControllerName")
</div>
#RenderBody()
#RenderSection("scripts", required: false)
#Scripts.Render("~/bundles/jqueryval")
My Partial View
<div id="divActions">
// My Form Here
#Ajax.ActionLink("Submit", "ActionName", "ControllerName", new AjaxOptions
{
HttpMethod = "POST",
UpdateTargetId = "divActions",
OnSuccess = "onSucess()"
})
</div>
Now my action code which I have tried so far:
1.
// My Code
return PartialView("MyPartialView");
2
// My Code
return PartialView("MyPartialView", MyModel);
3
// My Code
return View();
4
// My Code
return ParialView();
I am a beginner and not able to find what I am doing wrong. Please suggest what should I do to make this work.
It is hard to say what you are doing wrong, due to the limited workspace that we have to discuss the problem. However here is a working example that may help you, please follow each step:
Bundles
bundles.Add(new ScriptBundle("~/bundles/jquery")
.Include("~/Scripts/jquery-{version}.js"));
bundles.Add(new ScriptBundle("~/bundles/jqueryval")
.Include(
"~/Scripts/jquery.unobtrusive*",
"~/Scripts/jquery.validate*"));
HomeController
public ActionResult Index()
{
return View();
}
public PartialViewResult GetPartial()
{
return PartialView("_MyPartial");
}
Index.cshtml
<h2>Index</h2>
<div id="divActions">
#Ajax.ActionLink("Submit", "GetPartial", "Home", new AjaxOptions
{
HttpMethod = "POST",
UpdateTargetId = "divActions",
OnSuccess="onSuccess()"
})
</div>
<script type="text/javascript">
function onSuccess()
{
alert("Success!");
}
</script>
_MyPartial.cshtml
<h2>_MyPartial</h2>
_Layout.cshtml
<!DOCTYPE html>
<html>
<head>
<title>#ViewBag.Title</title>
#Styles.Render("~/Content/css")
#Scripts.Render("~/bundles/modernizr")
</head>
<body>
#RenderBody()
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/jqueryval")
#RenderSection("scripts", required: false)
</body>
</html>
To confirm the rendered scripts in the page source (in the browser):
<script src="/Scripts/jquery-1.8.2.js"></script>
<script src="/Scripts/jquery.unobtrusive-ajax.js"></script>
<script src="/Scripts/jquery.validate.js"></script>
<script src="/Scripts/jquery.validate.unobtrusive.js"></script>
As you can see, there is nothing hard about it. You just need to follow the steps above.
I hope it helps.
Hint: check for other scripts errors, maybe your custom code to show the popup is causing a error. Double check if you are rendering javascript inside the partial view. Consider extract it to the regular view.

MVC Ajax form with unobstructive validation errors not going away

I am having an issue where form errors are persisting on the page even after the form is valid.
I have the following setup:
_Layout.cshtml:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>#ViewBag.Title</title>
<link href="#Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
<script src="#Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/modernizr-1.7.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/MicrosoftAjax.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/MicrosoftMvcAjax.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 src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>
</head>
<body>
#RenderBody()
</body>
</html>
index.cshtml:
#model SimpleForm.Models.Name
#{
ViewBag.Title = "Form";
}
<script>
$().ready(function () {
$("#quote_form").submit(function () {
return true;
});
});
</script>
#using (Ajax.BeginForm("RunQuote", "Page", new AjaxOptions { UpdateTargetId = "quoteSummary" }, new { id = "quote_form", onreset = "return confirm('Clear all form data?')" }))
{
<input type="submit" value="Send" />
<fieldset>
<legend>Name </legend>
<dl>
<dt>First</dt>
<dd>#Html.TextAreaFor(m => m.first, new { onblur = "$('#quote_form').submit();" })</dd>
<dt>Last</dt>
<dd>#Html.TextAreaFor(m => m.last, new { onblur = "$('#quote_form').submit();" })</dd>
</dl>
</fieldset>
<div class="qMatrixSubText">
#Html.ValidationSummary()
#{
Html.ValidateFor(m => m.first);
Html.ValidateFor(m => m.last);
}
</div>
<div id="quoteSummary" class="quoteSummary">
</div>
}
FormController.cs
using System;
using System.Web.Mvc;
using SimpleForm.Models;
namespace SimpleForm.Controllers
{
public class FormController : Controller
{
//
// GET: /Form/
public ActionResult Index()
{
return View();
}
public String RunQuote(Name quote)
{
return "Success!";
}
}
}
Name.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
namespace SimpleForm.Models
{
public class Name
{
[Required()]
public string first { get; set; }
public string last { get; set; }
}
}
The form populates fine, I see the error if I don't put anything into first and the form won't submit. After populating something into first I get the ajax call and then it posts "Success" to the div.
However, this is the problem, the error "the first field is required." still remains on the page. It's as if the ajax submit form is going through before the validation gets a chance to clear the error, and then it never gets the chance.
Any way to get the validation to still remove the errors?
The form is not being validated, because your onblur event is short-circuiting the submission process in jquery-unobtrusive-ajax.js.
Instead, change your onblur event for both fields to the following:
$(this).parents('form:first').find(':submit')[0].click();
This will invoke the jquery.unobtrusive-ajax.js script, causing validation to occur prior to the Ajax submission to the server.
UPDATE
When I looked back at your view, I saw that you are calling #Html.ValidateFor() for your properties. This creates HTML markup outside of the div created by #Html.ValidationSummary.
Because this markup is outside of where unobtrusive validation expects it, this markup is never overwritten, and will always remain. Remove the #Html.ValidateFor() lines. If you need to have the validation messages after your initial load, call validate() on document.ready to set your validation messages.
Because I haven't found a proper solution to this problem, I've decided to simply target the validation-summary-errors div and add the class display:none; to the li elements. This hides the validation errors that have otherwise not cleared before submitting the form.
$('#form_errors').children('div.validation-summary-errors').children('ul').children('li').css('display','none')
There has to be a better solution, but I've tried everything and can't figure out why my attempts to force validation don't work.

Categories

Resources