I am consuming Wcf Rest Service into Angular JS Application. I am trying to retrieve a single record based on string parameter Account_Number.when user enter account number into input filed i want to display single record in angular js application but its not displaying the data.I am facing two problems.
I write the url in local host with the method name .I got the result is Method not allowed .
when i clicked the submit button to retrieve that particular account details then i got following error in google chrome .
angular.js:12701 POST http://localhost:52098/HalifaxIISService.svc/GetAccountDetails16 404 (Not Found)
AccountBalance.js:22 failure loading Employee {data: "<?xml version="1.0" encoding="utf-8"?>
when i click this link it shows error in network tab(preview) that the End point not found and the header section .
Request URL:http://localhost:52098/HalifaxIISService.svc/GetAccountDetails16
Request Method:POST
Status Code:404 Not Found
Remote Address:[::1]:52098
Referrer Policy:no-referrer-when-downgrade
Here is my method interface.
[OperationContract]
[WebInvoke(Method = "POST",
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "/GetAccountDetails")]
bool GetAccountDetails(string Account_Number);
Here is the implementation .
public bool GetAccountDetails(string Account_Number)
{
List<object> customers = new List<object>();
string sql = "SELECT * FROM Current_Account_Holder_Details WHERE Account_Number = '"+ Account_Number;
using (SqlConnection conn = new SqlConnection())
{
conn.ConnectionString = ConfigurationManager.ConnectionStrings["DBCS"].ConnectionString;
using (SqlCommand cmd = new SqlCommand(sql))
{
cmd.Parameters.AddWithValue("#Account_Number", Account_Number);
cmd.Connection = conn;
conn.Open();
using (SqlDataReader sdr = cmd.ExecuteReader())
{
while (sdr.Read())
{
customers.Add(new
{
Tittle = sdr["Tittle"],
Account_Holder_First_Name = sdr["Account_Holder_First_Name"],
Account_Holder_Last_Name = sdr["Account_Holder_Last_Name"],
Account_Holder_DOB = sdr["Account_Holder_DOB"],
Account_Holder_House_No = sdr["Account_Holder_House_No"],
Account_Holder_Street_Name = sdr["Account_Holder_Street_Name"],
Account_Holder_Post_Code = sdr["Account_Holder_Post_Code"],
Account_Holder_Occupation = sdr["Account_Holder_Occupation"],
Account_Number = sdr["Account_Number"]
});
}
}
conn.Close();
}
return true;
}
}
here is the script code .
var app = angular.module("WebClientModule", [])
.controller('Web_Client_Controller', ["$scope", 'myService', function ($scope, myService) {
var Id = $scope.Account_Number;
$scope.search = function (Id) {
var promisePostSingle = myService.postbyId(Id);
promisePostSingle.then(function (pl) {
var res = pl.data;
$scope.Account_Number = res.Account_Number;
$scope.Account_Creation_Date = res.Account_Creation_Date;
$scope.Account_Type = res.Account_Type;
$scope.Branch_Sort_Code = res.Branch_Sort_Code;
$scope.Account_Fees = res.Account_Fees;
$scope.Account_Balance = res.Account_Balance;
$scope.Over_Draft_Limit = res.Over_Draft_Limit;
// $scope.IsNewRecord = 0;
},
function (errorPl) {
console.log('failure loading Employee', errorPl);
});
}
}]);
app.service("myService", function ($http) {
this.postbyId = function (Id) {
return $http.post("http://localhost:52098/HalifaxIISService.svc/GetAccountDetails" + Id);
};
})
Here is the HTML CODE .
#{
Layout = null;
}
<!DOCTYPE html>
<html ng-app="WebClientModule">
<head>
<meta name="viewport" content="width=device-width" />
<title>AccountBalance</title>
<script src="~/Scripts/angular.min.js"></script>
<script src="~/RegistrationScript/AccountBalance.js"></script>
</head>
<body>
<div data-ng-controller="Web_Client_Controller">
Enter Account_Number: <input type="text" ng-model="Id" />
<input type="button" value="search" ng-click="search(Id)" />
<table id="tblContainer">
<tr>
<td>
<table style="border: solid 2px Green; padding: 5px;">
<tr style="height: 30px; background-color: skyblue; color: maroon;">
<th></th>
<th>Account Number</th>
<th>Account Creation Date</th>
<th>Account Type</th>
<th>Branch Sort Code</th>
<th>Account Fees</th>
<th>Account Balance</th>
<th>Over Draft Limit</th>
<th></th>
<th></th>
</tr>
<tbody data-ng-repeat="user in Users">
<tr>
<td></td>
<td><span>{{user.Account_Number}}</span></td>
<td><span>{{user.Account_Creation_Date}}</span></td>
<td><span>{{user.Account_Type}}</span></td>
<td><span>{{user.Branch_Sort_Code}}</span></td>
<td><span>{{user.Account_Fees}}</span></td>
<td><span>{{user.Account_Balance}}</span></td>
<td><span>{{user.Over_Draft_Limit}}</span></td>
<td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<td></td>
</tr>
<tr>
<td>
<div style="color: red;">{{Message}}</div>
</td>
</tr>
</table>
</div>
</body>
</html>
<script src="~/RegistrationScript/AccountBalance.js"></script>
Here is the screen shot when i run the application .
Here is the screen shot on Network Tab.
In network Tab preview section
Related
I'm trying to retrieve whole table in mvc5 using angularJS.
Data in Json result is being displayed but not in the table as I wanted.
I'm using mvc5 and angularjs(1.x) to retrive the data from sql server
Here's the Data Access Layer code:
public List<Employee> ShowAllEmployee()
{
List<Employee> prdList = userdb.Employees.ToList();
return prdList;
}
Here's the HomeController method:
public JsonResult AllEmployee()
{
repo = new Employee_DAL.EmpRepo();
var hotList = repo.ShowAllEmployee();
List<Models.Employee> mList = new List<Models.Employee>();
foreach (var hotl in hotList)
{
Models.Employee hotLocal = new Models.Employee();
hotLocal.EmployeeId = hotl.EmployeeId;
hotLocal.FirstName = hotl.FirstName;
hotLocal.LastName = hotl.LastName;
hotLocal.Designation = hotl.Designation;
//hotLocal.Description = hotl.Description;
hotLocal.Country = hotl.Country;
hotLocal.Gender = hotl.Gender;
//hotLocal.Rating = hotl.Rating;
//hotLocal.Email = hotl.Email;
mList.Add(hotLocal);
}
return Json(mList, JsonRequestBehavior.AllowGet);
}
Here's the script ( angular) code:
var myApp = angular.module('MyModule', []);
myApp.controller('DBcontroller', function ($scope, $http) {
$http.get('/Home/AllEmployee') // added an '/' along with deleting Controller portion
.then(function (response) {
$scope.students = response.data
})
})
Here's my view(cshtml):
#{
Layout = null;
}
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/bootstrap")
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<script src="~/Customs/angular.min.js"></script>
<script src="~/Customs/Scripts.js"></script>
<title>AllEmployee</title>
</head>
<body ng-app="myApp">
<div ng-controller="DBcontroller">
<table class="table-bordered">
<tr>
<th>Emp No</th>
<th>First Name</th>
<th>Last Name</th>
<th>Designation</th>
<th>Country</th>
<th>Gender</th>
</tr>
<tr ng-repeat="e in students" #*ng-class-even="'even'" ng-class-odd="'odd'"*#>
<td>{{e.EmployeeId}}</td>
<td>{{e.FirstName}}</td>
<td>{{e.LastName}}</td>
<td>{{e.Designation}}</td>
<td>{{e.Country}}</td>
<td>{{e.Gender}}</td>
</tr>
</table>
</div>
</body>
</html>
I expect the jsonresult to be displayed in a table. Not directly like this in the browser.Screenshot of my current output
How do I initiate an ajax request (calling controller action) from razor view which returns the data in JSON format?
At the moment after clicking the action link in my razor view the page does the post request which redirects the page to /actionName which of course does not exist.
I am also using jQuery but not sure how do I fetch the data from razor view which needs to be passed if I use jQuery ajax method.
ShowEventLogs.cshtml
#{ ViewBag.Title = "Event Logs"; }
#model IEnumerable
<Application.Models.EventLogs>
<table id="data-table" class="table display responsive" style="width:100%">
<thead class="thead-colored thead-light">
<tr>
<th>Time</th>
<th>Scheme</th>
<th>Serial Number</th>
<th>Batch</th>
<th>Exp Date</th>
<th>Product Code</th>
<th>Http Code</th>
<th>Is Confirmed?</th>
<th>Confirmation Date</th>
<th>Verify Pack</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>#item.Timestamp</td>
<td>#item.ProductCodeScheme</td>
<td>#item.SerialNumber</td>
<td>#item.Batch</td>
<td>#item.ExpirationDate</td>
<td>#item.ProductCode</td>
<td>#item.HttpResponseCode</td>
<td>#item.ConfirmedParsed</td>
<td>#item.ConfirmedDate</td>
if (#item.HttpResponseCode == "202")
{
<td class="text-secondary">#Html.ActionLink("Verify Pack", "VerifyPack", "Home", new { ProductCodeScheme = #item.ProductCodeScheme, ProductCode = #item.ProductCode, SerialNumber = #item.SerialNumber, Batch = #item.Batch, ExpirationDate = #item.ExpirationDate, CommandStatusCode = 0 }, new { #class = "text-info" })</td>
}
else
{
<td class="text-secondary">Not Available</td>
}
</tr>
}
</tbody>
</table>
}
Controller action
[HttpPost]
public ActionResult VerifyPack(string productCodeScheme, string productCode, string serialNumber, string batch, string expirationDate, int commandStatusCode, string orderTrackingNo = null) {
string TextAreaResult = string.Empty;
string TextAreaResultException = string.Empty;
string TextAreaResultHttpOperationCode = string.Empty;
string TextAreaResultHttpResponseCode = string.Empty;
string TextAreaResultHttpInformation = string.Empty;
string TextAreaResultHttpWarning = string.Empty;
string TextAreaResultState = string.Empty;
string RemoteIpAddress = string.Format("{0}", Request.UserHostAddress);
try {
using(SecureMediDatabase database = new SecureMediDatabase(this)) {
DatabaseFactory.setDatabase(database);
Request baseRequest = (Request) database.createRequest(Country);
ServiceThread serviceThread = new ServiceThread(0, null, Country);
serviceThread.attach(this);
baseRequest.setId(0);
baseRequest.setProductCodeScheme(productCodeScheme);
baseRequest.setRequestType(1); //single pack
baseRequest.setProductCode(productCode);
baseRequest.setSerialNumber(serialNumber);
baseRequest.setBatch(batch);
baseRequest.setExpirationDate(expirationDate);
baseRequest.setWorkstation(RemoteIpAddress);
baseRequest.setManualEntry(string.IsNullOrEmpty(expirationDate) || string.IsNullOrEmpty(batch));
if (baseRequest.isManualEntry()) {
switch (commandStatusCode) {
case 2:
case 3:
break;
default:
throw new NotSupportedException("This operation does not support manual entries!");
}
}
switch (Country) {
case "SE":
SecureMediRequestSE requestSE = (SecureMediRequestSE) baseRequest;
requestSE.setUserId(#User.Identity.Name);
requestSE.setCommandStatusCode(commandStatusCode);
requestSE.OrderTrackingNumber = orderTrackingNo;
break;
case "FI":
SecureMediRequestFI requestFI = (SecureMediRequestFI) baseRequest;
requestFI.setSubUserId(#User.Identity.Name);
break;
}
serviceThread.RunRequest(control, baseRequest, apteekki);
TextAreaResult = string.Format("{0} {1} {2} {3} {4}", baseRequest.getResponseOperationCode(), baseRequest.getHttpResponseCode(), baseRequest.getHttpInformation(), baseRequest.getHttpWarning(), baseRequest.getResponseStatusCode());
TextAreaResultHttpOperationCode = string.Format("{0}", baseRequest.getResponseOperationCode());
TextAreaResultHttpResponseCode = string.Format("{0}", baseRequest.getHttpResponseCode());
TextAreaResultHttpInformation = string.Format("{0}", baseRequest.getHttpInformation());
TextAreaResultHttpWarning = string.Format("{0}", baseRequest.getHttpWarning());
TextAreaResultState = string.Format("{0}", baseRequest.getResponseStatusCode());
}
} catch (Exception exc) {
TextAreaResultException = "Exception: " + exc.Message;
}
return Json(new {
result = TextAreaResult,
httpOperationCode = TextAreaResultHttpOperationCode,
httpResponseCode = TextAreaResultHttpResponseCode,
httpInformation = TextAreaResultHttpInformation,
httpWarning = TextAreaResultHttpWarning,
state = TextAreaResultState,
exception = TextAreaResultException,
isSuccess = TextAreaResultHttpResponseCode == "200" || TextAreaResultHttpResponseCode == "202"
});
}
Error based on the answer:
Basically #Html.ActionLink() helper renders anchor tag (<a>) with attributes and defaulted to use GET request by refreshing whole page, hence you need to add preventDefault() in order to use AJAX callback from that element. If the action method uses HTTP GET method, you can perform simple AJAX call against common class of the anchor link like this:
$('.text-info').on('click', function (e) {
e.preventDefault();
var url = $(this).attr('href');
$.get(url, function (response) {
// do something with AJAX response
});
});
However since target controller action marked as [HttpPost], you need to extract query string parameters from href attribute with additional function and use them in the AJAX call with type: 'POST' setting, or use $.post():
$('.text-info').on('click', function (e) {
e.preventDefault(); // mandatory to prevent GET request
var url = $(this).attr('href');
var pcs = getQueryStringParams(url, 'ProductCodeScheme');
var pc = getQueryStringParams(url, 'ProductCode');
var sn = getQueryStringParams(url, 'SerialNumber');
var batch = getQueryStringParams(url, 'Batch');
var expDate = getQueryStringParams(url, 'ExpirationDate');
var csc = getQueryStringParams(url, 'CommandStatusCode');
// create key-value pair for action method parameters
var obj = { ProductCodeScheme: pcs, ProductCode: pc, SerialNumber: sn, ... }
$.ajax({
type: 'POST',
url: url.split('?')[0], // URL without query string, or use '#Url.Action("VerifyPack", "Home")'
data: obj,
dataType: 'json', // expects response as JSON
success: function (response) {
// do something with AJAX response
},
error: function (xhr, status, err) {
// error handling
}
});
// just make sure that the link is not redirecting
return false;
});
function getQueryStringParams(url, name) {
return (RegExp(name + '=' + '(.+?)(&|$)').exec(url)||[,null])[1];
}
Actually there exists another way to call AJAX from anchor tag like #Ajax.ActionLink(), depending on your choice:
#Ajax.ActionLink("Verify Pack", "VerifyPack", "Home", new { ProductCodeScheme = #item.ProductCodeScheme, ProductCode = #item.ProductCode, SerialNumber = #item.SerialNumber, Batch = #item.Batch, ExpirationDate = #item.ExpirationDate, CommandStatusCode = 0 },
new AjaxOptions { HttpMethod = "POST",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "targetElementId",
OnComplete = "onComplete();"
},
new { #class = "text-info" })
Note:
If you need to handle AJAX request and normal request from the same controller, you can differentiate them using Request.IsAjaxRequest() (or Context.Request.Headers["X-Requested-With"] == "XMLHttpRequest" in Core MVC).
Something like this should get you started. Add a class to the items you need to pull information from. Then instead of using an actionlink just create a normal a element with a unique class as well. Have JQuery handle click events on those links and pass the other TD items of the same row to the controller via an AJAX call.
$(".button").click( function() {
var tr = $(this).closest("tr");
var ProductCodeScheme = tr.find(".ProductCodeScheme").html();
var SerialNumber = tr.find(".SerialNumber").html();
var Batch = tr.find(".Batch").html();
var ExpirationDate = tr.find(".ExpirationDate").html();
var ProductCode = tr.find(".ProductCode").html();
$.ajax({
url: "/Verify Pack/VerifyPack",
type: "POST",
data: ({
ProductCodeScheme: ProductCodeScheme,
SerialNumber: SerialNumber,
Batch: Batch,
ExpirationDate: ExpirationDate,
ProductCode: ProductCode
}),
cache: false,
success: function(data){
//Do something here for a successful POST
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="data-table" class="table display responsive" style="width:100%">
<thead class="thead-colored thead-light">
<tr>
<th>Time</th>
<th>Scheme</th>
<th>Serial Number</th>
<th>Batch</th>
<th>Exp Date</th>
<th>Product Code</th>
<th>Http Code</th>
<th>Is Confirmed?</th>
<th>Confirmation Date</th>
<th>Verify Pack</th>
</tr>
</thead>
<tbody>
<tr>
<td>Timestamp 1</td>
<td class="ProductCodeScheme">ProductCodeScheme 1</td>
<td class="SerialNumber">SerialNumber 1</td>
<td class="Batch">Batch 1</td>
<td class="ExpirationDate">ExpirationDate 1</td>
<td class="ProductCode">ProductCode 1</td>
<td>HttpResponseCode 1</td>
<td>ConfirmedParsed 1</td>
<td>ConfirmedDate 1</td>
<td class="text-secondary">Item 1</td>
</tr>
<tr>
<td>Timestamp 2</td>
<td class="ProductCodeScheme">ProductCodeScheme 2</td>
<td class="SerialNumber">SerialNumber 2</td>
<td class="Batch">Batch 2</td>
<td class="ExpirationDate">ExpirationDate2</td>
<td class="ProductCode">ProductCode 2</td>
<td>HttpResponseCode 2</td>
<td>ConfirmedParsed 2</td>
<td>ConfirmedDate 2</td>
<td class="text-secondary">Item 2</td>
</tr>
</tbody>
</table>
I am consuming Wcf Rest Service into Angular JS Application . I am trying to display single record based on account number in input filed. But when i click the submit button to display the record then i got following errors in Google Chrome Network Tap.
The server encountered an error processing the request. The exception message is 'Conversion failed when converting the nvarchar value '{Account_Number}15' to data type int.'. See server logs for more details. The exception stack trace is:
And its returns 400 Bad Request on Post Method Operation .
Here is the interface .
[OperationContract]
[WebInvoke(Method = "POST",
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "/GetAccountDetails/{Account_Number}")]
string GetAccountDetails(string Account_Number);
Here is the Implementation.
public string GetAccountDetails(string Account_Number)
{
List<object> customers = new List<object>();
string sql = "SELECT * FROM Current_Account_Holder_Details WHERE Account_Number = #Account_Number";
using (SqlConnection conn = new SqlConnection())
{
conn.ConnectionString = ConfigurationManager.ConnectionStrings["DBCS"].ConnectionString;
using (SqlCommand cmd = new SqlCommand(sql))
{
cmd.Parameters.AddWithValue("#Account_Number", Account_Number);
cmd.Connection = conn;
conn.Open();
using (SqlDataReader sdr = cmd.ExecuteReader())
{
while (sdr.Read())
{
customers.Add(new
{
Tittle = sdr["Tittle"],
Account_Holder_First_Name = sdr["Account_Holder_First_Name"],
Account_Holder_Last_Name = sdr["Account_Holder_Last_Name"],
Account_Holder_DOB = sdr["Account_Holder_DOB"],
Account_Holder_House_No = sdr["Account_Holder_House_No"],
Account_Holder_Street_Name = sdr["Account_Holder_Street_Name"],
Account_Holder_Post_Code = sdr["Account_Holder_Post_Code"],
Account_Holder_Occupation = sdr["Account_Holder_Occupation"],
Account_Number = sdr["Account_Number"]
});
}
}
conn.Close();
}
return (new JavaScriptSerializer().Serialize(customers));
}
}
Here is the Script code.
var app = angular.module("WebClientModule", [])
.controller('Web_Client_Controller', ["$scope", 'myService', function ($scope, myService) {
var Account_Number = $scope.Account_Number;
$scope.search = function (Account_Number) {
var promisePostSingle = myService.postbyId(Account_Number);
promisePostSingle.then(function (pl) {
var res = pl.data;
$scope.Account_Number = res.Account_Number;
$scope.Account_Creation_Date = res.Account_Creation_Date;
$scope.Account_Type = res.Account_Type;
$scope.Branch_Sort_Code = res.Branch_Sort_Code;
$scope.Account_Fees = res.Account_Fees;
$scope.Account_Balance = res.Account_Balance;
$scope.Over_Draft_Limit = res.Over_Draft_Limit;
// $scope.IsNewRecord = 0;
},
function (errorPl) {
console.log('failure loading Employee', errorPl);
});
}
}]);
app.service("myService", function ($http) {
this.postbyId = function (Id) {
return $http.post("http://localhost:52098/HalifaxIISService.svc/GetAccountDetails/{Account_Number}" + Id);
};
})
Here is the HTML .
#{
Layout = null;
}
<!DOCTYPE html>
<html ng-app="WebClientModule">
<head>
<meta name="viewport" content="width=device-width" />
<title>AccountBalance</title>
<script src="~/Scripts/angular.min.js"></script>
<script src="~/RegistrationScript/AccountBalance.js"></script>
</head>
<body>
<div data-ng-controller="Web_Client_Controller">
Enter Account_Number: <input type="text" ng-model="Account_Number" />
<input type="button" value="search" ng-click="search(Account_Number)" />
<table id="tblContainer">
<tr>
<td>
<table style="border: solid 2px Green; padding: 5px;">
<tr style="height: 30px; background-color: skyblue; color: maroon;">
<th></th>
<th>Account Number</th>
<th>Account Creation Date</th>
<th>Account Type</th>
<th>Branch Sort Code</th>
<th>Account Fees</th>
<th>Account Balance</th>
<th>Over Draft Limit</th>
<th></th>
<th></th>
</tr>
<tbody data-ng-repeat="user in Users">
<tr>
<td></td>
<td><span>{{user.Account_Number}}</span></td>
<td><span>{{user.Account_Creation_Date}}</span></td>
<td><span>{{user.Account_Type}}</span></td>
<td><span>{{user.Branch_Sort_Code}}</span></td>
<td><span>{{user.Account_Fees}}</span></td>
<td><span>{{user.Account_Balance}}</span></td>
<td><span>{{user.Over_Draft_Limit}}</span></td>
<td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<td></td>
</tr>
<tr>
<td>
<div style="color: red;">{{Message}}</div>
</td>
</tr>
</table>
</div>
</body>
</html>
Here is the Screen Shot on Debugging mode on Wcf Service .
Here is the result on Google Chrome Console Windows .
You should change it;
$http.post("http://localhost:52098/HalifaxIISService.svc/GetAccountDetails/{Account_Number}" + Id);
to
$http.post("http://localhost:52098/HalifaxIISService.svc/GetAccountDetails?Account_Number=" + Id);
You are sending the parameter as {Account_Number}15. It should be 15.
I'm new to web development and right now I'm working on a website. I have a problem with a Save button on an ASP.Net (front end) web form (back end is in C#). The button is supposed to save data entered in a textbox to a database.
When the Save button is clicked the first time, the page just 'reloads' and clear the textbox and nothing is saved in the SQL Server database (dbo connection). Then when I click the same 'Save' button a second time after re-entering information in the textbox, it actually saves to the database and goes back to a main menu page (as expected). And if I try to re-enter different information, the save button will be working just fine.
The problem happens when a user logs in and navigate to the page where he enters the data and saves it. It will never ever work the first time.
Unfortunately because of confidential purposes, I have to omit and rename certain file paths/directories and tables name!
Here's my Asp.NET code:
<%# Page Language="C#" debug="True" Inherits="Default" src="Default.cs" AutoEventWireup ="true"%>
<%# Register TagPrefix="ob" TagName="ComboTree" Src="/obout/Combotree/ComboTree.ascx" %>
<%# Reference Control="/obout/Combotree/ComboTree.ascx" %>
<HTML>
<HEAD>
<!-- #INCLUDE VIRTUAL="/.../" -->
</HEAD>
<BODY >
<FORM runat="server">
<BASEFONT face="Arial, Helvetica, Sans Serif" color=black size=2>
<TABLE height="100%" cellSpacing=0 cellPadding=0 width="780" align=Center border=0>
<!-- #INCLUDE VIRTUAL="/.../" -->
<TR VALIGN="top">
<!-- #INCLUDE VIRTUAL="/.../" -->
`enter code here`<TD vAlign=top width="100%" HEIGHT="100%">
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0 HEIGHT="100%">
<!-- #INCLUDE VIRTUAL="/.../" -->
<TR>
<!-- #INCLUDE VIRTUAL="/.../" -->
<TD vAlign=top align=left >
<!--- START YOUR CODE HERE!!!!! --->
<script>
function disableListItems(checkBoxListId, disable)
{
// Get the checkboxlist object.
ctr = 0;
while(1 == 1)
{
checkbox = document.getElementById(checkBoxListId + "_" + ctr);
if(checkbox == null)
{
return;
}
checkbox.checked = true;
checkbox.disabled = disable;
ctr++;
}
}
function checkForm()
{
var errMsg = "";
if(isBlank(document.getElementById("tbName").value))
{
errMsg += "\n-Folder Name";
}
if(errMsg!="")
{
alert("The following fields cannot be left blank." + errMsg);
return false;
}
return true;
}
</script>
<font Class="heading">File Library - <ASP:Label ID="lbTitle" RunAt="Server"/> Folder</font>
<INPUT Type="Hidden" ID="hdFolderID" RunAt="Server"/>
<INPUT Type="Hidden" ID="hdParentFolderID" RunAt="Server"/>
<TABLE CellPadding="4" CellSpacing="0" Width="100%" >
<TR>
<TD ColSpan="2" Class="spreadsheet_line"> </TD>
</TR>
<TR>
<TD Class="Spreadsheet"><B>Name</B></TD>
<TD Class="Spreadsheet" Width="100%"><ASP:TextBox ID="tbName" Columns="34" RunAt="Server"/></TD>
</TR>
<TR VAlign="Top" Visible="False" RunAt="Server">
<TD Class="Spreadsheet" NOWRAP><B>Description</B></TD>
<TD Class="Spreadsheet"><ASP:TextBox ID="tbDescription" TextMode="Multiline" Cols="25" Rows="5" RunAt="Server"/></TD>
</TR>
<TR>
<TD Class="Spreadsheet"><B>Active?</B></TD>
<TD Class="Spreadsheet"><ASP:CheckBox ID="cbActive" RunAt="Server"/></TD>
</TR>
<TR Visible="False" RunAt="Server">
<TD Class="Spreadsheet"><B>Folder</B></TD>
<TD Class="Spreadsheet"><ob:ComboTree id="ctFolders" runat="server"/></TD>
</TR>
<TR VAlign="Top" ID="trLicensees" RunAt="Server">
<TD Class="Spreadsheet"><B>Departments</B></TD>
<TD Class="Spreadsheet">
<ASP:DropDownList ID="ddLicensee" DataTextField="Name" DataValueField="DepartmentId" RunAt="Server"/>
<ASP:CheckBox ID="cbAll" Text="All" RunAt="Server"/>
<div style="text-align: left; width: 30%; margin-left:-3px">
<ASP:CheckBoxList ID="cblLicensees" DataTextField="Name" DataValueField="DepartmentId" style="background-color:F3F3F3" RunAt="Server"/> <!--**-->
</div>
</TD>
</TR>
<TR>
<TD Class="Spreadsheet" Align="Right" ColSpan="2">
<ASP:ImageButton ID="btnSave" OnClick="btnSave_OnClick" ImageUrl="/images/buttons/btnSave.gif" RunAt="Server"/>
</TD>
</TR>
</TABLE>
<!--- END YOUR CODE HERE!!!!! --->
</TD>
<!-- #INCLUDE VIRTUAL="/.../" -->
</TR>
<!-- #INCLUDE VIRTUAL="/.../" -->
</TABLE>
</TD>
<!-- #INCLUDE VIRTUAL="/.../" -->
</TR>
<!-- #INCLUDE VIRTUAL="/.../" -->
</TABLE>
</BASEFONT>
</FORM>
</BODY>
</HTML>
And here's the (back end) code for the Save button written in C#:
public void btnSave_OnClick(object sender, System.Web.UI.ImageClickEventArgs E){
int counter = int.Parse(Request.Cookies["counter"].Value);
counter++;
Response.Cookies["counter"].Value = counter.ToString();
try{
SqlConnection Conn = GetConnection();
string SQL;
SqlCommand Cmd;
SqlDataReader Dtr;
if(hdFileID.Value=="")
{
Response.Write("Executing Save (adding new folder to DB");
SQL = "EXEC sp_File_Add #Name,#Description,#UserID";
Response.Write("Save successfully executed. Added to DB");
}
else
{
Response.Write("Executing Save (saving info of folder to DB");
SQL = "EXEC sp_File_Update #Name,#Description,#UserID,#FileID";
Response.Write("Save successfully executed. Saved to DB");
}
Cmd = new SqlCommand(SQL,Conn);
Cmd.Parameters.Add(new SqlParameter("#Name", SqlDbType.VarChar));
Cmd.Parameters["#Name"].Value = tbName.Text;
Cmd.Parameters.Add(new SqlParameter("#Description", SqlDbType.Text));
Cmd.Parameters["#Description"].Value = tbDescription.Text;
Cmd.Parameters.Add(new SqlParameter("#UserID", SqlDbType.Int));
Cmd.Parameters["#UserID"].Value = Convert.ToInt32(hdUserID_Global.Value);
if(hdFileID.Value!="")
{
Cmd.Parameters.Add(new SqlParameter("#FileID", SqlDbType.Int));
Cmd.Parameters["#FileID"].Value = Convert.ToInt32(hdFolderID.Value);
}
Cmd.ExecuteNonQuery();
if(hdFileID.Value=="")
{
SQL = "SELECT MAX(FileID) AS FileID FROM tbl_File WHERE CreatedByUserID=#UserID";
Cmd = new SqlCommand(SQL,Conn);
Cmd.Parameters.Add(new SqlParameter("#UserID", SqlDbType.Int));
Cmd.Parameters["#UserID"].Value = Convert.ToInt32(hdUserID_Global.Value);
Dtr = Cmd.ExecuteReader();
if(Dtr.Read())
{
hdFileID.Value = Dtr["FileID"].ToString();
}
Dtr.Close();
}
SQL = "DELETE FROM tbl_FileLicense ";
SQL += " WHERE FileID=#FileID ";
Cmd = new SqlCommand(SQL,Conn);
Cmd.Parameters.Add(new SqlParameter("#FileID", SqlDbType.Int));
Cmd.Parameters["#FileID"].Value = Convert.ToInt32(hdFileID.Value.ToString());
Cmd.ExecuteNonQuery();
if(ddLicense.Visible)
{
SQL = "EXEC sp_doc_Folder_Add #FileID,#LicenseID,#UserID";
Response.Write("Save successfully executed. Added to DB");
Cmd = new SqlCommand(SQL,Conn);
Cmd.Parameters.Add(new SqlParameter("#FolderID", SqlDbType.Int));
Cmd.Parameters["#FileID"].Value = Convert.ToInt32(hdFileID.Value.ToString());
Cmd.Parameters.Add(new SqlParameter("#LicenseID", SqlDbType.Int));
Cmd.Parameters["#LicenseID"].Value = Convert.ToInt32(ddLicense.SelectedItem.Value.ToString());
Cmd.Parameters.Add(new SqlParameter("#UserID", SqlDbType.Int));
Cmd.Parameters["#UserID"].Value = Convert.ToInt32(hdUserID_Global.Value);
Cmd.ExecuteNonQuery();
}
else
{
}
Conn.Close();
Response.Redirect("/Library/Default2.aspx?FileID=" + Request["RootFileID"].ToString());
Response.End();
}
catch (Exception e){
Response.Write("An error occurred while saving: " + e);
Response.End();
}
}
I've been struggling for more than 2 days on that and I don't see why the button is not firing the first time but only as from the 2nd time. Any help will be greatly appreciated. Thank you.
You should open connection i.e Conn.open() before executing cmd.ExecuteNonQuery() method.
Try this, if it still doesn't work, in first line of webform.aspx i.e. <%# Page Language="C#" add this attribute and see if it works: EnableEventValidation="false". Also check the flow of code by setting breakpoints.
I got it to work by adding EnableViewState = False in the <FORM runat="server"> tag in the asp.NET code
I am new to angularJS even this client side coding.Started for interest and exploring it happily.
I just tried to follow an example # Navigational Menu
Have tied to do it from binding the data from server side.its not working. need help ..
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Script.Serialization;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.Services;
using System.Data;
namespace AngularJS
{
public partial class AngularJSTest : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
[WebMethod]
public static DataTable A()
{
DataTable table = new DataTable();
table.Columns.Add("date", typeof(string));
table.Columns.Add("text", typeof(string));
table.Rows.Add("20/05/2012", "A");
table.Rows.Add("20/05/2012", "B");
table.Rows.Add("20/05/2012", "C");
return table;
}
[WebMethod]
public static DataTable B()
{
DataTable table = new DataTable();
table.Columns.Add("date", typeof(string));
table.Columns.Add("text", typeof(string));
table.Rows.Add("20/05/2012", "P");
table.Rows.Add("20/05/2012", "Q");
table.Rows.Add("20/05/2012", "R");
return table;
}
[WebMethod]
public static DataTable C()
{
DataTable table = new DataTable();
table.Columns.Add("date", typeof(string));
table.Columns.Add("text", typeof(string));
table.Rows.Add("20/05/2012", "X");
table.Rows.Add("20/05/2012", "Y");
table.Rows.Add("20/05/2012", "Z");
return table;
}
}
}
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="AngularJSTest.aspx.cs"
Inherits="AngularJS.AngularJSTest" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<link href="Styles/style.css" rel="stylesheet" type="text/css" />
<link href="Styles/css.css" rel="stylesheet" type="text/css" />
<script src="Scripts/angular.min.js" type="text/javascript"></script>
<script>
myApp.factory('getProductService', function ($http, $q) {
function getProduct(url) {
var deferred = $q.defer();
$http({ method: 'GET', url: url })
.success(function (data) {
deferred.resolve(data);
})
.error(function (error) {
console.error('Error occurred trying to get the products: ', error);
deferred.reject(error);
});
return deferred.promise;
}
return {
purchases: function () {
var url = 'AngularJSTest.aspx/A'
return getProduct(url);
},
sale30Days: function () {
var url = 'AngularJSTest.aspx/B'
return getProduct(url);
},
saleProducts: function () {
var url = 'AngularJSTest.aspx/C'
return getProduct(url);
}
};
});
myApp.controller('ProductsController', function ($scope, getProductService) {
$scope.purchase = getProductsService.purchases();
$scope.sale30Day = getProductsService.sale30Days();
$scope.saleProduct = getProductsService.saleProducts();
});
</script>
<style>
body
{
font: 12px arial, helvetica, sans-serif;
}
h2
{
font-size: 16px;
}
table
{
margin: 20px 0;
border-collapse: collapse;
}
th, td
{
border: 1px solid #ccc;
padding: 2px;
}
a.active
{
color: red;
}
</style>
</head>
<body>
<form id="form1" runat="server">
<div ng-app="myApp">
<nav class="{{active}}" ng-init="active='home'">
Purchases
Products on sale
Last 30 days sales
</nav>
<div id="tab1" class="tabContent selected" ng-controller="PurchasesCtrl" ng:show="active == 'home'">
<h2>
Purchases:</h2>
<table cellspacing="0">
<tr class="first">
<th class="first">
Date
</th>
<th>
Description
</th>
</tr>
<tr ng-repeat="purchase in purchases.data" ng-class-odd="'odd'" ng-class-even="'even'"
ng-class="{'last':$last}">
<td class="first">
{{purchase.date}}
</td>
<td>
{{purchase.text}}
</td>
</tr>
</table>
</div>
<div id="tab2" class="tabContent selected" ng-controller="SaleProductsCtrl" ng:show="active == 'projects'">
<h2>
Sale products:</h2>
<table cellspacing="0">
<tr class="first">
<th class="first">
Date
</th>
<th>
Description
</th>
</tr>
<tr ng-repeat="saleProduct in saleProducts.data" ng-class-odd="'odd'" ng-class-even="'even'"
ng-class="{'last':$last}">
<td class="first">
{{saleProduct.date}}
</td>
<td>
{{saleProduct.text}}
</td>
</tr>
</table>
</div>
<div id="tab3" class="tabContent selected" ng-controller="Sale30DaysCtrl" ng:show="active == 'services'">
<h2>
Sale 30 days:</h2>
<table cellspacing="0">
<tr class="first">
<th class="first">
Date
</th>
<th>
Description
</th>
</tr>
<tr ng-repeat="sale30Day in sale30Days.data" ng-class-odd="'odd'" ng-class-even="'even'"
ng-class="{'last':$last}">
<td class="first">
{{sale30Day.date}}
</td>
<td>
{{sale30Day.text}}
</td>
</tr>
</table>
</div>
</div>
</form>
</body>
</html>
Focusing strictly on the front end I would recommend making a single service for getting Purchases, SalesProducts, Sale30Days for ex:
myApp.factory('getProductService', function ($http, $q) {
function getProduct(url) {
var deferred = $q.defer();
$http({method: 'GET', url: url})
.success(function (data) {
deferred.resolve(data);
})
.error(function (error) {
console.error('Error occurred trying to get the products: ', error);
deferred.reject(error);
});
return deferred.promise;
}
return {
purchases: function () {
var url = 'yourURLPurchases'
return getProduct(url);
},
sale30Days: function () {
var url = 'yourURLSale30Days'
return getProduct(url);
},
saleProducts: function () {
var url = 'yourURLSaleProducts'
return getProduct(url);
}
};
});
Now you can use Dependancy Injection to inject this service into whatever controller needs to get data.
For example your purchases controller:
myApp.controller('PurchasesController', function($scope, getProductService) {
$scope.purchases = getProductsService.purchases();
});
Sale30Days:
myApp.controller('Sale30Days', function($scope, getProductService) {
$scope.sale30Days = getProductsService.sale30Days();
});
However looking at an even higher level of functionality all three of these controllers are doing a similar function - serving products.
So i would recommend refactoring to an even higher level just having a single ProductsController:
myApp.controller('ProductsController', function($scope, getProductService) {
$scope.purchases = getProductsService.purchases();
$scope.sale30Days = getProductsService.sale30Days();
$scope.saleProducts = getProductsService.saleProducts();
});
In this way you can share the potential functions you will need to calculate attributes of the products - prices, tax, amounts - all within one single controller.
Now you can bind the data properly.