Reputation: 838
I've a DetailView returning insert parameters:
<InsertParameters>
<asp:Parameter Name="Name" Type="String" />
<asp:Parameter Name="Capital" Type="String" />
<asp:Parameter Name="Currency" Type="String" />
<asp:Parameter Name="ISOCode" Type="String" />
</InsertParameters>
to method:
public void AddCountry(string Name, string Capital, string Currency, string ISOCode)
{
CountyList.Add(new Country(Name, Capital, Currency, ISOCode)));
}
but how to force DetailsView to return a custom class?
public void AddCountry(Country country)
{
CountyList.Add(country);
}
Upvotes: 1
Views: 333
Reputation: 838
Here is the answer.
In your business object, creating methods with long parameter lists that map control values one-to-one to data store values can result in code that is not easily reusable. A better practice is to encapsulate your data in a custom class and then pass an instance of the class as a parameter. That way, the data that makes up an instance of the class, such as an employee record, can change without requiring any changes to the public interfaces exposed by the data source object.
Although you cannot set the Type of a parameter to the name of a custom class, you can set the ObjectDataSource control's DataObjectTypeName property to the name of a custom user-defined type, such as the NorthwindEmployee class, and then pass an instance of the type to a business object data method. To pass user-defined objects to a data source object, the following conditions must be met:
The user-defined type must have a default constructor (a constructor that takes no parameters).
The user-defined type must define public properties whose names match those of the dictionary entries passed to the data source control from data-bound controls such as GridView and DetailsView. For details about these dictionaries, see Using Parameters with Data Source Controls.
The data source object's public properties must expose both get and set accessors.
So, in my case I can pass Countries object only if object's public properties expose both get and set accessors. Only getter was public and setters were initialized through constructor. This is something can't be done: pass values through object constructor. Finally, problem was somewhere else: in ObjectDataSource not in DetailsView component.
Upvotes: 1
Reputation: 10565
You force to return a Class using the properties:TypeName
and DataObjectTypeName
of ObjectDataSource
. No need to specify any Insert Parameters then.
Create a class in your App_Code
folder which declares the various fields as publicly accessible.
For example:
Class file Country.cs
, that declares the fields
public class Country
{
public Country()
{
}
private string name;
public string Name
{
get { return name; }
set { name= value; }
}
private string capital;
public string Capital
{
get { return capital; }
set { capital= value; }
}
private string currency;
public string Currency
{
get { return currency; }
set { currency= value; }
}
private string iSOCode;
public string ISOCode
{
get { return iSOCode; }
set { iSOCode= value; }
}
}
Now in your Insert Method: AddCountry()
, just pass an instance of the above class as below. Access the field values using Class_variable_Name.Public_Field_Name
as seen below.
public void AddCountry(Country country)
{
// a sample code to access the values from Class instance passed in this method
string connString = WebConfigurationManager.ConnectionStrings["MyConnections"].ConnectionString;
SqlConnection con = new SqlConnection(connString);
SqlCommand cmd = new SqlCommand();
cmd.CommandText = "Insert into Country(Name, Capital,Currency,ISOCode)
values(@Name,@Capital,@Currency,@ISOCode)";
cmd.Connection = con;
// Add the insert parameters
cmd.Parameters.Add(new SqlParameter("@Name", SqlDbType.NVarChar, 20));
// specify the values for insert parameters
// using the Country class passed as parameter to this method
cmd.Parameters["@Name"].Value = country.Name; // country.Public_Field_Name
cmd.Parameters.Add(new SqlParameter("@Capital", SqlDbType.NVarChar, 20));
cmd.Parameters["@Capital"].Value = country.Capital;
cmd.Parameters.Add(new SqlParameter("@Currency", SqlDbType.NVarChar, 20));
cmd.Parameters["@Currency"].Value = country.Currency;
cmd.Parameters.Add(new SqlParameter("@ISOCode", SqlDbType.NVarChar, 20));
cmd.Parameters["@ISOCode"].Value = country.ISOCode;
con.Open();
// execute the Insert Command
cmd.ExecuteNonQuery();
}
Obviously in your ObjectDataSource
control, you need to specify the properties: TypeName
, DataObjectTypeName
.
1.) TypeName
indicates the name of the class that contains the data access methods, means the Class file that contains your method: AddCountry()
2.) DataObjectTypeName
: Gets or sets the name of a class that the ObjectDataSource
control uses for a parameter in an update
, insert
, or delete
data operation, instead of passing individual values from the data-bound control. Here in our case this is Country
class created above.
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
DataObjectTypeName="Country"
InsertMethod="AddCountry"
TypeName="CountryAccessMethods" <!-- assuming you have defined your Insert,
Update,Delete methods inside a class file named `CountryAccessMethods` -->
</asp:ObjectDataSource>
Upvotes: 1