I'm writing a simple winforms app in C# that connects to an ashx file which has JSON updating every 1 second. My app needs to call this file, gathering data and display it on my aspx page.
The requirements are that I have one button to start the process. When the button is pressed one instance of the data displays as it should. The problem is when I try to do it multiple times.
protected void eThorButton_Click(object sender, EventArgs e)
{
//for (int i = 0; i < 5; i++)
//{
RenderData(eThorButton.Text);
Thread.Sleep(1000);
//}
}
private void RenderData(string buttonText)
{
EquationData deserializedData = getData("http://test.com/test.ashx");
var processed = new ProcessEquation();
int result = processed.Calculate(deserializedData);
string res = deserializedData.parm1 + " " + deserializedData.op + " " + deserializedData.parm2 +
" = " + result;
TextBoxResult.Text = res;
equation.Append(" " + deserializedData.parm1 + " " + deserializedData.op + " " + deserializedData.parm2 +
" = " + result + '\n');
TextAreaResults.Value = equation.ToString();
}
What I want is for each record to render as I loop through the data, pausing for one second before continuing. What actually happens is the loop finishes first and then renders all five records at the same time.
How can I modify my code to display each record, one second apart?
thanks
I created an ajax enabled WCF service:
namespace CandidateTest.Service
{
[ServiceContract(Namespace = "CandidateTest.Service")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class eThorService
{
public string button;
[WebGet()]
[OperationContract]
public void getUpdate()
{
_Default def = new _Default();
def.RenderData(button);
}
}
}
and a script to call 'getUpdate'
$(function () {
while ($('#eThorButton').text != "Stop") {
$.ajax({
url: 'Service/eThorService.svc/getUpdate',
method: 'GET',
dataType: 'json',
success: function(){
alert("success");
},
error: function (err) {
alert(err);
}
})
delay(1000);
}
});
This is based on research online. This is my first attempt at doing this so I don't really know what I'm doing. The service runs from the browser when I enter the URL but it doesn't appear to be being called from my script. What am I doing wrong?
You are forgetting how the page lifecycle works. Your eThorButton_Click event handler finishes before any HTML is sent back to the browser to be rendered.
If you want to see data change on your page live, you need to use javascript on the client to make a request back to the server to get the update for that second. I would make a new webservice that calls your RenderData function and returns the equation.ToString() result. Then have javascript calls this webservice. When it gets the result, append it to a <div/> to display it.
Related
I have a single Visual Studio project that has the aspx default page, some jquery scripts and the .svc WCF service file. It works fine if I connect with a browser (non debug) but when I debug in VS and hit a button that calls a web method to display the server time, it works fine the first and second times but then shows the first time again and cycles through both times. If I put a breakpoint on the web method it doesn't break after the first few times.
Is this to do with the fact that they are in the same project?
Sorry, here's the JQuery function:
function controlOutput(outputNumber, state) {
var webMethod = "ControlOutput?DeviceIPAddress=" + adamsIPAddress + "&OutputNumber=" + outputNumber + "&State=" + state + "&vSessionID=" + sessionID;
var fullCommandURL = webServiceUrl + webMethod;
jQuery.support.cors = true;
$.ajax({
type: "GET", //GET or POST or PUT or DELETE verb
url: fullCommandURL, // Location of the service
contentType: 'application/json; charset=utf-8', // content type sent to server
dataType: "json", //Expected data format from server
success: function (result) {//On Successfull service call
connectionInfo = result;
$(h2Test).text(result);
//alert(result);
},
error: function (result) {// When Service call fails
alert(result.statusText);
}
});
}
And the WCF Service code:
public string ControlOutput(string DeviceIPAddress, int OuputNumber, int State, Guid SessionID)
{
try
{
string ret = DateTime.Now.ToString("HH:mm:ss.fff");
AdamSocket adamSocket = new AdamSocket();
adamSocket.SetTimeout(1000, 1000, 1000);
bool con = adamSocket.Connect(DeviceIPAddress, ProtocolType.Tcp, 502);
bool res = adamSocket.Modbus().ForceSingleCoil(17, State);
adamSocket.Disconnect();
return ret;
}
catch (Exception ex)
{
LogEvent(null, "Application Exception", ex.Message, SessionID);
return "Failed";
}
}
It turns out the GET command was caching and so only executing a couple of times. Using POST fixed this. ;)
I realize this is a common error and I've followed the many fixes to this problem offered online but have yet to find a solution.
I developed a winform app which gets JSON from an external website. I click a button control and the app goes through my json serialiser method and posts the results to a textbox and appends to a textarea.
public void RenderData(string buttonText)
{
if (buttonText == "Start")
{
EquationData deserializedData = getData("http://test.ethorstat.com/test.ashx");
var processed = new ProcessEquation();
int result = processed.Calculate(deserializedData);
string res = deserializedData.parm1 + " " + deserializedData.op + " " + deserializedData.parm2 +
" = " + result;
TextBoxResult.Text = res;
equation.Append(" " + deserializedData.parm1 + " " + deserializedData.op + " " + deserializedData.parm2 +
" = " + result + '\n');
TextAreaResults.Value = equation.ToString();
}
}
This worked fine as it was. But requirements have changed in that the app has to poll data every second. Therefore I created a wcf web service called by a jquery script to run every second.
The problem is my controls - textbox and textboxarea - generate {"Object reference not set to an instance of an object."}. My assumption is that these controls aren't being loaded now that I'm calling the method from JQuery's ajax function (?).
$(document).ready(function () {
//while ($('#eThorButton').text != "Stop") {
if ($('#eThorButton').click) {
$.ajax({
url: 'Service/eThorService.svc/getUpdate',
method: 'get',
dataType: 'json',
success: function(){
alert("success");
},
error: function (err) {
alert(err);
}
})
//delay(1000);
}
});
My controls do show in intellisense and, of course, on Default.aspx when I run it. How can I fix this?
EDIT
I solved the 'Object not set...' problem by instantiating a new textbox:
public partial class _Default : Page
{
public static StringBuilder equation = new StringBuilder();
public TextBox TextBoxTest = new TextBox();
When I debug and step through the value is set, the textbox renders but the textbox is empty. How do I fix that?
Make your method static and add annotation [WebMethod] and return list of results.
[System.Web.Services.WebMethod(EnableSession=true)]
public static List<string> RenderData(string buttonText)
{
// return result here
}
Pass parameter with data:{buttonText:yourvalue} to $.ajax call. and change the success function and assign values to your control on client side via javascript.
success : function(msg){
if(msg.d!=null){
$('#<%=TextBoxResult.ClientID%>').val(msg.d[0]);
}
}
First, i have quickly become a huge fan of jQuery. The simplicity has really caught my attention. I am learning something new everyday working with jQuery as i have not been working with it for that long. I have working with the SimpleModal and love its look and feel. I have come across and issue though and was wondering if there was anyone who could help me with it. I have a page that was originally making a call to the database retrieving data and populating a gridview with the data. I had the OSX Style SimpleModal attached to a linkbutton in the gridview and that worked GREAT!! However, ive decided to instead of having server-side code call the database, i will have an .ajax call which will retrieve the data. Obviously i cannot populate the gridview with the data from the .ajax call so i decided to dynamically create a table with a link inside the table hoping it would have the ability to launch the OSX Style SimpleModal the same way the gridview link did. But to my dismay, it did not. I was wondering if anyone had any ideas on how to get it to work or perhaps suggest a different technique for showing the data coming back from the .ajax call.
Here is my jQuery code:
$('#cmdSubmit_Create').click(function () {
var allowCodes;
if ($('#chkAllowValueCodes').is(':checked')) {
allowCodes = 1;
}
else {
allowCodes = 0;
}
$.ajax({
type: "POST",
url: "Test.aspx/createSource",
data: '{"schoolId":"' + $('#ddSchools').val() + '","vendor":"' + $('#txtVendor').val() + '","tsource":"' + $('#txtTSource').val() + '","allowCodes":"' + allowCodes + '"}',
contentType: "application/json",
dataType: "json",
success: function (msg) {
// Replace the div's content with the page method's return.
document.getElementById('divResults').innerHTML = msg.d;
},
error: function (xhr, status, error) {
alert('error' + error)
}
});
return false;
});
This is my code-behind:
[WebMethod]
public static string createSource(string schoolId, string vendor, string tsource, int allowCodes)
{
try
{
dsResults = Common.CreateHandPSource(tsource, schoolId, vendor, allowCodes);
return BuildTable(dsResults.Tables[0]);
}
catch
{
throw new Exception("Could not create source code!");
}
}
public static string BuildTable(DataTable dt)
{
StringBuilder sb = new StringBuilder();
int x = 0;
int y = 1;
int colCount = dt.Columns.Count;
sb.Append("<table><thead>");
foreach (DataColumn column in dt.Columns)
{
sb.Append("<th>" + column.ColumnName + "</th>");
}
sb.Append("</thead><tbody>");
foreach (DataRow row in dt.Rows)
{
sb.Append("<tr>");
do
{
sb.Append("<td>");
if (y == 0)
{
sb.Append("<a href='#' class='osx' OnClientClick='showFields(this)' >" + row["SchoolId"] + "-" + row["title"] + "</a>");
}
else
{
sb.Append(row[y]);
}
sb.Append("</td>");
y++;
}
while (y < colCount);
sb.Append("<tr>");
y = 0;
}
sb.Append("</tbody></table>");
return sb.ToString();
}
SOLUTION:
I initialize the OSX modal on the live.hover of the link and that allows the link to launch the click function for the OSX SimpleModal. Here is the code:
$('.osx').live('hover', function () {
OSX.init();
});
I see two potential problems...
You are telling the .ajax method that you expect a Json return but you are actually returning HTML.
Your data looks like a Json obect inside a string for some reason.
Try this:
$.ajax({
type: "POST",
url: "Test.aspx/createSource",
data: { schoolId: $('#ddSchools').val(), vendor: $('#txtVendor').val(), tsource: $('#txtTSource').val(), allowCodes: allowCodes},
dataType: "html",
success: function (msg) {
// Replace the div's content with the page method's return.
$('#divResults').clear().html(msg);
},
error: function (xhr, status, error) {
alert('error' + error)
}
});
I am trying to use the jQuery Autocomplete UI widget on a text box and I am having no luck getting the source to work. I have a database full of names that I want the autocomplete to work against, so I created a page called searchpreload.aspx and it looks for a variable in the url and queries the db based on the querystring vraiable.
When I type in the search box, I am using the keyup function so I can capture what the value is that needs to be sent over. Then I do my string gathering from the db:
if (Request.QueryString["val"] != null)
{
curVal = Request.QueryString["val"].ToString();
curVal = curVal.ToLower();
if (Request.QueryString["Type"] != null)
type = Request.QueryString["Type"].ToString();
SwitchType(type,curVal);
}
It queries the database correctly and then it takes the strings and puts them in a list and prints them out to the page:
private void PreLoadStrings(List<string> PreLoadValues, string curVal)
{
StringBuilder sb = new StringBuilder();
if (PreLoadValues.Any())
{
foreach (string str in PreLoadValues)
{
if (!string.IsNullOrEmpty(str))
{
if (str.ToLower().Contains(curVal))
sb.Append(str).Append("\n");
}
}
Response.Write(sb.ToString());
}
}
This works fine, if I navigate to this page I get a listing of all of the data that I need, however I can not get it to show up in the autocomplete box. When I debug the code, the source of the autocomplete is calling this page correctly each time and getting the correct data, it just is not displaying anything. Am I doing something wrong?
JQuery Code:
<script type="text/javascript">
$(document).ready(function () {
$(".searchBox").focus();
var checked = 'rbCNumber';
$("input:radio").change(function (eventObject) {
checked = $(this).val();
});
$(".searchBox").keyup(function () {
var searchValue = $(".searchBox").val();
//alert("Searchpreload.aspx?val=" + searchValue + "&Type=" + checked);
$(".searchBox").autocomplete({
source:"Searchpreload.aspx?val=" + searchValue + "&Type=" + checked,
minLength: 2
});
});
});
</script>
Also, should I be doing this a different way to make it faster?
You arent displaying the results into anything - source will return a data item that you can then use to populate something else on the page. Look at autocomplete's select and focus methods.
here is an example of how i have done it:
field.autocomplete({
minLength: 1,
source: "whatever",
focus: function (event, ui) {
field.val(ui.item.Id);
return false;
},
search: function (event, ui) {
addBtn.hide();
},
select: function (event, ui) {
setup(ui);
return false;
}
})
.data("autocomplete")._renderItem = function (ul, item) {
return $("<li></li>")
.data("item.autocomplete", item)
.append("<a>" + item.Id+ ", " + item.Name + "</a>")
.appendTo(ul);
};
The .data part is the part you are missing. Once the data comes back from the autocomplete you arent doing anything with it.
The source does not need to include the term the user entered into the search box. Jquery will automatically append the term onto the query string for you. If you watch the request get generated in firebug, you will see the term query hanging off the end of the url.
I am lazy loading snippets of html on our page in order to improve performance. jQuery's load method does not provide access to the full ajax api (things like error callbacks) so I created a more robust version of it.
I am calling this method 3-5 times per page on just about every page load and am logging when there is some sort of error with ajax call. What I am finding is that about 0.3% of the time the ajax calls are failing the majority of the failures are in firefox 3.6. I am using jQuery 1.5.1 with ASP.NET server side. The 'errorThrown' parameter of the error callback reads:
[Exception... "Component returned failure code: 0x80040111 (NS_ERROR_NOT_AVAILABLE) [nsIXMLHttpRequest.getAllResponseHeaders]" nsresult: "0x80040111 (NS_ERROR_NOT_AVAILABLE)"
and the jqXHR reads:
{"readyState":4,"status":0,"statusText":"error"}
I have confirmed with users that they are experienceing this problem and it's not just bots or some logging of an unexperienced error.
here is the code for my "load" widget
(function ($) {
$.fn.elfLoad = function (url, options) {
return this.each(function () {
var $elem = $(this);
options = $.extend({}, {
type: "GET",
dataType: "html",
data: "",
error: function (jqXHR, status, errorThrown) {
$elem.html('<div class="elf-missing-content centerText">Doh! Something did not go so well when trying to load this content. Please try again later.');
elf.ajax.logInfo("data: " + options.data + " errorThrown: " + errorThrown + " webmethod: " + options.url + "jqXHR: " + JSON.stringify(jqXHR),"elfLoad");
}
}, options);
options.success = function (data, status, jqXHR, responseText) {
responseText = jqXHR.responseText;
if (jqXHR.isResolved()) {
jqXHR.done(function (r) {
responseText = r;
});
$elem.html(responseText);
}
if (options.callback) {
var callbackArgs = {
responseText: responseText,
$elem: $elem,
status: status,
jqXHR: jqXHR
};
$elem.each(options.callback, [callbackArgs]);
}
}
options.url = url;
if (options.data) {
options.data = $.param(options.data, $.ajaxSettings.traditional);
options.type = "POST";
} else {
options.data = "";
}
$.ajax(options);
});
}
})(jQuery);
A call to it would look like this $('#container').elfLoad('url.aspx',{foo:'bar'});
Has anyone else had this problem? Any ideas? jQuery claims to have recently closed a ticket that looks like this in 1.5.1 but I see someone else is having a similar issue. http://bugs.jquery.com/ticket/8400
Thanks!
I ended up solving this issue by using a setTimeout for 2 seconds and retrying the request. So far this is working 100% of the time.