User Control controls are null - c#

I'm calling a webService.asmx using Jqueryand inside that service i'm retrieving a usercontrolcontrol's values to save them in the database but the user control has thrown a NullReferenceException
here is Ajaxcall
function SaveEdit()
{
$.ajax({
type: "POST",
url: "Services/RatiosSettingsService.asmx/UpdateRatios",
data: "{}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (result) { }
});
}
and this is WebServicecode
[WebMethod]
public void UpdateRatios()
{
using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["Crs2"].ConnectionString))
{
ADO ado = new ADO();
List<SqlParameter> parameters = new List<SqlParameter>();
ucOtherRatios2 obj = new ucOtherRatios2();
Dictionary<string, int> hs = obj.GetHsChks();
foreach (KeyValuePair<string, int> item in hs)
{
SqlParameter para = new SqlParameter(item.Key, item.Value);
parameters.Add(para);
}
con.Open();
ado.CUDSp("UpdateRatios", "spUpdateClientRatios",parameters,con);
con.Close();
}
}
and here is where the exception happened inside usercontrol method that retrieve the controls values
public Dictionary<string, int> GetHsChks()
{
Dictionary<string, int> chks = new Dictionary<string, int>();
chks.Add("#siAnalysisOtherRatiosHistorical1", Convert.ToInt32(chkOthWcHs.Checked));
chks.Add("#siAnalysisOtherRatiosHistorical2", Convert.ToInt32(chkOthWiHs.Checked));
chks.Add("#siAnalysisOtherRatiosHistorical3", Convert.ToInt32(chkOthTlgHs.Checked));
chks.Add("#siAnalysisOtherRatiosHistorical4", Convert.ToInt32(chkOthEiHs.Checked));
chks.Add("#siAnalysisOtherRatiosHistorical5", Convert.ToInt32(chkOthEcHs.Checked));
chks.Add("#siAnalysisOtherRatiosHistorical6", Convert.ToInt32(chkOthEicHs.Checked));
chks.Add("#siAnalysisOtherRatiosHistorical7", Convert.ToInt32(chkOthEsHs.Checked));
chks.Add("#siAnalysisOtherRatiosHistorical8", Convert.ToInt32(chkOthEtHs.Checked));
return chks;
}
it says that checkbox is null

You can't access page's controls from a webmethod.
Since web methods don't carry the page state. It isn't a full postback. Instead just the session cookie travels with the request. You have to do a full page postback to get or set the control values.
Or you have to send the values of the controls through AJAX post method.
You can get more details on below link:
How to access page controls inside a static web method?

I see one thing in jQuery what would be good to change. Maby is better to use $.getJSON() function inside jQuery if you only getting JSON data. There you can use .done() to get data and .fail() for debbug.
Next thing is setup POST or GET variables to pass data to your JSON file to get proper data.

Related

List<string> with Json asp.net mvc

I've been trying to find an answer on google without any result. My question is how can I manipulate my Json data (List<string>) in my view? I'd like to show all the string returned in a div for example.
Here's where I'm currently stuck at:
CONTROLLER
[HttpPost]
public async Task<ActionResult> RetournerOP(int OF)
{
List<string> ops = new List<string>();
Task verif = Task.Run(() =>
{
try
{
connection.Open();
string sqlQuery = "SELECT Operation from ZZ where ordre = " + OF;
SqlCommand command = new SqlCommand(sqlQuery, connection);
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
ops.Add(Convert.ToString(reader["Operation"]));
}
}
}
catch (Exception) { }
finally { connection.Close(); }
});
await verif;
return Json(ops);
}
VIEW
function retournerOp() {
$.ajax({
url: '#Url.Action("RetournerOp", "Home", new { area = "Ajout" })',
data: {OF: document.getElementById("NumOf").value},
type: 'POST',
dataType: 'JSON',
cache: false,
success: function (data) {
//How can I manipulate my data returned?
}
});
}
Your server action method is currently returning an array of strings. So in your ajax call's success callback, you may loop through them and use each item as needed ( like adding to your DOM). $.each method will be handy to loop.
For example, the below code loops through the array and wrap each item in a p tag and append the list of p tags to a div with id myDivId
success: function (data) {
var t = "<div>";
$.each(data,function(a, b) {
t += '<p>'+b+'</p>';
});
$("#myDivId").html(t);
}
If you want to render a more complex html markup, i would strongly advise creating an action method (if you cannot update the existing one because other code is already using it) which returns a partial view result instead of the json. So you will pass the list of strings to the partia view and the partial view will have the code to render the sophisticated markup you want to return.
return PartialView(ops);
and in the partial view,
#model List<string>
#foreach (var item in Model)
{
<p>#item</p>
}
Now since the response coming from the server call is the HTML markup you want, simply update the DOM with that as needed.
$.ajax({
url: '#Url.Action("RetournerOp", "Home", new { area = "Ajout" })',
data: {OF:6},
type: 'POST',
success: function (data) {
$("#myDivId").html(data);
}
});
Also as others mentioned in the comments, your server code is prone to SQL injection. You should never concatenate the user input directly to a SQL statement like that. Consider using Parameterized queries.

How to obtain checked checkbox values on the serverside in c# from an ajax Http POST using web forms (not MVC)?

Here's my ajax call:
$(function () {
$("#chkFilter").on("click", "input", function (e)
{
var filterCheckboxes = new Array();
$("#chkFilter").find("input:checked").each(function () {
//console.log($(this).val()); //works fine
filterCheckboxes.push($(this).prop("name") + "=" + $(this).val());
console.log($(this).prop("name") + "=" + $(this).val());
//var filterCheckboxes = new Array();
//for (var i = 0; i < e.length; i++) {
// if (e[i].checked)
// filterCheckboxes.push(e[i].value);
//}
});
console.log("calling ajax");
$.ajax({
url: "/tools/oppy/Default",
type: "POST",
dataType: "json",
data: { filterValues: filterCheckboxes }, // using the parameter name
success: function (result) {
if (result.success) {
}
else {
}
}
});
});
});
And my server side code:
public partial class tools_oppy_Default : System.Web.UI.Page
{
...
protected void Page_Load(object sender, EventArgs e)
{
if (Request.HttpMethod == "POST")
{
string checkedBoxes = Request["filterValues"];
testLabel.Text = checkedBoxes;
}
I'm just trying to obtain the post URL with the appropriate checked values so I can parse it on the server. However, I'm having trouble obtaining the URL. The string checkedBoxes is supposed to hold a query string like name=value&name=value&name.... but when I test it, the testLabel doesn't show anything. I'm using web forms app, not MVC. Also, I'm new to ajax and their behavior. Thanks.
First, I assume that the url in you JQuery call is valid as there is not aspx extension their.
Second, It looks like what you need to do is create a web method and call it from JQuery for example the following is a web method that accept string
[WebMethod]
public static string GetData(String input)
{
return DateTime.Now.ToString();
}
and you can call it using the same way with your current code just update the url parameter to include the method name
url: "PageName.aspx/MethodName",
for more details about web methods and their union with JQuery please check this article
Edited The following is complete sample
The web method should look like the following one
[WebMethod]
public static string GetData(string filterValues)
{
return filterValues; //This should be updated to return whatever value you need
}
The client side part of calling the web method should look like the following
$.ajax({
url: "/Default/GetData",
type: "POST",
contentType: "application/json; charset=utf-8", //I have added this as "contentType" parameter represents the type of data inside the request meanwhile the "data" parameter describes the data inside the response
data: "{ filterValues:\"" + filterCheckboxes + "\"}", //Note that I have updated the string here also set the name of the parameter similar to the input of the webmethod
dataType: "json",
success: function (result) {
alert(result.d);//You should access the data using the ".d"
}
});
One last thing, If you are using asp.net permanent routing the above code will not work and you should disable it by updating the file "App_Code/RouteConfig.cs" From
settings.AutoRedirectMode = RedirectMode.Permanent;
To
settings.AutoRedirectMode = RedirectMode.Off;
And remember to clear browser cache after the above update

save data in session one by one and save them altogether in database

I am sending ajax request to save model in json format in a Session
<script type="text/javascript">
$(function () {
$('#addSubject').click(function () {
var mydata = {
"SubjectId": $('#subjectid').val(),
"ObtainedGpa": $('#obtainedgpa').val(),
"SubjectTypeId": $('#subjecttypeid').val()
};
var dataToPost = JSON.stringify(mydata);
$.ajax({
type: "Post",
url: "/PreviousExamInfo/SaveSubjectInfo",
contentType: "application/json;charset=utf-8",
data: dataToPost,
dataType: "json",
});
})
});
</script>
this is done successfully.But the in my action i have to save them in Session.The approach is like "Click The ADD button and save the Values in the Session, again click the ADD button and store the new values in session with the previously stored values".And after clicking the submit button all the values which is in the session will be stored in database. How can I know that the session works as I expecting?Because wher I use
var mySession=Session["myItem"]
this only shows the new values not what I was added previously.Should I use Session? Or Is there anything else that I can use?
[HttpPost]
public JsonResult SaveSubjectInfo(PreviousExamSubject previousExamSubject)
{
List<PreviousExamSubject> list=new List<PreviousExamSubject>();
list.Add(previousExamSubject);
Session["myitem"] = list;
return Json(JsonRequestBehavior.AllowGet);
}
The code always replaces the existing Session["myitem"] with a new list. To append instead you could do something like this:
[HttpPost]
public JsonResult SaveSubjectInfo(PreviousExamSubject previousExamSubject)
{
List<PreviousExamSubject> list= (List<PreviousExamSubject>) Session["myitem"] ?? new List<PreviousExamSubject>();
list.Add(previousExamSubject);
Session["myitem"] = list;
return Json(JsonRequestBehavior.AllowGet);
}

JQuery changes not reflected in postback

I have two asp:BulletedLists, one is populated on Page_Load and the other is empty. The user can drag and drop < li >'s between them, the meat of that drag-n-drop is
function Move(element, source, target) {
var newLI = document.createElement("li");
var sourceBL = document.getElementById(source);
var targetBL = document.getElementById(target);
newLI.innerHTML = element.innerHTML;
sourceBL.removeChild(element);
targetBL.appendChild(newLI);
}
I create a new element so that it aligns itself within the asp:BulletedList rather than placing itself where the mouse is released.
The problem is I need to know what is where on postback, the second asp:BulletedList is always empty and the first asp:BulletedList populates itself with the original values even though I do not clear or repopulate them.
foreach (ListItem li in blSelectedDocuments.Items) // .Items is empty
{
}
In the past with working with jQuery plugins on ASP.NET WebForms pages, I have used AJAX to send the updated data back to an ASP.NET AJAX Page Method and then stored the changes into Session cache. Then upon postback, the Page_Load would look into the Session to see what order the values in the list were (I had a drag and drop list for the order of display of a report).
Mock code example:
JavaScript:
function Move(element, source, target) {
var newLI = document.createElement("li");
var sourceBL = document.getElementById(source);
var targetBL = document.getElementById(target);
newLI.innerHTML = element.innerHTML;
sourceBL.removeChild(element);
targetBL.appendChild(newLI);
// TODO: Serialize source and target lists to JSON to pass to the server
var serializedData = {};
// Use jQuery.ajax() to call ASP.NET AJAX Page Method
$.ajax({
type: "POST",
url: "PageName.aspx/UpdateListsInSessionCache",
data: serializedData,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(msg) {
// Do something here when the AJAX calls completes
}
});
}
ASP.NET Code-behind (C#)
using System.Web.Services;
[WebMethod]
public static void UpdateListsInSessionCache(List<ListItem> source, List<ListItem> target)
{
Session["SourceList"] = source;
Session["TargetList"] = target;
}
protected void Page_Load(object sender, EventArgs e)
{
// Create new lists so we have something empty and not null to work with
var source = new List<ListItem>();
var target = new List<ListItem>();
// Always check for values in Session cache and update if there are values
if (Session["SourceList"] != null)
{
source = Session["SourceList"] as List<ListItem>;
}
if (Session["TargetList"] != null)
{
target = Session["TargetList"] as List<ListItem>;
}
// Do something with source and target lists
}
Horrifically, none of that worked. I'm on SharePoint and the Session wasn't enabled (or whatever) because of some deep dark corner of SharePoint that the asp.config file is located in. Neither did ViewState work in the similar manner. Maybe the AJAX half of that would have worked, but I never got that far.
The solution I got to work was to create a hidden input field, write the order of the asp:BulletedList to that hidden field to go with the postback via the Submit button. Thanks JasonP for serialisation fiddle.
NOTE: I tried some other suggestions I found on the web, using a Label/TextBox with ViewState and/or Readonly properties set did not work for me. Label worked to change text within the page but did not persist on postback.

Query DataTable from ashx page

I would like to fill a DataTable with the Page_Load event, then be able to access it from the ashx handler page when an Ajax call is sent from the client side. Currently, the DataTable is filled every time I make an Ajax call to the handler page, which makes it a bit on the slow side. Here's what I currently do:
Default.aspx.cs
public DataTable fillSCOMDTts()
{
//SCOM TableAdapter and DataTable
dsCIInfoTableAdapters.vManagedEntityTableAdapter taSCOM;
taSCOM = new dsCIInfoTableAdapters.vManagedEntityTableAdapter();
dsCIInfo.vManagedEntityDataTable dtSCOM = new dsCIInfo.vManagedEntityDataTable();
taSCOM.Fill(dtSCOM);
return dtSCOM;
}
Ajax call from client-side:
$.ajax({
url: '/FindFootprint.ashx?queryStr=' + strParameter,
dataType: 'json',
success: function (data) {
//do stuff
});
FindFootprint.ashx.cs
public void ProcessRequest(HttpContext context)
{
string strParameter = context.Request.QueryString["queryStr"];
bool binSCOMts = false;
Default d = new Default();
DataTable dtSCOMts = d.fillSCOMDTts();
var qstSCOMts = (from row in dtSCOMts.AsEnumerable()
let fieldName = row.Field<string>("DisplayName")
where fieldName.ToLower().Contains(strParameter)
select fieldName).ToArray();
if (qstSCOMts.Length > 0)
{
binSCOMts = true;
}
JsonObject JO = new JsonObject();
JO.Add("assetName", strParameter);
JO.Add("inSCOMts", binSCOMts.ToString());
context.Response.ContentType = "text/plain";
context.Response.Write(JO.ToString());
}
A handler is not really supposed to know anything about code/objects outside of itself.
If you're able to not use the handler in this case then you could set a private static DataTable MyTable; in your page.
Then on your page_load populate this static property.
You should then be able to access this property inside a web method that you call from you Ajax. The web method would be part of your pages code-behind so will have access to the private property set above. Put the code from your handler into this web method - bar the binding.

Categories

Resources