C# return statement determined dynamically - c#

Could someone give me an advice on this issue, so what am I doing is receiving username and password as parameters.
If that is ok (checking credentials) I want to return QR code of it, and if not i want to return string (or boolean or void).
Is their a solution for this? So is it possible not to know return statement?

Create a class whose object will be returned. In that class you can add properties.
class ReturnClass
{
public string QRCode { get; set; }
public bool IsOK { get; set; }
}
public ReturnClass MainMethod()
{
ReturnClass mrc = new ReturnClass();
// Do checks and populate value of ReturnClass
return mrc;
}

Just return an object. Then you can return whatever object you like and check on the requester's side what type was returned.
public object returnObject(string user, string pwd)
{
if(checkCredentials(user,pwd))
return new QRcode(usr,pwd);
else
return false;
}

Related

How can i see if my JSON contains a certain value and then compare it?

var Name = "Resources.myjson.json";
var NameJSON = new System.IO.StreamReader(typeof(Strings).GetTypeInfo().Assembly.GetManifestResourceStream(Name)).ReadToEnd();
var ParsedBrandJSON = Newtonsoft.Json.JsonConvert.DeserializeObject<TheInfo>(NameJSON);
await JsonCS.LoadJson(ParsedBrandJSON);
And on the page:
static public class TheInfoJSON
{
static public TheInfo Data { get; set; }
static public async Task LoadJson(Data JSON)
{
Data = JSON;
}
}
and
public class TheInfo
{
public List<TheName> TheName { get; set; } = new List<TheName>();
}
My json:
{
"TheInfo":[
{
"TheName": ["Martin", "Jonas", "Alex", "Oscar"]
}
]
}
When i now try to compare how can i see if my JSON contains a certain object and then store that as a single TheName? Is it possible to do it in the same cast?
var TheNameDataFromOtherPage = OtherPage.TheName; //Here i gather the name from another page that i will compare with the JSON
//Wrong syntax
bool DoTheyMatch = TheNameDataFromOtherPage == TheInfoJSON.Data.TheName.Contains("Alex");
This is now wrong syntax because i cant compare the value to a bool. How can i get out the data i find and then instead of having TheInfoJSON.Data.TheName.Contains("Alex"); as a bool, back to a single value of TheName containing "Alex" so I can create a bool out of the two values to see if the JSON has it or not.
I tried to add something along the lines like this after the contains(): as TheInfo.TheName but that isnt the correct syntax either.
bool DoTheyMatch = TheInfoJSON.Data.TheName.Contains(TheNameDataFromOtherPage);

ASP.NET WebApi - two possible JSON "return" types?

A little intro
Hello, I'm developing a WebApi Rest Service and currently I'm working on an endpoint which returns different dictionaries (arrays of entities, don't confuse with Dictionary data type) in JSON format. Dictionaries can be retrieved by name: /dictionaries/:dictName. The problem is that items kept in dictionaries can be of two types:
First type of entities
class Item {
public long ID { get; set; }
public string Name { get; set; }
}
Second type of entities - extended item
class ExtendedItem : Item {
public string AdditionalProperty { get; set; } // Let's name it this way just for example
}
The problem
I'd like to avoid sending AdditionalProperty for dictionaries which don't need it.
Current solution
I've developed a simple method in ApiController:
public IHttpActionResult GetDict(string name)
{
try
{
object outDict = null;
switch(name) {
case "simpleDict":
IList<Item> simpleDict = _dataLayer.GetSimpleDict();
// ...
outDict = simpleDict;
break;
case "extDict":
IList<ExtendedItem> extDict = _dataLayer.GetExtDict();
// ...
outDict = extDict;
break;
// ... and a few more dictionaries
}
SomeLogger.SomeLogging(name, outDict);
return Ok(outDict);
}
catch (Exception ex)
{
// Just returning error
return BadRequest(ex.Message);
}
}
Conclusion and questions
Although I managed to find a solution for the problem, I'm not fully satisfied with it. Personally, I'd like to find a simple way to avoid using object data type, however couldn't figure any. And now come the questions:
What would be a better programmatic way of implementing such solution? For me better means solution without using the object type. Is there any easy way to restrict IList to contain either Item or ExtendedItem and no other types?
Or maybe I should completely change the approach to the problem?
Or... Maybe this approach is correct and I'm a bit oversensitive? ;-)
I'll be grateful for any help.
If you declare your outDict variable as a collection instead of object, then you'll be able to assign directly.
IEnumerable<Base> outDict = null;
switch(name) {
case "simpleDict":
IList<Item> simpleDict = _dataLayer.GetSimpleDict();
// ...
outDict = simpleDict;
break;
case "extDict":
IList<ExtendedItem> extDict = _dataLayer.GetExtDict();
// ...
outDict = extDict;
break;
// ... and a few more dictionaries
}
Try use Interface to free up the implementation for ExtendedItem. Using Object for API return can be useful if you need Type dynamic to process things differently before sending back the callback response.
interface Item {
public long ID { get; set; }
public string Name { get; set; }
}
class SimpleItem : Item {
public long ID { get; set; }
public string Name { get; set; }
}
class ComplicateItem: Item {
public long ID { get; set; }
public string Name { get; set; }
public string AdditionalProperty { get; set; }
}
Then in the api controller,
Item outDict;
switch(name) {
case "simpleDict":
var simpleDict = _dataLayer.GetSimpleDict();
// ...
outDict = simpleDict;
break;
case "extDict":
var extDict = _dataLayer.GetExtDict();
// ...
outDict = extDict;
break;
// ... and a few more dictionaries
}
You could just return in the switch statement as well:
public IHttpActionResult GetDict(string name)
{
try
{
switch(name) {
case "simpleDict":
return Ok(_dataLayer.GetSimpleDict());
case "extDict":
return Ok(_dataLayer.GetExtDict());
}
SomeLogger.SomeLogging(name, outDict);
return Ok(new List<Item>());
}
catch (Exception ex)
{
// Just returning error
return BadRequest(ex.Message);
}
}

Same Remote Validation for 2 different properties in a model

I have 2 properties contractor1 and contractor2 in a model, how can I use a single remote validation for both of them
[Display(Name ="Contractor 1:")]
[Remote("ValidateContractor", "Contracts")]
public string Cntrctr1 {get; set;}
[Display(Name = "Contractor 2:")]
[Remote("ValidateContractor", "Contracts")]`enter code here`
public string Cntrctr2 {get; set;}
Remote Validation function in the Controller
public JsonResult ValidateContractor1(string Cntrctr)
{
var valid = Validations.ValidateContractor(Cntrctr);
if (!valid)
{return Json("Enter correct contractor", JsonRequestBehavior.AllowGet);}
else{return Json(true, JsonRequestBehavior.AllowGet);}
}
public static bool ValidateContractor(string CntrctrNM)
{
bool valid;
using (var entities = new CAATS_Entities())
{
var result = (from t in entities.PS_VENDOR_V
where (t.VNDR_1_NM).Equals(CntrctrNM)
select t).FirstOrDefault();
if (result != null)
{
valid = true;
}
else
{
valid = false;
}
}
return valid;
}
This doesn't work. Can you please help me with this?
When remote validation is called, the querystring key is the name of the field, e.g. in your case /Contracts/ValidateContractor1?Cntrctr1=foo. You need a more dynamic solution.
One way you can do this is to not have any parameters in ValidateContractor1 and just grab the first query string value instead. This isn't tested but should work for you:
public JsonResult ValidateContractor1()
{
// gets the name of the property being validated, e.g. "Cntrctr1"
string fieldName = Request.QueryString.Keys[0];
// gets the value to validate
string Cntrctr = Request.QueryString[fieldName];
// carry on as before
var valid = Validations.ValidateContractor(Cntrctr);
if (!valid)
{return Json("Enter correct contractor", JsonRequestBehavior.AllowGet);}
else{return Json(true, JsonRequestBehavior.AllowGet);}
}
Adding onto Rhumborls answer if you find his method not to work it might be because you're using forms; if this is the case you need to use the Form attribute instead of the QueryString as so.
public JsonResult ValidateContractor()
{
// gets the name of the property being validated, e.g. "Cntrctr1"
string fieldName = Request.Form.Keys[0];
// gets the value to validate
string Cntrctr = Request.Form[fieldName];
// carry on as before
var valid = Validations.ValidateContractor(Cntrctr);
if (!valid)
{return Json("Enter correct contractor", JsonRequestBehavior.AllowGet);}
else{return Json(true, JsonRequestBehavior.AllowGet);}
}

c# What is wrong with my loop

I have a ChaseSelection class which i use in casting my dropdown list objects,
now i am trying to put the the values from the database as a default value in the drop down list, but it does not seem to work, can anyone help? I dont even think my loop runs. Here is my chaseselection class, and also put in the loop below: Thanks
public class ChaseSelectionItems
{
public string code { get; set; }
public string text { get; set; }
public ChaseSelectionItems(string code, string text)
{
this.code = code;
this.text = text;
}
public override string ToString()
{
return this.text;
}
}
foreach (ChaseSelectionItems items in drpdwnChaseSecSelection.Items)
{
if (items.code == _Row.xcs_View)
{
drpdwnChaseSecSelection.SelectedValue = items.text;
}
}
It is not entirely clear how you configured the listbox but most likely you did not configure ValueMember correctly. The following might fix that:
foreach (ChaseSelectionItems items in drpdwnChaseSecSelection.Items)
{
if (items.code == _Row.xcs_View)
{
// drpdwnChaseSecSelection.SelectedValue = items.text;
drpdwnChaseSecSelection.SelectedItem = items;
}
}

Reusing Common Functions With Best Correct Approach 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

Categories