Get data from Mobile Service Table - c#

I want get data from Azure. This is my code:
private async void FindPromotion()
{
MobileServiceCollection<Promotions, Promotions> result;
MobileServiceInvalidOperationException exception = null;
string _place = textInputPlace.Text;
if (_place!= null)
{
try
{
//lista obiektów Category
result = await todoTable2.Where(todoItem => todoItem.Place==_place)
.Select(todoItem => todoItem.Products, todoItem => todoItem.Description)
.ToCollectionAsync();
}
catch (MobileServiceInvalidOperationException ex)
{
exception = ex;
}
if (exception != null)
{
await new MessageDialog(exception.Message, "Can't find items").ShowAsync();
}
else
{
ListItems.ItemsSource = result.Distinct();
}
}
}
I have error:
No overload for method 'Select' takes 2 arguments.
Anybody know? Is another way to get this data?

This is how you can select multiple columns:
result = await todoTable2.Select(todoItem => new { todoItem.Products , todoItem.Description}).ToCollectionAsync();

Related

How to break from the Catch block after throwing BadRequestException using C#

I have a method which needs to break after the BadRequestException() is thrown.
Currently after BadRequestException() is thrown, frontend shows loading bar buffering infinitely.
Please find my code below
public FeSite GetSiteBySiteId(string envCode, string siteId)
{
try
{
envCode.ThrowIfNull();
siteId.ThrowIfNull();
var watch = new Stopwatch();
watch.Start();
FeSite result = this.ExecuteAndParseWebRequestForEnv<FeSite>(envCode, $"sites/{siteId}", HttpMethod.Get);
this.LogService.Info($"FeeDataAcccess - GetSitebySiteId - {watch.ElapsedMilliseconds}ms");
return result;
}
catch (Exception e)
{
this.LogService.Error($"GetSiteBySiteId - {e.Message}");
throw new BadRequestException("Invalid siteId!");
}
}
Below method calls GetSiteBySiteId() method:
public string GetDevicesSerialNumberBySiteId(string envCode, string siteId)
{
var siteSerialNumber = "";
if (siteId != null)
{
var result = this.feeDataAccess.GetSiteBySiteId(envCode, siteId);
List<string> gatewaySiteSNlist = result.Gateways.Select(x => x.SerialNumber).ToList();
foreach (var item in gatewaySiteSNlist)
{
var siteSN = item;
siteSerialNumber += $";{siteSN};";
}
}
return siteSerialNumber;
}
I have tried this code below :
public FeSite GetSiteBySiteId(string envCode, string siteId)
{
do
{
try
{
envCode.ThrowIfNull();
siteId.ThrowIfNull();
var watch = new Stopwatch();
watch.Start();
FeSite result = this.ExecuteAndParseWebRequestForEnv<FeSite>(envCode, $"sites/{siteId}", HttpMethod.Get);
this.LogService.Info($"FeeDataAcccess - GetSitebySiteId - {watch.ElapsedMilliseconds}ms");
return result;
}
catch (Exception e)
{
this.LogService.Error($"GetSiteBySiteId - {e.Message}");
throw new BadRequestException("Invalid siteId!");
}
}
while (false);
{
break;
}
}
But I get error "No enclosing loop out of which to break or continue"
How to fix this? Thanks in advance.
public string GetDevicesSerialNumberBySiteId(string envCode, string siteId)
{
var siteSerialNumber = "";
if (siteId != null)
{
try{
var result = this.feeDataAccess.GetSiteBySiteId(envCode, siteId);
List<string> gatewaySiteSNlist = result.Gateways.Select(x => x.SerialNumber).ToList();
foreach (var item in gatewaySiteSNlist)
{
var siteSN = item;
siteSerialNumber += $";{siteSN};";
}
}catch{
//BadRequestException catch and error handling goes here
}
}
return siteSerialNumber;
}

System.InvalidCastException: 'System.Linq.Expressions.PropertyExpression' to 'System.Linq.Expressions.MethodCallExpression'

I am trying to perform unit tests of a client that returns a task with a list of elements and iterates them, but what I have tried is not working for me.
IEnumerable<ExpenseNote> pendingExpenses = null;
try
{
pendingExpenses = await _expenseNoteService.GetPendingExpenseNotes().ConfigureAwait(false);
}
catch (Exception ex)
{
executionContext.Error($"Step 1-Final: Error when call \"getPendingExpenses()\". Detail: {ex.Message}", true);
throw;
}
if (!pendingExpenses.Any())
{
executionContext.Checkpoint("Step 1-Final: There are not pending expenses");
return;
}
int numApproveExpenses = 0;
executionContext.Checkpoint($"Step 2: Processing {pendingExpenses.Count()} pending expenses");
foreach (var expenseNote in pendingExpenses)
{
if (expenseNote.IsApprovable)
{
try
{
await _workflowsRRHHProxy.Approve(expenseNote.Id.ToString());
executionContext.Checkpoint($"Step 2.1: Expense with number {expenseNote.Number} has been approved ");
numApproveExpenses++;
}
catch (Exception ex)
{
executionContext.Error($"Step 2.1: Error when call \"Approve()\" with id: {expenseNote.Id} " +
$". Detail: {ex.Message}", false);
throw;
}
}
}
test example:
// ARRANGE
var mockExpenseNote = _mockFactory.CreateMock<DomainEntities.ExpenseNote>();
mockExpenseNote.Expects.One.Method(x => x.IsApprovable).WillReturn(true);
var expenseNote = mockExpenseNote.MockObject;
expenseNote.Id = Guid.NewGuid();
expenseNote.Number = "EX-APPROVE";
var expenseNotes = new List<DomainEntities.ExpenseNote>
{
expenseNote
};
Task<IEnumerable<DomainEntities.ExpenseNote>> task = Task.FromResult<IEnumerable<DomainEntities.ExpenseNote>>(expenseNotes);
var executionContext = _mockFactory.CreateMock<ITaskExecutionContext>();
executionContext.Expects.Between(1, 100).Method(method => method.Checkpoint("")).WithAnyArguments();
_expenseNoteService.Expects.One.Method(method => method.GetPendingExpenseNotes())
.WithAnyArguments()
.WillReturn(task);
var sut = GetServiceUnderTest();
// ACT
await sut.ProcessPendingExpenseNotes(executionContext.MockObject);
// ASSERT
_mockFactory.VerifyAllExpectationsHaveBeenMet();
but when i execute this test in " .WillReturn(task);" have this error:
System.InvalidCastException: Cannot cast object of type 'System.Linq.Expressions.PropertyExpression' to type 'System.Linq.Expressions.MethodCallExpression'..
Can Anyone Help me?
With mockExpenseNote.Expects.One.Method(x => x.IsApprovable).WillReturn(true); your lambda uses a property but you used the .Method() method so it expects you to use a method here (or call something else than .Method()).

how to call Call Async Methods in Parallel.ForEach loop properly [duplicate]

This question already has answers here:
Nesting await in Parallel.ForEach [duplicate]
(11 answers)
Closed 2 years ago.
how to call Call Async Methods in Parallel.ForEach loop properly.billDataService.SaveBillDetail and GetProfileDetails both are async methods.data saving in MongoDB in SaveBillDetail .
public async Task ConvertXMLFileToJSON()
{
try
{
if (Directory.Exists(_appSettings.DocumentsStorage))
{
int i = 1; //Test
bool exists = Directory.GetFiles(_appSettings.DocumentsStorage).Any(x => x.Equals(Path.Combine(_appSettings.DocumentsStorage, "Ready.txt"), StringComparison.OrdinalIgnoreCase)); //Need to check
if (exists)
{
Parallel.ForEach(System.IO.Directory.GetFiles(_appSettings.DocumentsStorage, "*.xml"), (currentFile) =>
{
try
{
XElement root = XElement.Load(currentFile); // or .Parse(string);
//Removing CDATA property from XElement.
XElement items = XElement.Parse(root.ToString().Replace("<![CDATA", "").Replace("]]>", "").Replace("[", ""));
//Removing XML_INFO Tag from XElement.
items.Elements("XML_INFO").Remove();
XmlDocument xmlDoc = new XmlDocument();
using (XmlReader xmlReader = items.CreateReader())
{
xmlDoc.Load(xmlReader);
}
var json = JsonConvert.SerializeXmlNode(xmlDoc);
billDetails obj = JsonConvert.DeserializeObject<billDetails>(json);
BillDetails billDetails = new BillDetails();
billDetails.AccountNumber = obj.BILL_INFO.BILL_RUN.ACCT_INFO.ACCT_CODE;
billDetails.MobileNumber = obj.BILL_INFO.BILL_RUN.ACCT_INFO.PRINCIPAL_NO.STR_PRINCIPAL_NO;
billDetails.BillDate = DateTime.ParseExact(obj.BILL_INFO.BILL_RUN.BILL_PROP.TO_DATE, "dd/MM/yyyy", CultureInfo.InvariantCulture);
billDetails.DueAmount = obj.BILL_INFO.BILL_RUN.ACCT_INFO.ACCT_BALANCE_TRACE.TOTAL_DUE;
billDetails.CustomerName = obj.BILL_INFO.BILL_RUN.CUST_INFO.CUST_NAME.FULL_NAME;
billDetails.InvoiceId = obj.BILL_INFO.BILL_RUN.BILL_PROP.INVOICE_ID;
billDetails.DueDate = DateTime.ParseExact(obj.BILL_INFO.BILL_RUN.BILL_PROP.DUE_DATE, "yyyyMMdd hh:mm:ss", CultureInfo.InvariantCulture);
billDetails.RepositoryName = "postpaid";
billDetails.BillRun = obj.BILL_INFO.BILL_RUN; //tempObj2.BILL_INFO.ToString().Remove(0, 1);
billDetails.ObjectId = Guid.NewGuid().ToString();
if (billDetails != null)
{
BillDataService billDataService = new BillDataService(_dbConfig);
Console.WriteLine("SaveBillDetail");
if (billDataService.SaveBillDetail(billDetails) != null)
{
Console.WriteLine("SaveBillDetail done");
GetProfileDetails(billDetails);
_logger?.LogInformation(i++ + " File Success");
Console.WriteLine(i++ + " File Success");
// File.Delete(file); //Delete File
}
}
}
catch (Exception ex)
{
_logger?.LogError(ex, "Error");
}
finally { }
});
}
}
}
catch (Exception ex)
{
_logger?.LogError(ex, "Error");
}
finally
{
}
}
public async Task GetProfileDetails(BillDetails billDetails)
{
try
{
ProfileService profileService = new ProfileService(_dbConfig);
var searchFilter = new SearchFilter
{
Filters = new List<Filter>()
};
if (!string.IsNullOrEmpty(billDetails.AccountNumber))
{
searchFilter.Filters.Add(new Filter() { PropertyName = "AccountNumber", Operator = Operator.Equals, Value = billDetails.AccountNumber, CaseSensitive = true });
}
if (searchFilter != null)
{
Profile profile = await profileService.GetProfiles(searchFilter);
if (profile != null)
{
await SendMailNotification(profile, billDetails);
}
else
{
_logger?.LogError("Profile Info not found");
}
}
}
catch (Exception ex)
{
_logger?.LogError(ex, "Error");
throw;
}
finally { }
}
normal for each loop I can able to call and save data in MongoDB.but Parallel.ForEach loop I cannot able to call the async method using await and data saving in mongo also not working.inside Parallel.ForEach loop I avoided using await of the front of the calling method.
You can change your code to be like below and wait for all the tasks to be completed.
var fileTasks = System.IO.Directory.GetFiles(_appSettings.DocumentsStorage, "*.xml").Select(async currentFile =>
{
try
{
XElement root = XElement.Load(currentFile); // or .Parse(string);
// rest o your code here
if (billDetails != null)
{
if (billDataService.SaveBillDetail(billDetails) != null)
{
Console.WriteLine("SaveBillDetail done");
await GetProfileDetails(billDetails);
}
}
}
catch(exception ex) { //log exeption }
});
await Task.WhenAll(fileTasks);

In app billing plugin fails on Xamarin.Android with a vague error message ("Something went wrong on our end. Please try again")

When using James Montemagno's In App Billing Plugin for Xamarin.Android, a vague error message appears at the purchase screen when attempting to purchase products from Google Play:
Something went wrong on our end. Please try again
I am more or less completely using sample code from the plugin's documentation. The plugin works fine with reserved billing IDs for testing, such as android.test.purchased. This support forum states that the issue is due to "existing security measures", which is not particularly clear- https://forums.xamarin.com/discussion/153166/in-app-purchase-error-something-went-wrong-on-our-end-please-try-again.
The error code that results is Plugin.InAppBilling.Abstractions.PurchaseError.UserCancelled.
Here is the code for the purchasing function:
class ProVersionUnlocker
{
string ProductID = "XXXXXXXXXXXX";
public async Task<bool> WasProVersionPurchased()
{
/*TESTING
*
* TESTING
*
* TESTING
*/
#if DEBUG
//return true;
#endif
var billing = CrossInAppBilling.Current;
try
{
var connected = await billing.ConnectAsync(ItemType.InAppPurchase);
if (!connected)
{
//Couldn't connect
return false;
}
//check purchases
var purchases = await billing.GetPurchasesAsync(ItemType.InAppPurchase);
//check for null just incase
if (purchases?.Any(p => p.ProductId == ProductID) ?? false)
{
//Purchase restored
return true;
}
else
{
//no purchases found
return false;
}
}
catch (InAppBillingPurchaseException purchaseEx)
{
//Billing Exception handle this based on the type
Log.Debug("IAP", "Error: " + purchaseEx);
}
catch (Exception ex)
{
//Something has gone wrong
}
finally
{
await billing.DisconnectAsync();
}
return false;
}
public async Task<bool> PurchaseProVersion()
{
if (await WasProVersionPurchased())
return true;
string Payload = "ProVersionProVersion";
var billing = CrossInAppBilling.Current;
try
{
var connected = await billing.ConnectAsync(ItemType.InAppPurchase);
if (!connected)
{
//we are offline or can't connect, don't try to purchase
return false;
}
//check purchases
var purchase = await billing.PurchaseAsync(ProductID, ItemType.InAppPurchase, Payload, new Verify());
//Consume for further testing
//var consumedItem = await CrossInAppBilling.Current.ConsumePurchaseAsync(purchase.ProductId, purchase.PurchaseToken);
//possibility that a null came through.
if (purchase == null)
{
//did not purchase; do nothing and fall through to failure
}
else if (purchase.State == PurchaseState.Purchased)
{
return true;
}
}
catch (InAppBillingPurchaseException purchaseEx)
{
//Billing Exception handle this based on the type
//Maybe it was an Already Purchased Error, in which case we return true
if (purchaseEx.PurchaseError == PurchaseError.AlreadyOwned)
return true;
Log.Debug("IAP", "Error: " + purchaseEx);
}
catch (Exception ex)
{
//Something else has gone wrong, log it
Log.Debug("IAP", "Issue connecting: " + ex);
}
finally
{
await billing.DisconnectAsync();
}
return false;
}
public class Verify : IInAppBillingVerifyPurchase
{
const string key1 = #"XOR_key1";
const string key2 = #"XOR_key2";
const string key3 = #"XOR_key3";
public Task<bool> VerifyPurchase(string signedData, string signature, string productId = null, string transactionId = null)
{
//This is only used for testing things at the moment.
#if false
var key1Transform = Plugin.InAppBilling.InAppBillingImplementation.InAppBillingSecurity.TransformString(key1, 1);
var key2Transform = Plugin.InAppBilling.InAppBillingImplementation.InAppBillingSecurity.TransformString(key2, 2);
var key3Transform = Plugin.InAppBilling.InAppBillingImplementation.InAppBillingSecurity.TransformString(key3, 3);
return Task.FromResult(Plugin.InAppBilling.InAppBillingImplementation.InAppBillingSecurity.VerifyPurchase(key1Transform + key2Transform + key3Transform, signedData, signature));
#else
return Task.FromResult(true);
#endif
}
}
Here is the calling code, which is within a PreferenceFragment:
var Unlocker = new ProVersionUnlocker();
var unlock = this.FindPreference("unlock");
unlock.PreferenceClick += async (sender, e) =>
{
//Toast.MakeText(Plugin.CurrentActivity.CrossCurrentActivity.Current.Activity, "Ayy lmao", ToastLength.Short).Show();
unlock.SetSummary(Resource.String.PressAgain);
bool Success = await Unlocker.PurchaseProVersion();
//Toast.MakeText(Plugin.CurrentActivity.CrossCurrentActivity.Current.Activity, Success.ToString(), ToastLength.Short).Show();
UnlockStuff();
};

async processing in c#

I have a service that implements functionality to return data from sentiment analysis APIs. The client can request results from one or all engines and I want to collate all the data together. I want to process these async and wait for them all to complete before returning the result set. I'm new to async programming and I really cant figure out how to arrange the code and how to implement it syntactically. Here's an EXAMPLE of what I'm TRYING to achieve (I know this doesn't work, but you get the idea; hopefully :-) ):
private ISentimentResponse ProcessRequest(ISentimentRequest request, SentimentEngineServices selectedEngines)
{
SentimentResponse response = new SentimentResponse();
List<Task> taskList = new List<Task>();
foreach (SentimentEngineServices engineService in (SentimentEngineServices[])Enum.GetValues(typeof(SentimentEngineServices)))
{
if (((int)engineService & (int)selectedEngines) > 0)
{
ISentimentEngine engine = _engineFactory.GetSentimentEngine(engineService, null);
Task<ISentimentEngineResult> task = new Task<ISentimentEngineResult>(engine.AnalyseSentimentASync(request));
taskList.Add(task);
}
}
if (taskList.Count > 0)
{
ISentimentEngineResult[] results = Task<ISentimentEngineResult>.WaitAll(taskList);
foreach (result in results)
response.Add(results);
}
return response;
}
The engine has the following code implementation of engine.AnalyseSentimentASync:
public ISentimentEngineResult AnalyseSentiment(ISentimentRequest request)
{
try
{
MultiLanguageBatchInput sentimentList = SentimentRequestToMicrosoftBatchInput(request, Properties.Settings.Default.DefaultLanguage);
SentimentBatchResult sentiment = _client.Sentiment(sentimentList);
KeyPhraseBatchResult keyPhrases = _client.KeyPhrases(sentimentList);
return MicrosoftBatchResultsToSentimentEngineResult(sentiment, keyPhrases);
}
catch (Exception ex)
{
_logger.LogMessage(ex,$"{EngineName} threw an unknown exception: ", LoggingLevel.Error);
throw;
}
}
public async Task<ISentimentEngineResult> AnalyseSentimentAsync(ISentimentRequest request)
{
return AnalyseSentiment(request);
}
What do I need to do and is there any better way to achieve this?
I've looked everywhere for an example but I cant find one that addresses my implementation requirements, or the whole approach is completely wrong!
Thanks all,
Stu.
This is how you can convert it to async:
public async Task<ISentimentEngineResult> AnalyseSentimentAsync(ISentimentRequest request)
{
try
{
MultiLanguageBatchInput sentimentList = SentimentRequestToMicrosoftBatchInput(request, Properties.Settings.Default.DefaultLanguage);
SentimentBatchResult sentiment = await _client.SentimentAsync(sentimentList);
KeyPhraseBatchResult keyPhrases = await _client.KeyPhrasesAsync(sentimentList);
return MicrosoftBatchResultsToSentimentEngineResult(sentiment, keyPhrases);
}
catch (Exception ex)
{
_logger.LogMessage(ex,$"{EngineName} threw an unknown exception: ", LoggingLevel.Error);
throw;
}
}
private async Task<ISentimentResponse> ProcessRequestAsync(ISentimentRequest request, SentimentEngineServices selectedEngines)
{
SentimentResponse response = new SentimentResponse();
List<Task<ISentimentEngineResult>> taskList = new List<Task<ISentimentEngineResult>>();
foreach (SentimentEngineServices engineService in (SentimentEngineServices[])Enum.GetValues(typeof(SentimentEngineServices)))
{
if (((int)engineService & (int)selectedEngines) > 0)
{
ISentimentEngine engine = _engineFactory.GetSentimentEngine(engineService, null);
Task<ISentimentEngineResult> task = engine.AnalyseSentimentASync(request);
taskList.Add(task);
}
}
if (taskList.Count > 0)
{
ISentimentEngineResult[] results = await Task.WhenAll(taskList);
foreach (result in results)
response.Add(results);
}
return response;
}
Remember that you have to call it from some kind of event handler. I don't know what framework you are using (wpf, asp.net, windows service, webapi).
Ok, so here it is:
public ISentimentResponse AnalyseSentiment(ISentimentRequest request, SentimentEngineServices selectedEngines)
{
if (selectedEngines == SentimentEngineServices.None) throw new ArgumentException(nameof(selectedEngines));
ValidateRequest(request);
return ProcessRequestAsync(request, selectedEngines).Result;
}
private async Task<ISentimentResponse> ProcessRequestAsync(ISentimentRequest request, SentimentEngineServices selectedEngines)
{
SentimentResponse response = new SentimentResponse();
List<Task<ISentimentEngineResult>> taskList = new List<Task<ISentimentEngineResult>>();
foreach (SentimentEngineServices engineService in (SentimentEngineServices[])Enum.GetValues(typeof(SentimentEngineServices)))
{
if (((int)engineService & (int)selectedEngines) > 0)
{
ISentimentEngine engine = _engineFactory.GetSentimentEngine(engineService, null);
Task<ISentimentEngineResult> task = engine.AnalyseSentimentASync(request);
taskList.Add(task);
}
}
if (taskList.Count > 0)
{
ISentimentEngineResult[] results = await Task.WhenAll(taskList);
foreach (var result in results)
response.Add(result);
}
return response;
}
And the sentiment interface implementation:
public async Task<ISentimentEngineResult> AnalyseSentiment(ISentimentRequest request)
{
try
{
MultiLanguageBatchInput sentimentList = SentimentRequestToMicrosoftBatchInput(request, Properties.Settings.Default.DefaultLanguage);
SentimentBatchResult sentiment = await _client.SentimentAsync(sentimentList);
KeyPhraseBatchResult keyPhrases = await _client.KeyPhrasesAsync(sentimentList);
return MicrosoftBatchResultsToSentimentEngineResult(sentiment, keyPhrases);
}
catch (Exception ex)
{
_logger.LogMessage(ex,$"{EngineName} threw an unknown exception: ", LoggingLevel.Error);
throw;
}
}
Thanks FCin.

Categories