Textbox (and other controls) - "Object not set to an instance...." - c#

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]);
}
}

Related

ASP.NET Form app not rendering continuously

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.

JavaScript dialog using AJAX call is out of sync

I'm having a problem with some JavaScript which is intended to display a JQUERY dialog box based on a C# ViewModel.
I have an ASP drop down within a repeater which displays 'Registration Date' information. The idea is when the user selects a date from the list, the JavaScript dialog box will appear displaying a more rounded summary of information relating to that registration using specific View Model properties. The function CustomerSummary is called on a standard $(document).ready for the page in question.
JS Code
function CustomerSummary() {
var registrationId;
var data;
$("select[id$='ddlRegistration']").change(function () {
registrationId = $(this).val();
if (registrationId !== 'default')
{
data = MakeAJAXCall(registrationId);
$("#dialog").html("Registration Id: " + data.RegistrationId + "<br />" +
"Permit From: " + data.PermitFrom + "<br />" +
"Permit To: " + data.PermitTo + "<br />" +
"Registration Status: " + data.RegistrationStatus
);
$("#dialog").dialog({
show: {
effect: "blind",
duration: 1000
},
hide: {
effect: "explode",
duration: 1000
}
});
}
});
function MakeAJAXCall(regId)
{
$.ajax({
type: "post",
contentType: "application/json; charset=utf-8",
dataType: "text json",
url: "/Secure/CustomerSummary.aspx/GetRegistration",
data: "{ regId: \"" + regId + "\" }",
success: function (msg) {
data = msg.d;
},
error: function (xOptions, textStatus)
{
console.log(textStatus);
console.log(xOptions);
}
});
}
}
C# Code
[WebMethod(), ScriptMethod(UseHttpGet=false)]
public static RegistrationViewModel GetRegistration(int regId)
{
RegistrationRepository repo = new RegistrationRepository();
RegistrationViewModel reg = new RegistrationViewModel();
RegistrationFactory regFac = new RegistrationFactory();
reg = regFac.ConvertToRegistrationViewModel(repo.GetRegistration(regId));
return reg;
}
What is happening during debug
What is happening here is on this line :
$("#dialog").html("Registration Id: " + data.RegistrationId + "<br />" +
I'm getting the error:
Uncaught TypeError: Cannot read property 'RegistrationId' of undefined
The first time I select a date from the menu and the change function is invoked, I get the above error message, and no dialog box appears, if I inspect data I can indeed see that it is undefined. Then, once I select a different data from the drop down menu, and I hit my breakpoint (change.(function) data is set to the data retrieved from the previous AJAX call, the dialog box then pops up but with the previous requests data, the results then stay in this cycle, every time I select a data I am presented with the previous selections information.
Can anyone point out why im constantly one selection out of sync, I believe its due to the first change request but I don't understand why the AJAX call isn't setting data to the desired result until I select the next drop down item.
This will not work
data = MakeAJAXCall(registrationId);
Because MakeAJAXCall is performing an Ajax call and it is asynchronous so the return will not execute in the same order as your return in the function. So, you need to use a callback.
Try this to change your code to something like:
MakeAJAXCall(registrationId, function(data){
$("#dialog").html("Registration Id: " + data.RegistrationId + "<br />" +
"Permit From: " + data.PermitFrom + "<br />" +
"Permit To: " + data.PermitTo + "<br />" +
"Registration Status: " + data.RegistrationStatus
);
});
Then on your Ajax Call you need to make this change as well:
function MakeAJAXCall(regId, callback)
{
$.ajax({
type: "post",
contentType: "application/json; charset=utf-8",
dataType: "text json",
url: "/Secure/CustomerSummary.aspx/GetRegistration",
data: "{ regId: \"" + regId + "\" }",
success: function (msg) {
data = msg.d;
callback(data); //<--- You callback function is called here
},
error: function (xOptions, textStatus)
{
console.log(textStatus);
console.log(xOptions);
}
});
}
First A in Ajax is for asynchronous. It means your call will run in the background and that is why you use callbacks. When your call completed with success/error, say 10 seconds later, correct function is called. In the meanwhile, you other code that sets up and creates a result also runs, most likely before any answers received from ajax query. As #Dalorzo suggested, wrap your result dialog code in a callback, so your code will run after results received.

Unexpected jQuery ajax json response

I am having some strange issues with jQuery (1.7.2) ajax and asp.net.
When using the code below locally this all appears to work fine. The ajax fires fine, the modal pops up as expected, the div slides down, and I'm very happy with the result.
However, on our development server, we run into some strange issues. We start hitting the error function. In the error function, the return text isn't our JSON'd time stamp, but rather the HTML from a different page in our page flow. We've tried playing with the params to .ajax, we've tried fiddling with the modal, we've tried just returning the timestamp in our code behind method, we tried changing our dataType to text. That allowed it to fire the modal, however, Inf.innerHTML just ended up displaying the rendering of that other page in our page flow.
We've spent a bunch of time trying to debug this, but we're still stuck. Any ideas would be much appreciated.
jQuery:
$("#<%= Btn.ClientID %>").click(function() {
$.ajax({
async: true,
type: "POST",
url: "Page.aspx/Method",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(data) {
$("#Modal").modal({
closeClass: "Modal-Close",
escClose: false,
opacity: 35,
overlayCss: { backgroundColor: "#000" }
}); //end Modal
//timeStamp = data.d; //Timestamp elsewhere in the js
}, //end success
error: function(xhr, status, error) { alert("xhr: " + xhr.responseText + "\n\nstatus: " + status + "\n\nerror: " + error); }
}); //end ajax
return false;
}); //end Btn.click
$(".Modal-Close").click(function() {
ModalClose();
});
var timeStamp;
function ModalClose() {
var img = document.getElementById("imgP");
var Inf = document.getElementById("Info");
var Name = document.getElementById("<%=divName.ClientID %>").value;
img.src = "difImg.png";
Inf.innerHTML = "Sometext" + Name + ", MoreText.<br />" + timeStamp;
var divO = document.getElementById("<%=divOut.ClientID %>");
$(divO).slideDown();
}
C# Page Code-behind
[WebMethod(EnableSession = true)]
public static string Method()
{
// Various magic
return "{\"d\":\"" + DateTime.Now.ToString("MMMM dd, yyyy h:mm tt") + "\"}";
}

How to get the OSX Style SimpleModal to work with dynamic linkbutton

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)
}
});

jquery autocomplete source as a url that takes in query strings

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.

Categories

Resources