How can I quickly display complex data on a asp.net page - c#

How should one display complex data objects in a asp.net page? Actually the below class is read only, the data needs to be displayed on screen so that agent's can tell customers how much they have to pay. I don't want to write lot of code to normalize it and show it on the page. This data is returned by web service method call.
public class FeeInfo {
private string countryInfoTextField;
public string CountryInfoTextField
{
get{return this.countryInfoTextField;}
set{this.countryInfoTextField= value;}
}
private stringfeeInfoTextField;
public string FeeInfoTextField
{
get{return this.feeInfoTextField;}
set{this.feeInfoTextField= value;}
}
private string taxInfoTextField;
public string TaxInfoTextField
{
get{return this.taxInfoTextField;}
set{this.taxInfoTextField = value;}
}
private string additionalInfoTextField;
public string additionalInfoText
{
get{return this.additionalInfoTextField;}
set{this.additionalInfoTextField = value;}
}
private PromotionInfo[] promotionInfoField; //Class
private SendAmountInfo sendAmountsField; //Class
private EstimatedReceiveAmountInfo receiveAmountsField; //Class
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("promotionInfo")]
public PromotionInfo[] promotionInfo {
get {
return this.promotionInfoField;
}
set {
this.promotionInfoField = value;
}
}
/// <remarks/>
public SendAmountInfo sendAmounts {
get {
return this.sendAmountsField;
}
set {
this.sendAmountsField = value;
}
}
/// <remarks/>
public EstimatedReceiveAmountInfo receiveAmounts {
get {
return this.receiveAmountsField;
}
set {
this.receiveAmountsField = value;
}
}
}
I converted the above into a list and bound it to gridview, but all I see is the 4 fields, not the last 3 complex properties. What could be the fast and quick way to show this data on screen?

add a toList method to FeeInfo.
public List<FeeInfo> toList(){
var retList;
var props = this.GetType().GetProperties();
foreach(var prop in props) {
if(prop.propertyType.IsArray)
for(int i=0;i<prop.length;i++)
retList.add(new GridView(prop.GetValue[i]);
else if(prop.propertyType.isClass)
retList.Add(new Gridview(prop.GetValue()));
else retList.Add(prop.GetValue());
}
return retList;
}
dont have VS to test atm unfortunatly so there's probably some adjustments to make :)

Related

How make a field in an Entity be built from two columns?

I have a table with the columns IsActive and CanBeUsed (don't ask why, it's not my choice). I want my entity to have one field called isWorkable that is done from those two fields. How can i do this?
The only thing I can think of is to do:
[Table(Name = "Task")]
public class Task
{
...elided...
private string IsActive;
[Column(Storage = "IsActive")]
public string activeState
{
get
{
return this.IsActive;
}
set
{
this.IsActive = value;
}
}
private string CanBeUsed;
[Column(Storage = "CanBeUsed")]
public string useState
{
get
{
return this.CanBeUsed;
}
set
{
this.CanBeUsed = value;
}
}
private bool isWorkable
{
get
{
return this.IsActive == "Y" && this.CanBeUsed == "Y";
}
}
}
But I would prefer that the two fields from the DB either are private (no public getter/setter) or don't exist and I can somehow make a custom setter that maps to two columns for isWorkable.
Is that possible?

Updating an object from another objects property history in C# for implementing a PATCH

I'm trying to implement a PATCH on Web API for an object that will be stored in a DB. The input object from the controller has all of the properties that can be modified but we allow the client to choose which fields to send back. We only want to update the MongoDB representation if some of the fields have changed or been set. We started using a Dirty object pattern (not sure this is a pattern) whereby when you set a property you also record that it is dirty. for instance
public class Example
{
private string _title;
public string Title
{
get { return _title; }
set
{
_title = value;
TitleWasSet = true;
}
}
public bool TitleWasSet {get;set;}
}
This could work but is kind of tedious and I feel it exposes lots of logic that could be contained.
So a solution I came up with was to store the update Actions in the inbound object then reapply them to the Mongo Object in a Try Update fashion.
like this:
public class Data
{
public string Header { get; set; }
public int Rating { get; set; }
}
public class EditDataRequest
{
private readonly List<Action<Data>> _updates;
public EditDataRequest()
{
_updates = new List<Action<Data>>();
}
public string Header
{
set
{
_updates.Add(data => {data.Header = value;});
}
}
public int Rating
{
set
{
_updates.Add(data => {data.Rating = value;});
}
}
public bool TryUpdateFromMe(Data original)
{
if (_updates.Count == 0)
return false;
foreach (var update in _updates)
{
update.Invoke(original);
}
return true;
}
}
Now this would work great but it doesn't take account of the values being the same. So i then looked at changing the list of actions to a list of functions that would return a bool if there was a difference in the value.
private readonly List<Func<Data, bool>> _updates;
And then the properties would look like this:
public int Rating
{
set
{
_updates.Add(data => {
if (data.Rating != value)
{
data.Rating = value;
return true;
}
return false;
});
}
}
And the try update method...
public bool TryUpdateFromMe(Data original)
{
if (_updates.Count == 0)
return false;
bool changesRequired = false;
foreach (var update in _updates)
{
changesRequired |= update.Invoke(original);
}
return changesRequired;
}
As you can see that property set implementation is rather clunky and would make the code nasty to read.
I'd like a way of extracting the check this property value then update it to another method that I can reuse in each property - I assume this is possibly somehow but it might not be.
Of course, if you have better suggestions for how to handle the PATCH situation then I'd be happy to hear them as well.
Thanks for reading this far.

Using { get set } Accessors for Multiple Values in MVC

EDIT: Question Reconstructed.
OK, I have revisited my get and set methods, but I am still very unclear on how it all works.
What I want to achieve is the Model is populated by the Controller, from the values that it takes form the form. This is then sent to the Db_Facade, which compares the uName and uPwd, and if they are equal returns the ACCESS, which will be set for the entire scope of the program.
I don't know if the get and set declarations are done correctly, or if they can be bunched together (If this is possible it would be great because I will be using this for much larger collections of data), and I'm pretty sure I'm implementing them wrong as well.
If you can help, my knowledge of Accessors is incredibly limited.
Here is my Compare Login method in my Controller:
public static void Compare_Login(User_Login_View Login_View)
{
User_Model getACCESS = new User_Model(); // Creates a new oject of User_Model
getACCESS.Name = Login_View.txtUsername.Text; //Populates the Model from the Login View
getACCESS.Pwd = Login_View.txtPassword.Text;
if (getACCESS.ACCESSLEVEL > 0)
{
Login_View.Close();
}
else
{
Login_View.lblError.Visible = true;
}
Login_View.Menu.SetMenuView();
}
Here is my Model:
public class User_Model
{
public string Name
{
get
{
return Db_Facade.uName;
}
set
{
Db_Facade.uName = value;
}
}
public string Pwd
{
get
{
return Db_Facade.uPwd;
}
set
{
Db_Facade.uPwd = value;
}
}
public int ACCESSLEVEL
{
get
{
return Db_Facade.ACCESS;
}
set
{
Db_Facade.ACCESS = value;
}
}
}
Here is the dummy database comparison:
class Db_Facade
{
public static string uName;
public static string uPwd;
public static string cPwd;
public static int ACCESS;
public static void getLoginACCESS()
{
uName = "paul";
uPwd = "pwd";
ACCESS = 1;
/* I get a "getACCESS does not exist" error here
if (uName == getACCESS.Name && uPwd == getACCESS.Pwd)
{
getACCESS.ACCESSLEVEL = ACCESS;
}
else
{
getACCESS.ACCESSLEVEL = 0;
}
*/
}
}
I don't know if it's needed, but here is my View
public partial class User_Login_View : Form
{
public Menu_View Menu { get; set; }
public User_Login_View()
{
InitializeComponent();
}
private void btnLogin_Click(object sender, EventArgs e)
{
User_Controller.Compare_Login(this);
}
}
2 Questions / Hints
1.) Where do you call your getLoginACCESS() ?
2.) Why do you think Db_Facade is able to access getACCESSfrom your class User_Controller?
a solution would be to modyfie your getLoginACCESS() to getLoginACCESS(User_Model getACCESS) and than call it in your Compare_Login(User_Login_View Login_View) befor your if like Db_Facade.etLoginACCESS(getACCESS);

ASMX webservice doesn't return any result

I'm trying to send an object of a custom class through my asmx webservice running on .net 4.0, but all i get is an empty response. See below:
<soap:Body>
<ActivateResponse xmlns="http://tempuri.org/">
<ActivateResult /> <!-- why is this empty -->
</ActivateResponse>
</soap:Body>
However, if i modify my method and change the return type for example from class A to B, then it returns all the properties of object B correctly. See below:
<ActivateResponse xmlns="http://tempuri.org/">
<ActivateResult>
<BtAddress>string</BtAddress>
<Name>string</Name>
<Number>string</Number>
</ActivateResult>
</ActivateResponse>
I'm wondering why its happening? I could blame to improper Serialization of class A but there's nothing fancy I'm involving in my class files. Both class files are almost similar in terms of contents and does not contain any Serialize attribute.
So, why does the webservice return one type, but not the other?
Class A:
public class A
{
private string code;
private bool isValid;
private int maxUniqueActivations;
private DateTime dateAdded;
private Customer customer = null;
private bool _initAsEmpty = false;
public License()
{
_initAsEmpty = true;
}
public string LicenseCode
{
get { return code; }
//set { code = String.IsNullOrWhiteSpace(value)? null : value.Trim(); }
}
//If i change return type to Customer, it works too
//so i dont think it should be blamed
public Customer Customer
{
get { return customer; }
}
public bool IsValid
{
get { return isValid; }
}
public int MaxUniqueActivations
{
get { return maxUniqueActivations; }
}
public DateTime DateAdded
{
get { return dateAdded; }
}
}
Class B:
public class Phone
{
private string btAddress, name, number;
private bool isValid;
private DateTime dateAdded;
private bool _initAsEmtpy = false;
public Phone()
{
_initAsEmtpy = true;
}
public string BtAddress
{
get { return btAddress; }
set { btAddress = string.IsNullOrWhiteSpace(value) ? null : value.Replace(":", "").Trim(); }
}
public string Name
{
get { return name; }
set { name = string.IsNullOrWhiteSpace(value) ? null : value.Trim(); }
}
public string Number
{
get { return number; }
set { number = string.IsNullOrWhiteSpace(value) ? null : value.Trim(); }
}
public bool IsValid
{
get { return isValid; }
}
public DateTime DateAdded
{
get { return dateAdded; }
}
}
some methods are suppressed
In order to be serializable, a class must have public setters on its properties. That's the difference between classes A and B, and the reason why A won't serialize.
Probably :)
I think the problem may be with the Customer class. Maybe it is private or something. Try checking it out.

Is it worthwhile to strongly-type datarows?

I have a datarow that I pass around and do things with, and would like to strongly type it, but don't need to strongly-type the table itself.
Is there a tool that will autogenerate a strongly-typed row with isnull methods and such?
In my opinion is is worthwhile to create a strongly-typed class for ADO data types. There are two ways you can do this:
Hand-code a subclass of DataRow or whatever that encapsulates the behavior you want.
Write an XSD file of your data and let Visual Studio construct strongly-typed classes.
The advantage of the first method is that it provides a custom API exposing exactly what you want. The second method is often faster.
It is worthwhile since you could get compile time checking with strongly typed DataRow/DataSet.
The code below (just a sample) shows how I do it. I have a tool that generates all of the classes from Database information, in particular the output of stored procedures. So I have a stored procedure that returns a result set whose fields map to the properties of the PostDtw class below.
The tool (with source) is available on my blog. It also generates DataReaders wrappers in a similar manner. You can get the tool from here
Data Access Layer CodeGen
The "Main" method below shows how you'd use the class. Notice how in the foreach loop you're accessing properties of a class but behind the scenes the property getter is using a DataRow.
The methods "GetPosts1" and "GetPosts2" shows how you'd basically use a DataTable but "convert" it to an
IEnumerable<PostDtw>
. GetPosts1 essentially uses the same instance, while GetPosts2 creates a new instance for each row.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
namespace ConsoleApplication5
{
class Program
{
static void Main(string[] args)
{
var posts = GetPosts1();
foreach (var post in posts)
{
Console.WriteLine(post.PostId);
Console.WriteLine(post.PostTitle);
Console.WriteLine(post.PostSlug);
Console.WriteLine(post.PostDate);
}
}
static IEnumerable<PostDtw> GetPosts1()
{
DataTable postsDt = GetPostsDataTable();
PostDtw postDtw = new PostDtw();
foreach(DataRow row in postsDt.Rows)
{
postDtw.DataRow = row;
yield return postDtw;
}
}
static IEnumerable<PostDtw> GetPosts2()
{
DataTable postsDt = GetPostsDataTable();
foreach (DataRow row in postsDt.Rows)
yield return new PostDtw(row);
}
static DataTable GetPostsDataTable()
{
throw new NotImplementedException();
}
}
/// <summary>
///This is the Base Class for all DataTable Wrappers
/// </summary>
public class BaseDataTableWrapper
{
public DataRow DataRow { get; set; }
public BaseDataTableWrapper()
{
}
public BaseDataTableWrapper(DataRow row)
: this()
{
DataRow = row;
}
}
#region [GetPost]
/// <summary>
///This class is a wrapper around a DataTable,
///Associated with the stored procedure - GetPost
///This class provides a strongly typed interface to access data from the DataTable
///containing the result of the given stored procedure.
/// </summary>
public sealed class PostDtw : BaseDataTableWrapper
{
public Int32 PostId { get { return (Int32)DataRow[0]; } set { DataRow[0] = value; } }
public DateTime PostDate { get { return (DateTime)DataRow[1]; } set { DataRow[1] = value; } }
public String PostSlug { get { return (String)DataRow[2]; } set { DataRow[2] = value; } }
public Int32 UserId { get { return (Int32)DataRow[3]; } set { DataRow[3] = value; } }
public String PostTitle { get { return (String)DataRow[4]; } set { DataRow[4] = value; } }
public String PostText { get { return (String)DataRow[5]; } set { DataRow[5] = value; } }
public Boolean PostIsPublished { get { return (Boolean)DataRow[6]; } set { DataRow[6] = value; } }
public Boolean PostIsPublic { get { return (Boolean)DataRow[7]; } set { DataRow[7] = value; } }
public String PostTitleImg { get { if (DataRow[8] != DBNull.Value) return (String)DataRow[8]; else return default(String); } set { DataRow[8] = value; } }
public PostDtw()
: base()
{
}
public PostDtw(DataRow row)
: base(row)
{
}
}
#endregion [GetPost]
}

Categories