Blazor 6.0 await HttpClient.GetFromJsonAsync<List CS8601 Possible null reference asignment - entity-framework

Hello Everyone im missing something fairly fundamental here and i could really appreciate some guidance .
I am fairly new to Blazor and the entity framework and am building one of my first Blazor apps
I have a fairly basic data class
using System.ComponentModel.DataAnnotations;
namespace BIDM2.Data
{
public class InvalidAddressMapping
{
[Key]
public int record_no { get; set; } = 0;
public string sales_org_pos { get; set; } = " ";
public string press_sales_mgr_code { get; set; } = " ";
public string press_sales_mgr_Name { get; set; } = " ";
public string forming_sales_rep_code { get; set; } = " ";
public string forming_sales_rep_Name { get; set; } = " ";
}
}
that i am using in my controller as follows
[HttpGet]
public async Task <ActionResult<List<InvalidAddressMapping>>> GetInvalidAdressMappings()
{
return await _db.GetInvalidAddressMappings.FromSqlRaw("EXEC BIDM_GetInvalidAddressMappings;").ToListAsync();
}
and im trying to use it in my razor page like this
#code {
List<InvalidAddressMapping> invalidMappings = new List<InvalidAddressMapping>();
protected override async Task OnInitializedAsync()
{
invalidMappings = await HttpClient.GetFromJsonAsync<List<InvalidAddressMapping>>(NavigationManager.BaseUri + "invalidmapping");
}
}
how ever when i try and run my razor page im getting an error CS8601 Possible null Reference asignment :(
Im not sure i totaly understand and i could use some guidance to point me in the right direction it has to be somethign fairly fundamental i am missing
interestingly this all came about because im trying to convert an existing non async method to an async method
when i use
//1. get invalid address mappings
public InvalidAddressMapping[] GetInvalidAddressMappings()
{
InvalidAddressMapping[] invMappings;
// exec BIDM_GetInvalidAddressMappings calls the stored procedure
invMappings = _dbcontext.GetInvalidAddressMappings.FromSqlRaw("EXEC BIDM_GetInvalidAddressMappings;").ToArray();
return invMappings;
}
}
it works beautifully and i can see a lovely list of JSON data
please help a struggling old git out and pint me in a direction where i can understand where i am going wrong :)
thank you every one

The GetFromJsonAsync extension method returns a nullable type. In your case, it is List<InvalidAddressMapping>? (note the extra ? on the end there). If it fails to deserialise properly, for example, it could return null. The code is telling you that you need to check for a null response to be safe.
So the safe version is to do something like this:
var result = await HttpClient.GetFromJsonAsync<List<InvalidAddressMapping>>(
NavigationManager.BaseUri + "invalidmapping");
if(result == null)
{
// Do something here to handle this error, for example:
throw new Exception("Can't get data from the server for some reason, help!");
}
invalidMappings = result;
Also note that the CS8601 message you see is a warning, not an error. So technically you could ignore it, though I would strongly advise against doing that.

Related

Many to Many Relationship doesn't work both ways?

I've been trying to grok EF many-to-many relationships for the past two days now and I'm still missing something even after scouring a dozen different questions here.
I've got a model named Text that can have an arbitrary number of Tag models associated with it, and obviously, at least in theory, each Tag can be associated with an arbitrary number of Texts. Entity Framework seems to understand this well enough to create a table named TextTags in the database without me asking it to do so, and I can access Text.Tags without trouble, but when I attempt to access Tag.Texts in my code, I get a null reference exception.
Now, I could just add every text to every tag manually (or could I? that seems to throw some kind of error), but that would seem to defeat the purpose... Besides which, it also seems error prone. What am I failing to understand?
Code as requested:
Text model:
public class Text
{
public int ID { get; set; }
public Author Author { get; set; }
public string Content { get; set; }
public virtual ICollection<Tag> Tags { get; set; }
}
Tag model:
public class Tag
{
public int ID { get; set; }
public string Name { get; set; }
public ICollection<Text> Texts { get; set; }
}
Data insert:
using (var db = new TextDbContext())
{
db.Authors.Add(new Author()
{
Name = "Poe"
});
db.Tags.Add(new Tag() { Name = "lame" });
db.Tags.Add(new Tag() { Name = "example" });
db.SaveChanges();
db.Texts.Add(new Text()
{
Author = db.Authors.First(),
Tags = db.Tags.ToList(),
Content = "This is the first text by Poe."
});
db.Texts.Add(new Text()
{
Author = db.Authors.First(),
Tags = db.Tags.ToList(),
Content = "This is the second text by Poe."
});
db.Texts.Add(new Text()
{
Author = db.Authors.First(),
Tags = db.Tags.ToList(),
Content = "This is the third text by Poe."
});
db.SaveChanges();
}
Error:
foreach (var tag in db.Tags)
{
foreach (var text in tag.Texts)
{
Console.WriteLine("Tag: {0}\tText: {1}", tag.Name, text.Content);
// Null reference on line above.
}
}
You get a NullReferenceException because your navigation property Tag.Texts is not marked as virtual. As a result lazy loading does not work to load the Tag.Texts collection when you access it and the collection is null. (Text.Tags is virtual, hence no exception here.)

Returning a list using Entity Framework

I am trying to return list. Any suggestion would be highly appreciable. Thanks in Advance.
It throws this error:
Cannot implicitly convert type System.Collections.Generic.List<HTentityFramework.tblFlower> to
System.Collections.Generic.List<HTentityFramework.testDomain>
Code is:
public class GetFlowers
{
public IList<testDomain> getFlowerList()
{
TestContainer ctx = new TestContainer();
return ctx.tblFlowers.ToList();
}
}
public class testDomain
{
public string Name { get; set; }
public int quantity { get; set; }
}
The error is pretty clear - just read it!
The type you're returning from getFlowerList is IList<testDomain> - yet you're selecting from an EF object set that's called tblFlowers.
The error clearly says that this is an IList<tblFlower> - a list of tblFlower objects.
Your code cannot just convert a list of tblFlowers to a list of testDomain - that's the whole point.
You need to either provide a conversion yourself, or you need to return a IList<tblFlower> from your method:
public IList<tblFlower> getFlowerList() <==== return an IList<tblFlower> here!!
{
TestContainer ctx = new TestContainer();
return ctx.tblFlowers.ToList();
}

How to use list of pages from graph.facebook.com/me/accounts

https://graph.facebook.com/me/accounts?access_token=USERS_AUTH_TOKEN
returns a list of pages the user has admin status in (in JSON format).
I would like to list all the pages in a dropdownlist, and make the user choose which facebook page he wants to use (on my webapp), so I can obtain the specific access token for that facebook page.
My question is - whats the easiest and best way to do that. Ive never worked with JSON before, but I guess theres a pretty easy was to do this through the facebook-sdk.
Since you're using the C# SDK, just take the array of objects and convert them into a IList<IDictionary>() array using the pageId as the key and the value being the page name.
This is not fully compilable, but you get the idea:
private void IList<IDictionary<long,string>> ConvertToList(dynamic meAccounts)
{
foreach(var acc in meAccounts.data)
{
yield return new Dictionary((long)acc.id, (string)acc.name);
}
{
Okay figured out a way to do it. But I have no idea ifs the right way or the most optimal.
Would very much like inputs on it.
[DataContract]
internal class FacebookObj
{
[DataMember]
public List<FacebookAccount> data;
[DataMember]
public FacebookNext paging;
}
[DataContract]
internal class FacebookAccount
{
[DataMember]
public string name;
[DataMember]
public string category;
[DataMember]
public string id;
[DataMember]
public string access_token;
}
[DataContract]
internal class FacebookNext
{
[DataMember]
public string next;
}
public void ShowPages(string authToken) {
WebRequest webRequest = WebRequest.Create("https://graph.facebook.com/me/accounts?access_token=" + authToken);
WebResponse webResponse = webRequest.GetResponse();
Stream sr = webResponse.GetResponseStream();
if (sr != null)
{
jsonSer = new DataContractJsonSerializer(typeof(FacebookObj));
FacebookObj o = (FacebookObj)jsonSer.ReadObject(sr2);
foreach (FacebookAccount s in o.data)
{
//Do stuff
Response.Write(s.id + " - " + s.name + "<br />");
}
}
}

EF4.1 - recursive query to get hierarchical data

I come up with this:
public partial class Forum
{
public List<Forum> GetHierachy(Forum foru)
{
foreach (var forum in foru.SubForums.ToList())
{
yield return GetHierachy(forum);
}
}
}
For this:
public partial class Forum
{
public int Id { get; set; }
public int SubForumId { get; set; }
public virtual ICollection<Forum> SubForums { get; set; }
public virtual Forum ParentForum { get; set; }
}
And I get that:
The body of 'Jami.Data.Forum.GetHierachy(Jami.Data.Forum)' cannot be an iterator block because 'System.Collections.Generic.List<Jami.Data.Forum>' is not an iterator interface type:
Then I found out this:
Some help understanding "yield"
So I changed my method to:
public IEnumerable<Forum> GetHierachy(Forum foru)
{
foreach (var forum in foru.SubForums.ToList())
{
yield return GetHierachy(forum);
}
}
And Now I'm getting missing cast exception.
Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<Jami.Data.Forum>' to 'Jami.Data.Forum'. An explicit conversion exists (are you missing a cast?)
A this point I have no slighest idea why this exception occurs. I might be wrong, but for me it looks like returning collection not single item.
Yes it returns collection because it returns return type of your GetHierarchy. Iterators do not nest. You need something like:
public IEnumerable<Forum> GetHierachy(Forum forum)
{
yield forum;
foreach (var x in forum.SubForums.SelectMany(s => GetHierarchy(s)))
{
yield return x;
}
}
When I look at this query I definitely don't like it. It is ugly and it will perform terribly bad because this will use lazy loading to load data = a lot of queries to database. Hierarchical queries should be done directly in database with Common table expressions.
Have a look at this excellent solution to query hierarchical data
It may require some db alterations but its worth it.

Exception calling UpdateModel - Value cannot be null or empty

This is probably something silly I'm missing but I'm definitely lost. I'm using .NET 4 RC and VS 2010. This is also my first attempt to use UpdateModel in .NET 4, but every time I call it, I get an exception saying Value cannont be null or empty. I've got a simple ViewModel called LogOnModel:
[MetadataType(typeof(LogOnModelMD))]
public class LogOnModel
{
public string Username { get; set; }
public string Password { get; set; }
public class LogOnModelMD
{
[StringLength(3), Required]
public object Username { get; set; }
[StringLength(3), Required]
public object Password { get; set; }
}
}
My view uses the new strongly typed helpers in MVC2 to generate a textbox for username and one for the password. When I look at FormCollection in my controller method, I see values for both coming through.
And last but not least, here's are post controller methods:
// POST: /LogOn/
[HttpPost]
public ActionResult Index(FormCollection form)
{
var lm = new LogOnModel();
UpdateModel(lm, form);
var aservice = new AuthenticationService();
if (!aservice.AuthenticateLocal(lm.Username, lm.Password))
{
ModelState.AddModelError("User", "The username or password submitted is invalid, please try again.");
return View(lm);
}
return Redirect("~/Home");
}
Can someone please lend some insight into why UpdateModel would be throwing this exception? Thanks!
Known issue with early previews of MVC 2. This was fixed for MVC 2 RTM. You can download MVC 2 RTM from http://www.asp.net/mvc/. Information on how to jury-rig this installation into VS2010 RC can be found at http://haacked.com/archive/2010/02/10/installing-asp-net-mvc-2-rc-2-on-visual-studio.aspx.