Getting the parameter value on a callback - c#

I have a very simple callback class that looks like this
class ActivityCallbacks
{
public class ActivityCallback : Java.Lang.Object, ICallbacks
{
Action<JSONObject> onSuccess;
Action<JSONObject> onFail;
public ActivityCallback(Action<JSONObject> success, Action<JSONObject> fail = null)
{
onFail = fail;
onSuccess = success;
}
public void FailCallback(JSONObject p0)
{
onFail?.Invoke(p0);
}
public void SuccessCallback(JSONObject p0)
{
onSuccess?.Invoke(p0);
}
}
}
The callback works fine if I use something like
someMethod(foo, new ActivityCallbacks.ActivityCallback(success=>...));#
This is fine, however there are occasions where I need to be able to use the value the callback is going to receive.
Currently I'm using this (which is incorrect)
someClass.SendFile(file, new ActivityCallbacks.ActivityCallback((r) =>
{
success =>
{
try
{
var newmessage = new ChatroomChatMessages(r.GetString("id"), r.GetString("original_file"), Utils.convertTimestampToDate(Java.Lang.JavaSystem.CurrentTimeMillis()), "Me :", true, "16", Constants.MyId, chatroomId);
addMessage(newmessage);
}
catch (Exception e)
{
//e.printStackTrace();
}
},fail => System.Console.WriteLine("failed to send")
}));
By the looks of the error generated, a semicolon is expected at the final success brace. However, this gives me an assignment error.
Am I approaching this the right way to obtain the value of the parameter the callback is expecting?

You need using success.GetString("id") in your try, because try is inner method of success action, r is be passed to success, you can only access sucess in try.

Related

How to exit method from sub-method without throwing exception

I have the following code, but I am not sure what is the right pattern to exit the Execute() method.
The code is working, but the Execute() method is too large.
public void Execute()
{
// load datatable from excel
DataTable data = new();
try
{
data = ExcelReader.ToDataTable(_meta.FullPath, new() { SheetName = _sheetName });
}
// these errors are fine, but the dataset is not relevant and we want exit the execution
catch (ArgumentOutOfRangeException e)
{
if (e.Message.Contains("HeaderRowIndex")) return;
}
catch (ArgumentNullException e)
{
if (e.Message.Contains("Parameter 'sheet'")) return;
}
// execute logic on dataset
// ..
}
I would like to move the load data part of the code into separate method like this, but then I don't know how to end the execution.
public void Execute()
{
// load data
DataTable data = new();
LoadData();
// execute logic on dataset
// ...
}
private DataTable LoadData()
{
try
{
data = ExcelReader.ToDataTable(_meta.FullPath, new() { SheetName = _sheetName });
}
// these errors are fine, but the dataset is not relevant and we want exit the execution => but how?
catch (ArgumentOutOfRangeException e)
{
if (e.Message.Contains("HeaderRowIndex")) return; // will return to Execute() method, but not exit it.
}
catch (ArgumentNullException e)
{
if (e.Message.Contains("Parameter 'sheet'")) return; // will return to Execute() method, but not exit it.
}
}
I think this is very common issue, so what is the recommended way to handle this requirement? Should I create some returning object from the LoadData method, for example
class LoadDataResult
{
public DataTable data {get; set};
public bool IsRelevant {get; set};
}
dataResult = LoadData()
if (!dataResult.IsRelevant) return;
or it is an overkill and easier solution exist (to not populate program with these result objects)?
You can return data in the output parameter and return result of data loading as a primary method output (true for successful load, false for error that is fine):
private bool TryLoadData(out DataTable data)
{
data = null;
try
{
data = ExcelReader.ToDataTable(
_meta.FullPath, new() { SheetName = _sheetName });
return true; // loading succeeded
}
catch (ArgumentOutOfRangeException e)
when (e.Message.Contains("HeaderRowIndex"))
{
// loading failed, continue to Execute method
return false;
}
catch (ArgumentNullException e)
when (e.Message.Contains("Parameter 'sheet'"))
{
// loading failed, continue to Execute method
return false;
}
// otherwise exception propagates to Execute method
}
Usage:
public void Execute()
{
if (TryLoadData(out var data)
{
// execute logic on dataset
}
else
{
// error, but not exception
}
}
I would think about what you are trying to return. In your catch's you can log the error but you don't need to return. All code will flow back to the previous method that called it regardless if it returns or not. You only need to return if you need to pass a value back up to the previous calling method. Otherwise, you can just leave it be!

Error getting value from ... with JSon exception and nullException

this is a pretty tough problem I got here, I don't get anything to it, I'll try to be as clear as possible
I'm working on a project which takes datas in a database and create Json files from it, here's the method that throws the Exception :
public async Task<int> RecupInters(List<string> fileExist)
{
List<JsonFile> ljf = (await myservice.getJsonFilesAsync(Switcher.pageSwitcher.currentUser, fileExist.ToArray())).ToList();
if (ljf.Count > 0)
{
float percentPerFile = 50 / ljf.Count;
string jsonFolder = Data.HelperDirectory.getFolderDocumentAndCreate("JSON");
float percent = 0.0f;
foreach (JsonFile jf in ljf)
{
this.changeValues("Récupération de nouveaux rapports", percent, "Sauvegarde des fichiers d'interventions");
File.WriteAllText(jsonFolder + jf.Name, jf.Content);
percent = percent + percentPerFile;
}
}
return ljf.Count;
}
It says "Error getting value from demandeAideFilledAndItsMine" and throws a JsonSerialization exception and a nullReferenceException. demandeAidefilledAndItsMine is a property of the FichePreDiag class :
public bool demandeAideFilledAndItsMine { get { return (this.NomDemandeAide != null && isMine()); } }
(here is the IsMine method if you want)
public bool isMine()
{
if (!String.IsNullOrEmpty(this.NomDemandeAide))
{
return this.NomDemandeAide.Equals(DAL.getUserByUsername(Environment.UserName).fullName);
}
else
return false;
}
And the FichePreDiag class is a DB Object generated by EntityFramework.
Anyway, actually the Exception is thrown when it calls the method getJsonFilesAsync so I digged deep into it, it comes from here :
public System.Threading.Tasks.Task<DAO.JsonFile[]> getJsonFilesAsync(DAO.User u, string[] fileExist) {
return base.Channel.getJsonFilesAsync(u, fileExist);
}
This method belongs to a partial class and calls the method of the same name in a reference :
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IService1/getJsonFiles", ReplyAction="http://tempuri.org/IService1/getJsonFilesResponse")]
System.Threading.Tasks.Task<DAO.JsonFile[]> getJsonFilesAsync(DAO.User u, string[] fileExist);
And I can't get deeper. I'm soooo confused right now, I need help.
Thanks for your time

Get All TurnBased Matches Info from GooglePlayServices, Unity Plugin

I'm using the TicTacToss code as a basis for a turn based game on android in Unity, using this : https://github.com/playgameservices/play-games-plugin-for-unity
Everything is working great, but there's no functionality exposed to return a list of games the current user is engaged in, active and completed. I need this for the main UI, so I can show the user what games they are playing, against whom etc. Without, this API seems pretty lacking.
Has anyone been able to get this going? Seems to me that the functionality might be there, as there is a function called GetAllTurnbasedMatches(), but my C# isn't strong enough to understand how it works. (see in https://github.com/playgameservices/play-games-plugin-for-unity/blob/master/source/PluginDev/Assets/GooglePlayGames/Platforms/Native/PInvoke/TurnBasedManager.cs)
(more info # https://github.com/playgameservices/play-games-plugin-for-unity/issues/414)
I managed to get this working back adding the following to NativeTurnBasedMultiplayerClient.cs:
public void GetAllTBMatches(Action<TurnBasedMatch, TurnBasedMatch.MatchTurnStatus> callback)
{
mTurnBasedManager.GetAllTurnbasedMatches(allMatches =>
{
foreach (var match in allMatches.MatchesMyTurn())
{
var converted = match.AsTurnBasedMatch(mNativeClient.GetUserId());
Logger.d("MY turn : Passing converted match to user callback:" + converted);
callback(converted, TurnBasedMatch.MatchTurnStatus.MyTurn);
}
foreach (var match in allMatches.MatchesTheirTurn())
{
var converted = match.AsTurnBasedMatch(mNativeClient.GetUserId());
Logger.d("Their Turn : Passing converted match to user callback:" + converted);
callback(converted, TurnBasedMatch.MatchTurnStatus.TheirTurn);
}
foreach (var match in allMatches.MatchesCompleted())
{
var converted = match.AsTurnBasedMatch(mNativeClient.GetUserId());
Logger.d("Completed : Passing converted match to user callback:" + converted);
callback(converted, TurnBasedMatch.MatchTurnStatus.Complete);
}
callback(null, TurnBasedMatch.MatchTurnStatus.Unknown);
});
}
public void GetAllTBInvitations(Action<Invitation> callback)
{
mTurnBasedManager.GetAllTurnbasedMatches(allMatches =>
{
foreach (var invitation in allMatches.Invitations())
{
var converted = invitation.AsInvitation();
Logger.d("Passing converted invitation to user callback:" + converted);
callback(converted);
}
callback(null);
});
}
You also need to edit the following in TurnBasedManager.cs
internal class TurnBasedMatchesResponse : BaseReferenceHolder {
internal TurnBasedMatchesResponse(IntPtr selfPointer) : base(selfPointer) {
}
protected override void CallDispose(HandleRef selfPointer) {
C.TurnBasedMultiplayerManager_TurnBasedMatchesResponse_Dispose(SelfPtr());
}
internal CommonErrorStatus.MultiplayerStatus Status() {
return C.TurnBasedMultiplayerManager_TurnBasedMatchesResponse_GetStatus(SelfPtr());
}
internal IEnumerable<MultiplayerInvitation> Invitations()
{
return PInvokeUtilities.ToEnumerable(
C.TurnBasedMultiplayerManager_TurnBasedMatchesResponse_GetInvitations_Length(SelfPtr()),
index => new MultiplayerInvitation(C.TurnBasedMultiplayerManager_TurnBasedMatchesResponse_GetInvitations_GetElement(SelfPtr(), index)));
}
internal IEnumerable<NativeTurnBasedMatch> MatchesMyTurn()
{
return PInvokeUtilities.ToEnumerable(
C.TurnBasedMultiplayerManager_TurnBasedMatchesResponse_GetMyTurnMatches_Length(SelfPtr()),
index => new NativeTurnBasedMatch(C.TurnBasedMultiplayerManager_TurnBasedMatchesResponse_GetMyTurnMatches_GetElement(SelfPtr(), index)));
}
internal IEnumerable<NativeTurnBasedMatch> MatchesTheirTurn()
{
return PInvokeUtilities.ToEnumerable(
C.TurnBasedMultiplayerManager_TurnBasedMatchesResponse_GetTheirTurnMatches_Length(SelfPtr()),
index => new NativeTurnBasedMatch(C.TurnBasedMultiplayerManager_TurnBasedMatchesResponse_GetTheirTurnMatches_GetElement(SelfPtr(), index)));
}
internal IEnumerable<NativeTurnBasedMatch> MatchesCompleted()
{
return PInvokeUtilities.ToEnumerable(
C.TurnBasedMultiplayerManager_TurnBasedMatchesResponse_GetCompletedMatches_Length(SelfPtr()),
index => new NativeTurnBasedMatch(C.TurnBasedMultiplayerManager_TurnBasedMatchesResponse_GetCompletedMatches_GetElement(SelfPtr(), index)));
}
internal static TurnBasedMatchesResponse FromPointer(IntPtr pointer)
{
if (PInvokeUtilities.IsNull(pointer)) {
return null;
}
return new TurnBasedMatchesResponse(pointer);
}
}

Validating and parsing url parameters in ASP.NET

I'm maintaining a legacy WebForms application and one of the pages just serves GET requests and works with many query string parameters. This work is done in the code-behind and does a lot of this type of check and casting.
protected override void OnLoad(EventArgs e)
{
string error = string.Empty;
string stringParam = Request.Params["stringParam"];
if (!String.IsNullOrEmpty(stringParam))
{
error = "No parameter";
goto LoadError;
}
Guid? someId = null;
try
{
someId = new Guid(Request.Params["guidParam"]);
}
catch (Exception){}
if (!someId.HasValue)
{
error = "No valid id";
goto LoadError;
}
// parameter checks continue on
LoadError:
log.ErrorFormat("Error loading page: {0}", error);
// display error page
}
I'd like to create a testable class that encapsulates this parsing and validation and moves it out of the code-behind. Can anyone recommend some approaches to this and/or examples?
As a first big step, I'd probably create some form of mapper/translator object, like this:
class SpecificPageRequestMapper
{
public SpecificPageRequest Map(NameValueCollection parameters)
{
var request = new SpecificPageRequest();
string stringParam = parameters["stringParam"];
if (String.IsNullOrEmpty(stringParam))
{
throw new SpecificPageRequestMappingException("No parameter");
}
request.StringParam = stringParam;
// more parameters
...
return request;
}
}
class SpecificPageRequest
{
public string StringParam { get; set; }
// more parameters...
}
Then your OnLoad could look like this:
protected override void OnLoad(EventArgs e)
{
try
{
var requestObject = requestMapper.Map(Request.Params);
stringParam = requestObject.StringParam;
// so on, so forth. Unpack them to the class variables first.
// Eventually, just use the request object everywhere, maybe.
}
catch(SpecificPageRequestMappingException ex)
{
log.ErrorFormat("Error loading page: {0}", ex.Message);
// display error page
}
}
I've omitted the code for the specific exception I created, and assumed you instantiate a mapper somewhere in the page behind.
Testing this new object should be trivial; you set the parameter on the collection passed into Map, then assert that the correct parameter on the request object has the value you expect. You can even test the log messages by checking that it throws exceptions in the right cases.
Assuming that you may have many such pages using such parameter parsing, first create a simple static class having extension methods on NamedValueCollection. For example,
static class Parser
{
public static int? ParseInt(this NamedValueCollection params, string name)
{
var textVal = params[name];
int result = 0;
if (string.IsNullOrEmpty(textVal) || !int.TryParse(textVal, out result))
{
return null;
}
return result;
}
public static bool TryParseInt(this NamedValueCollection params, string name, out int result)
{
result = 0;
var textVal = params[name];
if (string.IsNullOrEmpty(textVal))
return false;
return int.TryParse(textVal, out result);
}
// ...
}
Use it as follows
int someId = -1;
if (!Request.Params.TryParseInt("SomeId", out someId))
{
// error
}
Next step would be writing page specific parser class. For example,
public class MyPageParser
{
public int? SomeId { get; private set; }
/// ...
public IEnumerable<string> Parse(NamedValueCollection params)
{
var errors = new List<string>();
int someId = -1;
if (!params.TryParseInt("SomeId", out someId))
{
errors.Add("Some id not present");
this.SomeId = null;
}
this.SomeId = someId;
// ...
}
}

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