Error: objectdatasource could not find a non-generic method - c#

I am binding dropdown list using Object data source. I got an error like this
"ObjectDataSource 'objDSStatus' could not find a non-generic method 'GetIssueAllowedStatusByCategoryIDStatusIDandUserType' that has parameters: IssueCategoryID."
My code is as follows
.aspx
< asp:DropDownList ID="ddlStatus" runat="server" DataSourceID="objDSStatus"
DataTextField="IssueStatusName" DataValueField="IssueStatusID">
< /asp:DropDownList>
< asp:ObjectDataSource ID="objDSStatus" runat="server" TypeName="DA"></asp:ObjectDataSource>
.cs
private void Bind(int IssueCategoryID, int IssueStatusID, int UserType)
{
ddlStatus.Items.Clear();
objDSStatus.SelectMethod = "GetIssueAllowedStatusByCategoryIDStatusIDandUserType";
objDSStatus.SelectParameters.Clear();
objDSStatus.SelectParameters.Add("IssueCategoryID", IssueCategoryID.ToString());
objDSStatus.SelectParameters.Add("IssueStatusID", IssueStatusID.ToString());
objDSStatus.SelectParameters.Add("UserType", UserType.ToString());
objDSStatus.DataBind();
ddlStatus.DataBind();
}
DA.cs
public List<IssueStatus> GetIssueAllowedStatusByCategoryIDStatusIDandUserType(int IssueeCategoryID, int IssueStatusID, int UserType)
{
List<IssueStatus> issueStatusList = new List<IssueStatus>();
}
Can anyone help me on this.
Thanks,
Mahesh

This doesn't look right to me:
objDSStatus.SelectParameters.Add("IssueCategoryID", IssueCategoryID.ToString());
objDSFeedback.SelectParameters.Add("IssueStatusID", IssueStatusID.ToString());
objDSFeedback.SelectParameters.Add("UserType", UserType.ToString());
Did you mean to add the second and third parameters to objDSFeedback instead of objDSStatus? Your method has three parameters, after all...
Perhaps you meant this:
objDSStatus.SelectParameters.Add("IssueCategoryID", IssueCategoryID.ToString());
objDSStatus.SelectParameters.Add("IssueStatusID", IssueStatusID.ToString());
objDSStatus.SelectParameters.Add("UserType", UserType.ToString());

one of your DA.cs parameter is int IssueeCategoryID . It should be int IssueCategoryID

Related

ASP.Net Core - Call a static method from Razor View - Build Fail without giving error

I am trying to call a static method from my razor view.
I have tried these 2 function (for the same purpose)-
1. Extension Function
public static String GetPresentableClaimName(this String text)
{
string[] textArr = text.Split(".");
Array.Reverse(textArr);
return string.Join(" ", textArr);
}
2. Normal Function
public static String GetPresentableClaimNameFromString(String text)
{
string[] textArr = text.Split(".");
Array.Reverse(textArr);
return string.Join(" ", textArr);
}
Then in razor view, I am importing like this for the first function-
#item.ClaimValue.GetPresentableClaimName()
And for the second function, I am doing this-
#Utility.GetPresentableClaimNameFromString(#item.ClaimValue)
Where item is my model object and ClaimValue is a string property in that object.
For both of the cases, I am finding this-
When I am trying to build or rebuild the project. but no error is showing.
Can anyone please help me to find what I am doing wrong?
I have solved it with help of #Evk by changing the class from internal to public

Trying to filter data in grid, receiving "Cannot create an instance of the static class" error

I am attempting to filter the items populated in a grid in the code behind. When I try to call my adapter from the data access layer, I am receiving the following error:
Cannot create an instance of the static class 'SFTIP.DataAccessLayer.InventoryAdapter'
The filter is meant to only display items in the grid related to the user role (AssetOwnershipProgramIds).
The error is in this segment new InventoryAdapter() of this line:
filteredList = new InventoryAdapter().GetAllByFilter(inventoryFilter);
Here is the code for the filter I am trying to build:
public List<Inventory> BindGrid()
{
List<Inventory> filteredList = new List<Inventory>();
SearchFilterInventory inventoryFilter = new SearchFilterInventory();
User currentUser;
currentUser = (Session["CurrentUser"] == null) ? (User)Session["CurrentUser"] : new User();
if (currentUser.AdminPrograms.Count > 0)
{
inventoryFilter.AssetOwnershipProgramIds.Add(currentUser.AdminPrograms[0].ReferenceId);
filteredList = new InventoryAdapter().GetAllByFilter(inventoryFilter);
}
return filteredList;
}
Can anyone provide some guidance on to where I am going wrong? I know that this is something fairly simple - this is an inherited project and I'm still trying to connect all the dots. Thank you for taking a look.
The error says it all.
You cannot create an instance of a static class. If you wanted to make that, remove static keyword from your class declaration.
MSDN says:
A static class is basically the same as a non-static class, but there
is one difference: a static class cannot be instantiated. In other
words, you cannot use the new keyword to create a variable of the
class type. Because there is no instance variable, you access the
members of a static class by using the class name itself.
Static class aren't meant to be instantiated:
A static class is basically the same as a non-static class, but there
is one difference: a static class cannot be instantiated. In other
words, you cannot use the new keyword to create a variable of the
class type. Because there is no instance variable, you access the
members of a static class by using the class name itself.
(Source: MSDN)
Likely, the GetAllByFilter method is static as well. If that's the case, your problem will be solved by changing the faulting line to this:
var filtereditems = InventoryAdapter.GetAllByFilter(inventoryFilter);
You would need a class declaration such as this, to do in the way your code is implemented.
public class InventoryAdapter
{
public InventoryAdapter() { }
public object GetAllByFilter() { }
}
or else call your method like this, if it's meant to be static / you don't own or control it:
var filtereditems = InventoryAdapter.GetAllByFilter(inventoryFilter);
Sorry about the delay in coming back back to this - been out ill & other newer work priorities.
So, - something so very simple. Made the mistake of assuming that "no one would ever do (or NOT do) that" and as programmers we ought to know better than to make that assumption, right? Anyhow, I had to add the <SelectParameters> back into ObjectDataSource in the aspx page:
<asp:ObjectDataSource ID="odsItInventory" runat="server" SelectMethod="BindGrid"
TypeName="ADRUO.GUI.UserControls.ExtendedInventoryGridUserControl">
<SelectParameters>
<asp:SessionParameter Name="User" Type="Object" SessionField="CurrentUser" />
</SelectParameters>
</asp:ObjectDataSource>
Thank you for the assistance - all of your comments were helpful, I believe each answer would have worked, had I had those parameters in the page. As it was, the param add was all that was required to resolve.

Variables inside control properties

This code:
<asp:TextBox runat="server" MaxLength="<%=Settings.UsernameMaxLength %>" ID="Username"/>
Throws a parser error.
Is it possible to set properties in any way similar to this without using the code behind?
No, it is not possible. Syntax <%= some code here %> cannot be used with server-side controls. You can either go with <%# some code here %>, but only in case of data binding, or just set this property in code behind, say on Page_Load:
protected void Page_Load(object source, EventArgs e)
{
Username.MaxLength = Settings.UsernameMaxLength;
}
You may try this, which should set the MaxLength value upon rendering :
<%
Username.MaxLength = Settings.UsernameMaxLength;
%>
<asp:TextBox runat="server" ID="Username"/>
I think (not tried) you can also write :
<asp:TextBox runat="server" MaxLength="<%#Settings.UsernameMaxLength %>" ID="Username"/>
But you would then need to call Username.DataBind() somewhere in the codebehind.
I'm late to the party here, but here goes anyway...
You could build your own Expression Builder to handle this case. That would allow you to use syntax like this:
<asp:TextBox
runat="server"
MaxLength="<%$ MySettings: UsernameMaxLength %>"
ID="Username"/>
Note the $ sign.
To learn how to make you own Expression Builder, please go through this old but still relevant tutorial. Don't let the wall of text scare you off because in the end, making an expression builder is easy. It basically consists of deriving a class from System.Web.Compilation.ExpressionBuilder and overriding the GetCodeExpression method. Here is a very simple example (some parts of this code was borrowed from the linked tutorial):
public class SettingsExpressionBuilder : System.Web.Compilation.ExpressionBuilder
{
public override System.CodeDom.CodeExpression GetCodeExpression(System.Web.UI.BoundPropertyEntry entry, object parsedData, System.Web.Compilation.ExpressionBuilderContext context)
{
// here is where the magic happens that tells the compiler
// what to do with the expression it found.
// in this case we return a CodeMethodInvokeExpression that
// makes the compiler insert a call to our custom method
// 'GetValueFromKey'
CodeExpression[] inputParams = new CodeExpression[] {
new CodePrimitiveExpression(entry.Expression.Trim()),
new CodeTypeOfExpression(entry.DeclaringType),
new CodePrimitiveExpression(entry.PropertyInfo.Name)
};
return new CodeMethodInvokeExpression(
new CodeTypeReferenceExpression(
this.GetType()
),
"GetValueFromKey",
inputParams
);
}
public static object GetValueFromKey(string key, Type targetType, string propertyName)
{
// here is where you take the provided key and find the corresponding value to return.
// in this trivial sample, the key itself is returned.
return key;
}
}
In order to use it in your aspx page, you must also register it in web.config:
<configuration>
<system.web>
<compilation ...>
<expressionBuilders>
<add expressionPrefix="MySettings" type="SettingsExpressionBuilder"/>
</expressionBuilders>
</compilation>
</system.web>
</configuration>
This is just to show you that it's not difficult. But please review the tutorial I linked to in order to see an example of how to deal with the expected return type from your method depending on the property being assigned etc.

Is there a way to drop static declaration from page method?

For a site I'm developing I have two html buttons, not ASP because I do not want them to postback. For the submit button I am calling a javascript function that implements PageMethods to call a C# method from the codebehind. Here is the code for the buttons and the javascript.
<fieldset id="Fieldset">
<button onclick="SendForm();">Send</button>
<button onclick="CancelForm();">Cancel</button>
</fieldset>
<asp:ScriptManager ID="ScriptManager1" EnablePageMethods="true" EnablePartialRendering="true" runat="server" />
<script type="text/javascript">
function SendForm() {
var email = $get("txtEmail").value;
PageMethods.SendForm(email, OnSucceeded, OnFailed);
}
function OnSucceeded() {
$get("Fieldset").innerHTML = "<p>Thank you!</p>";
}
function OnFailed(error) {
alert(error.get_message());
}
</script>
The codebehind method shown here:
[WebMethod]
public static void SendForm(string email)
{
if (string.IsNullOrEmpty(email))
{
throw new Exception("You must supply an email address.");
}
else
{
if (IsValidEmailAddress(email))
{
bool[] desc = new bool[14];
bool[] local = new bool[14];
bool[] other = new bool[14];
for (int i = 1; i <= 14; i++)
{
desc[i] = ((CheckBox)Page.FindControl("chkDesc" + i.ToString())).Checked;
local[i] = ((CheckBox)Page.FindControl("chkLocal" + i.ToString())).Checked;
other[i] = ((CheckBox)Page.FindControl("chkOther" + i.ToString())).Checked;
/* Do stuff here */
}
}
else
{
throw new Exception("You must supply a valid email address.");
}
}
}
does not work unless it is declared as static. Declaring it as static blocks me from checking the checkboxes on the page because it generates a "An object reference is required for the non-static field, method, or property" error. So my problem can be fixed from either of two directions. A) Is there a way I can have this method work without declaring it as static? B) How do I check the checkboxes if the method is static.
It has to be static, no way around that; But you can access the Page like this
Page page = HttpContext.Current.Handler as Page;
and do FindControl on this page instance.
desc[i] = ((CheckBox)page.FindControl("chkDesc" + i.ToString())).Checked;
Page Methods are a special case of the legacy ASMX web service technology. They allow you to place the service in the codebehind class for the page, and keep you from needing a separate project for the service.
But they will never be able to access anything on the page itself. You'll have to do that from the client side, and pass the values of the check boxes to the service.
If you need to check the checkboxes, then you need to either use an UpdatePanel to do your AJAX stuff, or return something from your page method (ideally a string) and check the checkboxes based on what's returned in javascript on client.

Passing array of strings from JS to C# inside WebBrowser control

I'm using ObjectForScripting property to interact with web page inside WebBrowser control and everything works fine except I can't figure out how to pass array of strings back to C#
HTML code
<input type="submit" onclick="window.external.save(Array('test', 'test2'))" />
Form
// Returns System.__ComObject
public void Save(object parameters)
{
}
// Throws an exception
public void Save(object[] parameters)
{
}
// Also throws an exception
public void Save(string[] parameters)
{
}
Rather than fight it; maybe approach the problem from another angle... could you (instead, either of):
delimit the data (with Array.join) and pass a single string, and split it (string.Split) in the C#
call Save multiple times, accepting a single string each time (Save(string s)), then call a final method to actually commit the changes
You can use an anonymous object instead of an array on the javascript side:
<input type="submit" onclick="window.external.save({first: 'test', second: 'test2'})" />
On the C# side (you need to use .NET 4.0 or more for the dynamic or use Type.InvokeMember if you are on an older version):
public void Save(dynamic parameters)
{
MessageBox.Show(parameters.first);
MessageBox.Show(parameters.second);
}
Not tested, but I think you can use reflection to discover the members.
Also look at this: http://dotnetacademy.blogspot.fr/2009/11/vbnetcnet-communication-with-javascript.html
function JS2VBArray( objJSArray )
{
var dictionary = new ActiveXObject( "Scripting.Dictionary" );
for ( var i = 0; i < objJSArray.length; i++ )
{
dictionary.add( i, objJSArray[ i ] );
}
return dictionary.Items();
}
Reference: http://msdn.microsoft.com/en-us/library/zsfww439(v=vs.80).aspx
<input type="submit" onclick="window.external.Save( JS2VBArray( ['test', 'test2'] ) )" />
This should go to the method.
public void Save(object[] parameters)
{
}
The string array is automatically passed as a comma-delimited string.
So this call:
window.external.save(Array('test', 'test2'));
Is received like so:
public void save(string fromjs)
{
string[] result = fromjs.Split(',');
}
It's a bit late for this, but typically when I need to pass objects or, in this case Arrays, I pass them as a JSON string.
var sArr = JSON.stringify(myArr);
window.external(sArr);
Then I have a JavaScriptSerializer on the other side that deserializes it back into an object / array.
Deserialize JSON with C#
To pass an array I found this to not be supported directly. I took the approach recommended by Marc Gravell to call multiple times but structured it in 3 methods instead, that are used in sequence: InitArgs, PushArg (multiple times), FinalArgs.
private System.Collections.Generics.Queue<string> _argsQ;
public void InitArgs()
{
_argsQ = new System.Collections.Generics.Queue<string>();
}
public void PushArg(string arg)
{
_argsQ.Enqueue(arg);
}
public void FinalArgs()
{
string[] parameters = _argsQ.ToArray();
// Save parameters
}
Now method calls can be used sequentially from html/js:
...onclick="var params = ['test', 'test2']; window.external.InitArgs(); for (var i=0; i<params.length; i++) window.external.PushArg(params[i]); window.external.FinalArgs();"...

Categories

Resources