Reusing Common Functions With Best Correct Approach c# - c#

I need a Login function(login is just an example, any other frequently used method can be fine) which takes email and password as parameter and asks DB if there is such a user. If yes, it has to return customer_id(int), if no, it will return the message why login could not happen(ex:no such an email address).
I also do not wanna rewrite the login function everytime. I want to write it once in a common project which I can use in my every project and reuse it. But i am trying to find out the best practice for this. So far, i thought something like below, but the problem for me is that i cannot return customerID which i will get in codebehind in my projects(any other project) and open a session variable with it. I only can return strings in below structure. I also thought returning a Dic, but this also is wrong I guess because if bool(key) happens to be true, customerID is not a string(value). Can you help me please learning the correct way of using common functions with no need to think the returning messages and variables twice? Thanks a lot
public class UserFunctions
{
private enum Info
{
//thought of returning codes??
LoginSuccess = 401,
NoMatchPasswordEmail = 402,
InvalidEmail = 403,
};
public string TryLogin(string email, string password)
{
bool isValidEmail = Validation.ValidEmail(email);
if (isValidEmail == false)
{
return Result(Info.InvalidEmail);
// returning a message here
}
Customers customer = new Customers();
customer.email = email;
customer.password = password;
DataTable dtCustomer = customer.SelectExisting();
if (dtCustomer.Rows.Count > 0)
{
int customerID = int.Parse(dtCustomer.Rows[0]["CustomerID"].ToString());
return Result(Info.LoginSuccess);
// Here I cant return the customerID. I dont wanna open a session here because this function has no such a job. Its other projects button events job I guess
}
else
{
return Result(Info.NoMatchPasswordEmail);
}
}
private string Result(Info input)
{
switch (input)
{
case Info.NoMatchPasswordEmail:
return "Email ve şifre bilgisi uyuşmamaktadır";
case Info.InvalidEmail:
return "Geçerli bir email adresi girmelisiniz";
case Info.LoginSuccess:
return "Başarılı Login";
}
return "";
}
}

You may want to consider returning an instance of a custom class.
public class LoginResult
{
public Info Result { get; set; }
public int CustomerId { get; set;}
}
Modify your TryLogin method to return an instance of LoginResult.
Base your application flow on the result:
var loginResult = TryLogin(..., ...);
switch (loginResult.Result)
{
case Info.LoginSuccess:
var customerId = loginResult.CustomerId;
//do your duty
break;
case Info.NoMatchPasswordEmail:
//Yell at them
break;
...
}

You could try Creating an event and then the calling code can register to the event before attempting to login.
For example:
public class UserFunctions
{
private enum Info
{
LoginSuccess = 401,
NoMatchPasswordEmail = 402,
InvalidEmail = 403,
};
public delegate void LoginAttemptArgs(object sender, Info result, int CustomerID);//Define the delegate paramters to pass to the objects registered to the event.
public event LoginAttemptArgs LoginAttempt;//The event name and what delegate to use.
public void TryLogin(string email, string password)
{
bool isValidEmail = Validation.ValidEmail(email);
if (isValidEmail == false)
{
OnLoginAttempt(Info.InvalidEmail, -1);
}
Customers customer = new Customers();
customer.email = email;
customer.password = password;
DataTable dtCustomer = customer.SelectExisting();
if (dtCustomer.Rows.Count > 0)
{
int customerID = int.Parse(dtCustomer.Rows[0]["CustomerID"].ToString());
OnLoginAttempt(Info.LoginSuccess, customerID);
}
else
{
OnLoginAttempt(Info.NoMatchPasswordEmail, -1);
}
}
private void OnLoginAttempt(Info info, int CustomerID)
{
if (LoginAttempt != null)//If something has registered to this event
LoginAttempt(this, info, CustomerID);
}
}
I wouldn't compile a string to return, I would return the enum result and let the calling code do what it likes with the result. reading an enum is much quicker than parsing returned string.
Edit: Typos and i missed an event call... .Twice

Related

Passing variable from command handler

I have a following method in my command handler that gets variables from another method,im trying to pass those variable into the CreateUser(NewAccount); method but it always comes back as null
public async Task ExecuteAsync(CreateUserAccountCommand command)
{
var result = await _client.CreateUser(GetAccountFrom(command)); // so this line gets the variables from GetAccountFrom(command)
_httpContextAccessor.HttpContext.Items["CreateUserAccountCommand"] = result;
}
private Account GetAccountFrom(CreateUserAccountCommand command)
{
var NewAccount = new Account();
NewAccount.FirstName = command.FirstName;
NewAccount.LastName = command.LastName;
return NewAccount()
}
however when i call CreateUser to pass in the variables into NewAccount thats coming from GetAccountFrom(command) it passes it in as a null
public System.Threading.Tasks.Task<Account> CreateUser(Account NewAccount,)
{
return base.Channel.CreateUser(NewAccount);
}
What am i doing wrong?
You are creating a new instance of NewAccount in your return statement.
private Account GetAccountFrom(CreateUserAccountCommand command)
{
var newAccount = new Account();
newAccount.FirstName = command.FirstName;
newAccount.LastName = command.LastName;
return newAccount; // <- Return the variable
}
You are creating object with new keyword. All you need to do is to return this object from your method with simple call:
return NewAccount;
The way you do it now is that you are returning result of NewAccount() method (whatever it is, apparently null), which is not what you want.
Also you might want to inspect why NewAccount() returns always null.
Your code has many anti patterns but it seems like you have a method somewhere in the base newAccount(); This is why inheritance should be avoided (for beginners and mids)
also the convention for private local variables lowercase.. as to NOT CONFUSE yourself.
private Account GetAccountFrom(CreateUserAccountCommand command)
{
var newAccount = new Account();
newAccount.FirstName = command.FirstName;
newAccount.LastName = command.LastName;
return newAccount;
}
or to completely avoid confusion just do this
private Account GetAccountFrom(CreateUserAccountCommand command)
{
return new Account{
FirstName = command.FirstName,
LastName = command.LastName,
}
}
But to avoid anti-patterns and spaghetti code you should really make an extension method which is much more S.O.L.I.D !
namespace you.company
{
public static CommandExtensions{
public static Account GetAccountFrom(this CreateUserAccountCommand command)
{
return new Account
{
FirstName = command.FirstName,
LastName = command.LastName,
};
}
}

Where's the best place for validation... constructor or leave to client to call?

This is really a generic (and probably a more subjective too) question. I have some classes where I use an interface to define a standard approach to validating the object state. When I did this, I got to scratching my head... is it best to
1.) allow the constructor (or initializing method) to silently filter out the errant information automatically or...
2.) allow the client to instantiate the object however and let the client also call the interface's IsValid property or Validate() method before moving forward?
Basically one approach is silent but could be misleading in that the client may not be aware that certain pieces of information were filtered away due to it not meeting the validation criteria. The other approach then would be more straight forward, but also adds a step or two? What's typical here?
Okay, after a long day of trying to keep up with some other things, I finally did come up with an example. Please for me for it as it's not ideal and by no means something wonderful, but hopefully should serve well enough to get the point across. My current project is just too complicated to put something simple out for this, so I made something up... and trust me... totally made up.
Alright, the objects in the example are this:
Client: representing client-side code (Console App btw)
IValidationInfo: This is the actual interface I'm using in my current project. It allows me to create a validation framework for the "back-end" objects not necessarily intended for the Client to use since the business logic could be complicated enough. This also allowed me to separate validation code and call as-needed for the business logic.
OrderManager: This is an object the client-side code can use to manage their orders. It's client-friendly so-to-speak.
OrderSpecification: This is an object the client-side code can use to request an order. But if the business logic doesn't work out, an exception can be raised (or if necessary the order not added and exceptions ignored...) In my real-world example I actually have an object that's not quite so black-and-white as to which side of this fence it goes... thus my original question when I realized I could push validation request (calling IsValid or Validate()) to the cilent.
CustomerDescription: represents customers to which I've classified (pretending to have been read from a DB.
Product: Represents a particular product which is classified also.
OrderDescription: Represents the official order request.The business rule is that the Customer cannot order anything to which they've not been classified (I know.. that's not very real-world, but it gave me something to work with...)
Ok... I just realized I can't attach a file here, so here's the code. I apologize for it's lengthy appearance. That was the best I could do to create a client-friendly front-end and business logic back-end using my Validation interface:
public class Client
{
static OrderManager orderMgr = new OrderManager();
static void Main(string[] args)
{
//Request a new order
//Note: Only the OrderManager and OrderSpecification are used by the Client as to keep the
// Client from having to know and understand the framework beyond that point.
OrderSpecification orderSpec = new OrderSpecification("Customer1", new Product(IndustryCategory.FoodServices, "Vending Items"));
orderMgr.SubmitOrderRequest(orderSpec);
Console.WriteLine("The OrderManager has {0} items for {1} customers.", orderMgr.ProductCount, orderMgr.CustomerCount);
//Now add a second item proving that the business logic to add for an existing customer works
Console.WriteLine("Adding another valid item for the same customer.");
orderSpec = new OrderSpecification("Customer1", new Product(IndustryCategory.FoodServices, "Sodas"));
orderMgr.SubmitOrderRequest(orderSpec);
Console.WriteLine("The OrderManager now has {0} items for {1} customers.", orderMgr.ProductCount, orderMgr.CustomerCount);
Console.WriteLine("Adding a new valid order for a new customer.");
orderSpec = new OrderSpecification("Customer2", new Product(IndustryCategory.Residential, "Magazines"));
orderMgr.SubmitOrderRequest(orderSpec);
Console.WriteLine("The OrderManager now has {0} items for {1} customers.", orderMgr.ProductCount, orderMgr.CustomerCount);
Console.WriteLine("Adding a invalid one will not work because the customer is not set up to receive these kinds of items. Should get an exception with message...");
try
{
orderSpec = new OrderSpecification("Customer3", new Product(IndustryCategory.Residential, "Magazines"));
orderMgr.SubmitOrderRequest(orderSpec);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.ReadLine();
}
}
public interface IValidationInfo
{
string[] ValidationItems { get; }
bool IsValid { get; }
void Validate();
List<string> GetValidationErrors();
string GetValidationError(string itemName);
}
public class OrderManager
{
private List<OrderDescription> _orders = new List<OrderDescription>();
public List<OrderDescription> Orders
{
get { return new List<OrderDescription>(_orders); }
private set { _orders = value; }
}
public int ProductCount
{
get
{
int itemCount = 0;
this.Orders.ForEach(o => itemCount += o.Products.Count);
return itemCount;
}
}
public int CustomerCount
{
get
{
//since there's only one customer per order, just return the number of orders
return this.Orders.Count;
}
}
public void SubmitOrderRequest(OrderSpecification orderSpec)
{
if (orderSpec.IsValid)
{
List<OrderDescription> orders = this.Orders;
//Since the particular customer may already have an order, we might as well add to an existing
OrderDescription existingOrder = orders.FirstOrDefault(o => string.Compare(orderSpec.Order.Customer.Name, o.Customer.Name, true) == 0) as OrderDescription;
if (existingOrder != null)
{
List<Product> existingProducts = orderSpec.Order.Products;
orderSpec.Order.Products.ForEach(p => existingOrder.AddProduct(p));
}
else
{
orders.Add(orderSpec.Order);
}
this.Orders = orders;
}
else
orderSpec.Validate(); //Let the OrderSpecification pass the business logic validation down the chain
}
}
public enum IndustryCategory
{
Residential,
Textile,
FoodServices,
Something
}
public class OrderSpecification : IValidationInfo
{
public OrderDescription Order { get; private set; }
public OrderSpecification(string customerName, Product product)
{
//Should use a method in the class to search and retrieve Customer... pretending here
CustomerDescription customer = null;
switch (customerName)
{
case "Customer1":
customer = new CustomerDescription() { Name = customerName, Category = IndustryCategory.FoodServices };
break;
case "Customer2":
customer = new CustomerDescription() { Name = customerName, Category = IndustryCategory.Residential };
break;
case "Customer3":
customer = new CustomerDescription() { Name = customerName, Category = IndustryCategory.Textile };
break;
}
//Create an OrderDescription to potentially represent the order... valid or not since this is
//a specification being used to request the order
this.Order = new OrderDescription(new List<Product>() { product }, customer);
}
#region IValidationInfo Members
private readonly string[] _validationItems =
{
"OrderDescription"
};
public string[] ValidationItems
{
get { return _validationItems; }
}
public bool IsValid
{
get
{
List<string> validationErrors = GetValidationErrors();
if (validationErrors != null && validationErrors.Count > 0)
return false;
else
return true;
}
}
public void Validate()
{
List<string> errorMessages = GetValidationErrors();
if (errorMessages != null && errorMessages.Count > 0)
{
StringBuilder errorMessageReported = new StringBuilder();
errorMessages.ForEach(em => errorMessageReported.AppendLine(em));
throw new Exception(errorMessageReported.ToString());
}
}
public List<string> GetValidationErrors()
{
List<string> errorMessages = new List<string>();
foreach (string item in this.ValidationItems)
{
string errorMessage = GetValidationError(item);
if (!string.IsNullOrEmpty(errorMessage))
errorMessages.Add(errorMessage);
}
return errorMessages;
}
public string GetValidationError(string itemName)
{
switch (itemName)
{
case "OrderDescription":
return ValidateOrderDescription();
default:
return "Invalid item name.";
}
}
#endregion
private string ValidateOrderDescription()
{
string errorMessage = string.Empty;
if (this.Order == null)
errorMessage = "Order was not instantiated.";
else
{
if (!this.Order.IsValid)
{
List<string> orderErrors = this.Order.GetValidationErrors();
orderErrors.ForEach(ce => errorMessage += "\n" + ce);
}
}
return errorMessage;
}
}
public class CustomerDescription : IValidationInfo
{
public string Name { get; set; }
public string Street { get; set; }
public string City { get; set; }
public string State { get; set; }
public int ZipCode { get; set; }
public IndustryCategory Category { get; set; }
#region IValidationInfo Members
private readonly string[] _validationItems =
{
"Name",
"Street",
"City",
"State",
"ZipCode",
"Category"
};
public string[] ValidationItems
{
get { return _validationItems; }
}
public bool IsValid
{
get
{
List<string> validationErrors = GetValidationErrors();
if (validationErrors != null && validationErrors.Count > 0)
return false;
else
return true;
}
}
public void Validate()
{
List<string> errorMessages = GetValidationErrors();
if (errorMessages != null && errorMessages.Count > 0)
{
StringBuilder errorMessageReported = new StringBuilder();
errorMessages.ForEach(em => errorMessageReported.AppendLine(em));
throw new Exception(errorMessageReported.ToString());
}
}
public List<string> GetValidationErrors()
{
List<string> errorMessages = new List<string>();
foreach (string item in this.ValidationItems)
{
string errorMessage = GetValidationError(item);
if (!string.IsNullOrEmpty(errorMessage))
errorMessages.Add(errorMessage);
}
return errorMessages;
}
public string GetValidationError(string itemName)
{
//Validation methods should be called here... pretending nothings wrong for sake of discussion & simplicity
switch (itemName)
{
case "Name":
return string.Empty;
case "Street":
return string.Empty;
case "City":
return string.Empty;
case "State":
return string.Empty;
case "ZipCode":
return string.Empty;
case "Category":
return string.Empty;
default:
return "Invalid item name.";
}
}
#endregion
}
public class Product
{
public IndustryCategory Category { get; private set; }
public string Description { get; private set; }
public Product(IndustryCategory category, string description)
{
this.Category = category;
this.Description = description;
}
}
public class OrderDescription : IValidationInfo
{
public CustomerDescription Customer { get; private set; }
private List<Product> _products = new List<Product>();
public List<Product> Products
{
get { return new List<Product>(_products); }
private set { _products = value; }
}
public OrderDescription(List<Product> products, CustomerDescription customer)
{
this.Products = products;
this.Customer = customer;
}
public void PlaceOrder()
{
//If order valid, place
if (this.IsValid)
{
//Do stuff to place order
}
else
Validate(); //cause the exceptions to be raised with the validate because business rules were broken
}
public void AddProduct(Product product)
{
List<Product> productsToEvaluate = this.Products;
//some special read, validation, quantity check, pre-existing, etc here
// doing other stuff...
productsToEvaluate.Add(product);
this.Products = productsToEvaluate;
}
#region IValidationInfo Members
private readonly string[] _validationItems =
{
"Customer",
"Products"
};
public string[] ValidationItems
{
get { return _validationItems; }
}
public bool IsValid
{
get
{
List<string> validationErrors = GetValidationErrors();
if (validationErrors != null && validationErrors.Count > 0)
return false;
else
return true;
}
}
public void Validate()
{
List<string> errorMessages = GetValidationErrors();
if (errorMessages != null && errorMessages.Count > 0)
{
StringBuilder errorMessageReported = new StringBuilder();
errorMessages.ForEach(em => errorMessageReported.AppendLine(em));
throw new Exception(errorMessageReported.ToString());
}
}
public List<string> GetValidationErrors()
{
List<string> errorMessages = new List<string>();
foreach (string item in this.ValidationItems)
{
string errorMessage = GetValidationError(item);
if (!string.IsNullOrEmpty(errorMessage))
errorMessages.Add(errorMessage);
}
return errorMessages;
}
public string GetValidationError(string itemName)
{
switch (itemName)
{
case "Customer":
return ValidateCustomer();
case "Products":
return ValidateProducts();
default:
return "Invalid item name.";
}
}
#endregion
#region Validation Methods
private string ValidateCustomer()
{
string errorMessage = string.Empty;
if (this.Customer == null)
errorMessage = "CustomerDescription is missing a valid value.";
else
{
if (!this.Customer.IsValid)
{
List<string> customerErrors = this.Customer.GetValidationErrors();
customerErrors.ForEach(ce => errorMessage += "\n" + ce);
}
}
return errorMessage;
}
private string ValidateProducts()
{
string errorMessage = string.Empty;
if (this.Products == null || this.Products.Count <= 0)
errorMessage = "Invalid Order. Missing Products.";
else
{
foreach (Product product in this.Products)
{
if (product.Category != Customer.Category)
{
errorMessage += string.Format("\nThe Product, {0}, category does not match the required Customer category for {1}", product.Description, Customer.Name);
}
}
}
return errorMessage;
}
#endregion
}
Any reason you wouldn't want the constructor to noisily throw an exception if the information is valid? It's best to avoid ever creating an object in an invalid state, in my experience.
It's completely depends on the client. There's a trade-off as you already mentioned. By default approach number 1 is my favorite. Creating smart classes with good encapsulation and hiding details from client. The level of smartness depends who is going to use the object. If client is business aware you can reveal details according to the level of this awareness. This is a dichotomy and should not be treated as black or white.
Well if I correctly understood, there are basically two question - whether you should fail right away or later and whether you should omit/assume certain information.
1) I always prefer failing as soon as possible - good example is failing at compile time vs failing at run time - you always want to fail at compile time. So if something is wrong with the state of some object, as Jon said - throw exception right away as loudly as you can and deal with it - do not introduce additional complexity down the road as you'll be heading for if/elseif/elseif/elseif/else mumbo jumbo.
2) When it comes to user input, if you are in position to simply filter out errors automatically - just do it. For example, I almost never ask users for country - if I really need it, I automatically detect it from IP and display it in the form. It's way easier if user just needs to confirm/change the data - and I don't need to deal with null situation.
Now, in case we are talking about the data generated by code during some processing - for me situation is drastically different - I always want to know an much as possible (for easier debugging down the road) and ideally you never should destroy any piece of information.
To wrap up, in your case I would recommend that you keep IsValid as simple yes/no (not yes/no/maybe/kindaok/etc). If you can fix some problems automatically - do it, but consider that they keep object in IsValid yes. For everything else, you throw exception and go to IsValid=no.

How to string a value across two functions?

I am new to the world of c# so go easy on me! :]
I am not even sure I am using the correct terminology. I figured this would be an easy google search but I am afraid I may not be wording this correctly.
I am gathering data from a database. Like so:
SqlConnection mySqlConnection = new SqlConnection(strings.settings.connectionString);
SqlCommand mySqlCommand = mySqlConnection.CreateCommand();
mySqlCommand.CommandText = "SELECT FNAME, LNAME, ZIPCODE FROM database WHERE ID = #ID";
mySqlCommand.Parameters.Add("#ID", SqlDbType.Char).Value = txtID.Text;
mySqlConnection.Open();
SqlDataReader mySqlDataReader = mySqlCommand.ExecuteReader(CommandBehavior.SingleRow);
if (mySqlDataReader.HasRows == false)
{
throw new Exception();
}
if (mySqlDataReader.Read())
{
txtFname.Text = mySqlDataReader[0].ToString();
txtLname.Text = mySqlDataReader[1].ToString();
lblZipcode.Text = mySqlDataReader[2].ToString();
//need help on stringing the value ZIPCODE above.
}
My question is: How can I string the Zipcode value to another function? I have been trying things like
string Zipcode = mySqlDataReader[2].ToString();
but I get stuck trying to figure out how to string that value so I can use it in a different function like so:
private void GetZipData()
{
//Get that value
}
Any help or a point in the right direction would be greatly appreciated!
Either I've misunderstood the question or your approach is fundamentally wrong. Firstly, your GetZipData() is returning void so is a subroutine, not a function. Even better, refer to it as a method as that covers both subs and funcs...
You can pass parameters in like this...
public void GetZipData(String SomeInputString) {
///Do something
}
and you can return things from a function like this...
public String GetZipData() {
return "Some String";
}
What I suspect you want to do is get either a single Zip code or a list of zip codes from a data reader. Something like...
public String GetZipData(Integer Id) {
//All your MySQL Code here
return mySqlDataReader[2].ToString();
}
then you can simply call it like this...
String TheZipCode = GetZipData(123);
Of course, there are other things you can consider doing too - like creating a class to represent a customer and return that instead of a string - then you can get all the information in one Db trip...
class Person {
String Firstname;
String Lastname;
String ZipCode;
}
public Person GetPersonData(Integer Id) {
//All your MySQL Code here
Person ReturnData = new Person();
ReturnData.Firstname = mySqlDataReader[0].ToString();
ReturnData.Lastname = mySqlDataReader[1].ToString();
ReturnData.ZipCode = mySqlDataReader[2].ToString();
return ReturnData;
}
Then you'd have...
Person person = GetPersonData(12);
//You can now use person.Firstname, person.ZipCode, etc...
Change this method as
private string GetZipData()
{
string Zipcode = mySqlDataReader[2] as String;
return Zipcode;
}
I am not sure what you are trying to achieve. If you want to pass the zip string to antoher method, you can add a string parameter to that method
private void DoSomethingWithZipCode(string zipCode)
{
Console.WriteLine(zipCode);
}
If you want to return antoher value that depends on the zip code, you need a return type as well
private string GetCity(string zipCode)
{
string city = <get city from database>;
return city;
}
Or in your case
private string GetZipData(SqlDataReader dataReader)
{
return dataReader[2].ToString();
}
You would call it like this
lblZipcode.Text = GetZipData(mySqlDataReader);
You can also write an extension method. You must place this method in a static class whose namespace is available where you are using it
public static string ZipData(this SqlDataReader dataReader)
{
return dataReader[2].ToString();
}
You can call it like this
lblZipcode.Text = mySqlDataReader.ZipData();
string Zipcode = mySqlDataReader[2].ToString();
private void GetZipData(string yourInput)
{
//do your stuff with yourInput
}
If your top data access code is in its own method you can 'return' it from there you would then call your data access method from the new value, see below:
return ZipCode
private void GetZipData() {
var stry=DataCode();
}
Regards
Craig

return more than one data type

I query-ing this from entity framework using WCF, and i want to use the data in phone client side, may i know how can i query more than one data type from the WCF function ?
[OperationContract]
string LoginUser(string email, string password);
IService.cs
public string LoginUser(string email, string password)
{
string query = #"SELECT VALUE tblUser FROM MyEntities.tblUsers AS tblUser WHERE tblUser.email = #email AND tblUser.password = #password";
ObjectParameter[] parameters = new ObjectParameter[2];
parameters[0] = new ObjectParameter("email", email);
parameters[1] = new ObjectParameter("password", password);
using (var context = new SteamKingEntities())
{
ObjectQuery<string> results = context.CreateQuery<string>(query, parameters);
foreach (string result in results)
{
if (result != null)
{
return result;
}
}
}
return null;
}
IService.svc.cs
public Login()
{
InitializeComponent();
_serviceClient = new Service1Client();
_serviceClient.LoginUserCompleted += new EventHandler<LoginUserCompletedEventArgs>(_serviceClient_LoginUserCompleted);
}
private void loginBtn_Click(object sender, RoutedEventArgs e)
{
_serviceClient.LoginUserAsync(txtEmail.Text, txtPassword.Password);
}
private void _serviceClient_LoginUserCompleted(object sender, LoginUserCompletedEventArgs e)
{
if (e.Error == null && e.Result != null)
{
MessageBox.Show("Welcome " + e.Result + "!");
}
else
{
MessageBox.Show(e.Error.Message + " Couldn't Login, Please try again =D");
}
}
Login.xaml.cs
I want to return the entire table from Entity Framework and allow me to process one by one in Window Phone side.
I guess i need to do some modification to the IService side but i seriously don't know how because i'm new to phone development and used to Linq to SQL. Can you please guide me on how to make something like type for the return, Please. Thank you.
Update
The error i get There was an error while trying to deserialize parameter http://tempuri.org/:LoginUserResult. Please see InnerException for more details.
i was modified the code into the way stated in WCF Custom Object but i could not deserialize it... i guess the problem came from the WP part, how could i deserialize the result ?
You can use ref or you can use custom-objects
You need to use data contract:
[DataContract]
public class ReturnType
{
[DataMember]
public string Name { get; set; }
[DataMember]
public string Pass { get; set; }
}
in service it would look like this:
[OperationContract]
Entities.ReturnType[] SelectTopUser(int countOfTop);
the return type can be an entity framework type

Is there a way to generically wrap any function call in a try/catch block?

I am writing a bunch of integration tests for a project. I want to call each individual integration point method wrapped in a try/catch block so that when it fails, I get some sort of feedback to display, rather than just crashing the app. I also want to be able to time how long the calls take, and check return values when needed. So, I have an IntegrationResult class with some basic description, result and time elapsed properties:
class IntegrationResult
{
private StopWatch _watch;
public string Description {get;set;}
public string ResultMessage {get;set;}
public bool TestPassed {get;set;}
public string TimeElapsed {get { return _watch == null ? "0" : _watch.Elapsed.TotalMilliseconds.ToString(); } }
public void Start()
{
_watch = StopWatch.StartNew();
}
public void Stop()
{
_watch.Stop();
}
}
The code I keep writing looks like this:
IntegrationResult result = new IntegrationResult();
result.Description = "T-SQL returns expected results";
try
{
result.Start();
SomeIntegrationPoint("potential arguments"); //This is the line being tested
result.Stop();
//do some check that correct data is present
result.TestPassed = true;
result.ResultMessage = "Pulled 10 correct rows";
}
catch(Exception e)
{
result.TestPassed = false;
result.ResultMessage = String.Format("Error: {0}", e.Message);
}
I would really like to be able to just pass the SomeIntegrationPoint method in as an argument and a delegate or something to check the results, but I can't figure out if that's even possible. Are there any frameworks to handle this type of testing, or do you have any suggestions on how I might simplify the code for better reuse? I'm tired of typing this block ;)
(I'm assuming this is C#, as tagged... though the syntax was not in the question.)
You can do this. Just change your result class to include:
class IntegrationResult
{
string Description { get; set; }
string SuccessResultMessage { get; set; }
string FailResultMessage { get; set; }
public IntegrationResult(string desc, string success, string fail)
{
this.Description = desc;
this.SuccessResultMessage = success;
this.FailResultMessage = fail;
}
public bool ExecuteTest(Func<IntegrationResult, bool> test)
{
bool success = true;
try
{
this.Start();
success = test(this);
this.Stop();
this.ResultMessage = success ?
this.SuccessResultMessage :
this.FailResultMessage;
this.TestPassed = true;
}
catch(Exception e)
{
this.TestPassed = false;
this.ResultMessage = String.Format("Error: {0}", e.Message);
success = false;
}
return success;
}
...
You could then change your code for your tests to:
private void myDoTestMethod(string argumentOne, string argumentTwo)
{
IntegrationResult result = new IntegrationResult(
"T-SQL returns expected results",
"Pulled 10 correct rows",
"Wrong number of rows received");
result.Execute( r=>
{
integrationPoint.call(argumentOne, argumentTwo);
//do some check that correct data is present (return false if not)
return true;
});
}
This can easily be extended to include your timings as well.
Have you looked into AOP? PostSharp looks like a nice place to start. There is also an example on exception handling aspects.

Categories