When I run the code below, I get the following error:
Value cannot be null. Parameter name: first
Here is my code:
private async void CallWebApiDetails()
{
WebApiService oWS = new WebApiService();
lstLocalDBAlertsID = new List<string>();
try
{
ErrorHandle err = await oWS.GetAllAlerts();
var lstdistinct = err.lstServerAlertsIDs.Except(lstLocalDBAlertsID).ToList();
if (lstdistinct != null)
{
var lstOrderedLst = lstdistinct.OrderBy(i => i).ToList();
if (lstOrderedLst.Count > 0)
{
for (int i = 0; i < lstOrderedLst.Count; i++)
{
AlertData oAlertData = new AlertData();
oAlertData.Where.AlertId.Value = lstOrderedLst[i];
if (!oAlertData.Query.Load())
{
ErrorHandle oErr = new ErrorHandle();
oErr = await oWS.getSpecificAlert(lstOrderedLst[i]);
await SaveAlertData(Convert.ToInt32(lstOrderedLst[i]), oErr);
}
}
}
}
}
catch (Exception ex)
{
LogError oLE = new LogError();
oLE.logEx(ex, "CallWebApiDetails");
}
}
Can somebody tell me what's wrong with my code?
The Except extension method has first as the this parameter; it is defined as
public static IEnumerable<TSource> Except<TSource>(
this IEnumerable<TSource> first, IEnumerable<TSource> second)
{
if (first == null)
{
throw Error.ArgumentNull("first");
}
// ...
}
so presumably in this line:
var lstdistinct = err.lstServerAlertsIDs.Except(lstLocalDBAlertsID).ToList()
the value of err.lstServerAlertsIDs is null. So: fix that.
Note: it is a good idea to get familiar with using the debugger with breakpoints or at least the stack trace to identify which line is failing. You can't always (or even often) infer the context like this.
Related
I want to download a file via Results.File(). It works when executing it in the main method (app.MapGet), however returning it in a different method does do nothing. The line where it should send the file is executed in the Debugger, however it does not return, but jumps back to the main method to execute the last return (The one that never should be executed). This last return does indeed return a result.
I have also used several methods like Result.BadRequest(), however nothing is executed when it is not in the main method.
I saw people using IResult as return method but I am not sure whether this is even right.
My guess is maybe the wrong return type or executing a Task or so.
Whole methods:
app.MapGet("/", (HttpContext context) =>
{
if (context.Request.Query.ContainsKey("amount"))
{
if (context.Request.Query["amount"].Count > 1)
{
return Results.BadRequest(new { Error = "The query parameter 'amount' may only be used once." });
}
if (int.TryParse(context.Request.Query["amount"], out int amount))
{
if (amount <= 0)
{
return Results.BadRequest(new { Error = "The specified amount must be greater or equal to 1." });
}
var list = new List<string>();
for (int i = 0; i < amount; i++)
{
list.Add(Ulid.NewUlid().ToString());
}
CheckIfDownload(context, (list, null));
return Results.Json(new { Ulids = list });
}
else
{
return Results.BadRequest(new { Error = "The specified amount is not a valid number." });
}
}
string ulid = Ulid.NewUlid().ToString();
CheckIfDownload(context, (null, ulid));
return Results.Json(new { Ulid = ulid });
});
static IResult? CheckIfDownload(HttpContext context, (List<string>? list, string? single) ulidListOrSingle)
{
if (context.Request.Query.ContainsKey("download"))
{
if (context.Request.Query["download"].Count > 1)
{
return Results.BadRequest(new { Error = "The query parameter 'download' may only be used once." });
}
if (context.Request.Query["download"] == "" || (bool.TryParse(context.Request.Query["download"], out bool download) && download))
{
if (ulidListOrSingle.list != null)
{
return SendJsonFile(JsonSerializer.Serialize(ulidListOrSingle.list));
}
if (ulidListOrSingle.single != null)
{
return SendJsonFile(JsonSerializer.Serialize(ulidListOrSingle.single));
}
return Results.BadRequest(new { Error = "An unknown error occurred." });
}
}
return null;
}
static IResult SendJsonFile(string data)
{
byte[] buffer = Encoding.UTF8.GetBytes(data);
var stream = new MemoryStream(buffer);
return Results.File(stream, "application/json", $"UlidGenerator_{DateTime.Now:MM-dd-yyyy_HH-mm-ss}.json");
}
when you inline an entire method block (not just a single expression), you must return what you want to be the output of the block. In your case you are not capturing the result of SendJsonFile to return it:
app.MapGet("/download", () =>
{
string data = "json data";
var result = SendJsonFile(data);
return result;
});
Okay so I'm still quite new to coding and mostly only knows the basics. I have never worked with API. I'm trying to make a program that gets the number of subs from PewDiePie and Cocomelon and compare them.
namespace PewdiepieVsCoco
{
class Program
{
static void Main(string[] args)
{
try
{
var len = args?.Length;
if (len == null || len.Value == 0)
{
PrintStart();
return;
}
var pdpSubCount = args[0];
var pdpSub = GetPDPSubcount(pdpSubCount).Result;
PrintPDPResult(pdpSub);
}
catch (AggregateException agg)
{
foreach (var e in agg.Flatten().InnerExceptions)
Console.WriteLine(e.Message);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.ReadKey();
}
private static async Task<dynamic> GetPDPSubcount(string pdpSubCount)
{
var parameters = new Dictionary<String, String>
{
["key"] = ConfigurationManager.AppSettings["APIKey"],
["channelsId"] = "UC-lHJZR3Gqxm24_Vd_AJ5Yw",
["part"] = "statistics",
["forUsername"] = "PewDiePie",
["fields"] = "items/statistics(subscriberCount)"
};
var baseUrl = "https://www.googleapis.com/youtube/v3/channels";
var fullUrl = MakeUrlWithQuery(baseUrl, parameters);
var pdpSub = await new HttpClient().GetStringAsync(fullUrl);
if (pdpSub != null)
{
//Does the thing
return JsonConvert.DeserializeObject(pdpSubCount);
}
return default(dynamic);
}
private static string MakeUrlWithQuery(string baseUrl,
IEnumerable<KeyValuePair<string, string>> parameters)
{
if (string.IsNullOrEmpty(baseUrl))
throw new ArgumentException(nameof(baseUrl));
if (parameters == null || parameters.Count() == 0)
return baseUrl;
return parameters.Aggregate(baseUrl,
(accumulated, kvp) => string.Format($"{accumulated}{kvp.Value}&"));
}
private static void PrintPDPResult(dynamic pdpSub)
{
Console.WriteLine($"PewDiePie currently have: {pdpSub} subscribers");//insert subs
}
private static void PrintStart()
{
Console.WriteLine("The war is on!");
Thread.Sleep(500);
Console.WriteLine("PewDiePie Vs Cocomelon – Nursery Rhymes");
Thread.Sleep(500);
}
}
}
Here is the code, I have followed what an Indian dude did in a YT video so some things I don't know what do but I have an idea on what's going on.
Your program is likely returning before making any API calls because you aren't executing it with any command line arguments. Remove this block of code, so it continues without returning early.
var len = args?.Length;
if (len == null || len.Value == 0)
{
PrintStart();
return;
}
Also, pdpSubCount should not be a function argument, and should not be passed into DeserializeObject. You should be deserializing the response from the api call
return JsonConvert.DeserializeObject(pdpSub)
I have written an app that goes through our own properties and scraps the data. To make sure I don't run through the same URLs, I am using a MySQL database to store the URL, flag it once its processed. All this was being done in a single thread and it's fine if I had only few thousand entries. But I have few hundred thousand entries that I need to parse so I need to make changes in the code (I am newbie in multithreading in general). I found an example and was trying to copy the style but doesn't seem to work. Anyone know what the issue is with the following code?
EDIT: Sorry didn't mean to make people guess the issue but was stupid of me to include the exception. Here is the exception
"System.InValidCastException: 'Specified cast is not valid.'"
When I start the process it collects the URLs from the database and then never hits DoWork method
//This will get the entries from the database
List<Mappings> items = bot.GetUrlsToProcess(100);
if (items != null)
{
var tokenSource = new CancellationTokenSource();
var token = tokenSource.Token;
Worker.Done = new Worker.DoneDelegate(WorkerDone);
foreach (var item in items)
{
urls.Add(item.Url);
WaitingTasks.Enqueue(new Task(id => new Worker().DoWork((int)id, item.Url, token), item.Url, token));
}
LaunchTasks();
}
static async void LaunchTasks()
{
// keep checking until we're done
while ((WaitingTasks.Count > 0) || (RunningTasks.Count > 0))
{
// launch tasks when there's room
while ((WaitingTasks.Count > 0) && (RunningTasks.Count < MaxRunningTasks))
{
Task task = WaitingTasks.Dequeue();
lock (RunningTasks) RunningTasks.Add((int)task.AsyncState, task);
task.Start();
}
UpdateConsole();
await Task.Delay(300); // wait before checking again
}
UpdateConsole(); // all done
}
static void UpdateConsole()
{
Console.Write(string.Format("\rwaiting: {0,3:##0} running: {1,3:##0} ", WaitingTasks.Count, RunningTasks.Count));
}
static void WorkerDone(int id)
{
lock (RunningTasks) RunningTasks.Remove(id);
}
public class Worker
{
public delegate void DoneDelegate(int taskId);
public static DoneDelegate Done { private get; set; }
public async void DoWork(object id, string url, CancellationToken token)
{
if (token.IsCancellationRequested) return;
Content obj;
try
{
int tries = 0;
bool IsUrlProcessed = true;
DateTime dtStart = DateTime.Now;
string articleDate = string.Empty;
try
{
ScrapeWeb bot = new ScrapeWeb();
SearchApi searchApi = new SearchApi();
SearchHits searchHits = searchApi.Url(url, 5, 0);
if (searchHits.Hits.Count() == 0)
{
obj = await bot.ReturnArticleObject(url);
if (obj.Code != HttpStatusCode.OK)
{
Console.WriteLine(string.Format("\r Status is {0}", obj.Code));
tries = itemfound.UrlMaxTries + 1;
IsUrlProcessed = false;
itemfound.HttpCode = obj.Code;
}
else
{
string title = obj.Title;
string content = obj.Contents;
string description = obj.Description;
Articles article = new Articles();
article.Site = url.GetSite();
article.Content = content;
article.Title = title;
article.Url = url.ToLower();
article.Description = description;
string strThumbNail = HtmlHelper.GetImageUrl(url, obj.RawResponse);
article.Author = HtmlHelper.GetAuthor(url, obj.RawResponse);
if (!string.IsNullOrEmpty(strThumbNail))
{
//This condition needs to be added to remove ?n=<number> from EP thumbnails
if (strThumbNail.Contains("?"))
{
article.ImageUrl = strThumbNail.Substring(0, strThumbNail.IndexOf("?")).Replace("http:", "https:");
}
else
article.ImageUrl = strThumbNail.Replace("http:", "https:");
}
else
{
article.ImageUrl = string.IsNullOrEmpty(strThumbNail) ? article.Url.GetDefaultImageUrls() : strThumbNail.Replace("http:", "https:");
}
articleDate = HtmlHelper.GetPublishDate(url, obj.RawResponse);
if (string.IsNullOrEmpty(articleDate))
article.Pubdate = DateTime.Now;
else
article.Pubdate = DateTime.Parse(articleDate);
var client = new Index(searchApi);
var result = client.Upsert(article);
itemfound.HttpCode = obj.Code;
if (result)
{
itemfound.DateCreated = DateTime.Parse(articleDate);
itemfound.DateModified = DateTime.Parse(articleDate);
UpdateItem(itemfound);
}
else
{
tries = itemfound.UrlMaxTries + 1;
IsUrlProcessed = false;
itemfound.DateCreated = DateTime.Parse(articleDate);
itemfound.DateModified = DateTime.Parse(articleDate) == null ? DateTime.Now : DateTime.Parse(articleDate);
UpdateItem(itemfound, tries, IsUrlProcessed);
}
}
}
else
{
tries = itemfound.UrlMaxTries + 1;
IsUrlProcessed = true;
itemfound.HttpCode = HttpStatusCode.OK;
itemfound.DateCreated = DateTime.Parse(articleDate);
itemfound.DateModified = DateTime.Parse(articleDate) == null ? DateTime.Now : DateTime.Parse(articleDate);
}
}
catch (Exception e)
{
tries = itemfound.UrlMaxTries + 1;
IsUrlProcessed = false;
itemfound.DateCreated = DateTime.Parse(articleDate);
itemfound.DateModified = DateTime.Parse(articleDate) == null ? DateTime.Now : DateTime.Parse(articleDate);
}
finally
{
DateTime dtEnd = DateTime.Now;
Console.WriteLine(string.Format("\r Total time taken to process items is {0}", (dtEnd - dtStart).TotalSeconds));
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
Done((int)id);
}
}
All this code is based from Best multi-thread approach for multiple web requests this link. Can someone tell me how to get this approach running?
I think the problem is in the way you're creating your tasks:
new Task(id => new Worker().DoWork((int)id, item.Url, token), item.Url, token)
This Task constructor overload expected Action<object> delegate. That means id will be typed as object and you need to cast it back to something useful first.
Parameters
action
Type: System.Action<Object>
The delegate that represents the code to execute in the task.
state
Type: System.Object
An object representing data to be used by the action.
cancellationToken
Type: System.Threading.CancellationToken
-The CancellationToken that that the new task will observe.
You decided to cast it to int by calling (int)id, but you're passing item.Url as the object itself. I can't tell you 100% what the type of Url is but I don't expect Url-named property to be of type int.
Based on what #MarcinJuraszek said I just went back to my code and added an int as I couldn't find another way to resolve it. Here is the change I made
int i=0
foreach (var item in items)
{
urls.Add(item.Url);
WaitingTasks.Enqueue(new Task(id => new Worker().DoWork((string)id, item.Url, token), item.Url, token));
i++;
}
I currently run a Windows service that exports Crystal Reports to PDF on schedule. Out of the 66 reports that run, 5 or so have no parameters defined.
Using the Crystal Reports DLL, I understand that the ReportDocument.Export() method requires parameters, as I have been experiencing the "missing parameter values" exception when it hits the ReportDocument.Export() method.
I'm currently doing my set parameters in this method:
private void SetParameters(string rawParameters = null)
{
var crystalParameters = new Dictionary<string, object>();
var parameters = String.IsNullOrEmpty(rawParameters) ? null : HttpUtility.ParseQueryString(rawParameters);
if(parameters != null)
{
foreach (string rawKey in parameters.AllKeys)
{
var value = parameters[rawKey];
// Check for array value (e.g. key[0]=value)
var arrayCheck = Regex.Match(rawKey, #"^(.+)\[[0-9]?\]$");
if (arrayCheck.Success)
{
var key = arrayCheck.Groups[1].Value;
// Existing entry for this key, reconstruct object array with this added
if (crystalParameters.ContainsKey(key))
{
var newParameterArray = new object[((object[])crystalParameters[key]).Count() + 1];
int i = 0;
foreach (object item in (object[])crystalParameters[key])
{
newParameterArray[i++] = item;
}
newParameterArray[i++] = (object)value;
crystalParameters[key] = (object)newParameterArray;
}
// New array value
else
crystalParameters[key] = (object)new object[] { value };
}
// Discrete value
else
crystalParameters[rawKey] = (object)parameters[rawKey];
}
foreach (string parameter in crystalParameters.Keys)
{
try
{
this.reportDocument.SetParameterValue(parameter, crystalParameters[parameter]);
}
catch (Exception ex)
{
// Ignore invalid parameter exceptions, otherwise throw again
if (ex.HResult != -2147352565)
{
throw ex;
}
}
}
}
}
I tested a couple of scenarios, including ReportDocument.SetParameterValue("", ""). However, I resolved the issue when and only when I blanked out this if clause; reserving this method to be called only when the report does have parameters.
In my webmethod of my WCF rest service i am trying to find record using Linq's First method like below
[WebInvoke(UriTemplate = "UpdateProductObject", Method = "PUT")]
public Result UpdateProductObject(ProductObjectToSave prodSave)
{
IUnitOfWork unitOfWork = new UnitOfWork((IObjectContext)_objectSetFactory);
var versions = prodSave.VersionDetails;
foreach (var versionDetail in versions)
{
var detail = versionDetail;
var dbVersionentity = _productVersionEntityRepository.First(x => x.Id == detail.Id);
if (detail.Id < 0)
{
dbVersionentity.Id = GetNextTableId("vProductVersion");
}
dbVersionentity.Name = detail.Name;
dbVersionentity.Code = detail.Name;
if (detail.Id > 0){
_productVersionEntityRepository.Update(dbVersionentity);
}
else
{
_productVersionEntityRepository.Insert(dbVersionentity);
}
}
try
{
unitOfWork.Commit();
}
catch (Exception e)
{
return new Result() { Error = e.Message };
}
return new Result() { Error = "Record updated successfully" };
}
The "_productVersionEntityRepository" is defined as below in my service.
private readonly Repository<ProductVersionEntity> _productVersionEntityRepository;
When there are no records it throws exception "Sequence contains no elements" . I have done some finding that we can use FirstOrDefault method. But somehow i am not getting that option to use FirstOrDefault. I am really new to this so may be i have missed some links where solution could have been described. Please help me or suggest me other way to do some error handling if First method fails
That's the way that First() works, it will throw an exception if the element can't be found. You can use FirstorDefault() instead and check if the element is null.
Edit: I realised that you're using a custom repository. If you have access to the source code, I advise you to add a new method called .FirstOrDefault() that will take as parameter a predicate and returns null if no entities are found.
Edit 2: Add this method to your repository:
T FirstOrDefault(Expression<Func<T, bool>> where, params Expression<Func<T, object>>[] includeProperties)
{
IQueryable<T> query = AsQueryable();
query = PerformInclusions(includeProperties, query);
return query.FirstOrDefault(where);
}
Then you can do something like this in your code:
foreach (var versionDetail in versions)
{
bool isNew = false;
var detail = versionDetail;
var dbVersionentity = _productVersionEntityRepository.FirstOrDefault(x => x.Id == detail.Id);
// not found in database
if(dbVersionentity == null)
{
isNew = true;
// create entity here
dbVersionentity = new .....;
// you don't need to do this if id is auto-generated,
// i.e. Identity column in SQL Server
dbVersionentity.Id = GetNextTableId("vProductVersion");
}
dbVersionentity.Name = detail.Name;
dbVersionentity.Code = detail.Name;
if (isNew)
{
_productVersionEntityRepository.Insert(dbVersionentity);
}
else
{
_productVersionEntityRepository.Update(dbVersionentity);
}
}
try
var dbVersionentity = _productVersionEntityRepository.Where(x => x.Id == detail.Id).FirstOrDefault();