Displaying Specific Fields from Facebook Graph API JSON - winforms

I'm trying to simply display the list of members in a specific group using the Facebook Graph API. I'm using Newtonsoft.JSON.
Here is the results of my url query:
Graph API Results
I used a JSON class generator and it gave me this:
public class Datum
{
public string name { get; set; }
public string id { get; set; }
public bool administrator { get; set; }
}
public class Cursors
{
public string before { get; set; }
public string after { get; set; }
}
public class Paging
{
public Cursors cursors { get; set; }
}
public class Members
{
public List<Datum> data { get; set; }
public Paging paging { get; set; }
}
public class RootObject
{
public Members members { get; set; }
public string id { get; set; }
}
I've tried every combination I can think of to display simply the list of members in a multi-line text box, but not sure if this is even the best way to display the list on a Windows Form App.
Could someone help me understand 2 things.
1) What is the best component to display the list of names in a Windows Form App?
2) What is the 1 or 2 lines to generate just the list of names using JsonConvert.DeserializeObject from this?
My raw data is stored in: string responseFromServer = reader.ReadToEnd();

To deserialize the JSON into your classes:
RootObject obj = JsonConvert.DeserializeObject<RootObject>(responseFromServer);
To get the member names into a List<string>:
List<string> members = obj.members.data.Select(d => d.name).ToList();
Note: You need to have using System.Linq; at the top of your file in order to use the Select and ToList methods.
As far as displaying the data in a windows form app, there's not a "best" component-- it depends on what you're trying to accomplish as to what control you would choose to use. For example, if all you want to do is display the list of names in a multi-line textbox, you could do this:
textBox1.Text = string.Join("\r\n", members);
If you want to allow the user to be able to select individual names and do something based on that selection, you would probably want to use a ListBox or a ComboBox instead. You can populate a ListBox or ComboBox like this:
listBox1.DisplayMember = "name";
listBox1.DataSource = obj.members.data;
That should be enough to get you started.

Related

Advanced NoSQL Query (RavenDB)

I'm trying to run a query that gets all of my references, but it isn't working.
What I have right now is
from UserGroups
where Id="ActionGroup"
select Accomplishments.ID, Accomplishments.Accomplish
But I need only the Accomplishments.Accomplish that belong in my other collection ActivityAccomplishments and these are nested in another object.
To be exact, I'm trying to figure out how to query the UserGroups collection and only look at the one with id="ActionGroup". After that I need all of the Accomplishments.Accomplish strings within the UserGroup list to be filtered out if they don't match a id in ActivityAccomplishment.
Basically, in the UserGroup I'm looking at it's List Accomplishments needs to filter out all strings within the Acc class that don't match an Id in ActivityAccomplishments. Can someone please help me.
Here are the classes I'm using.
public class UserGroups
{
public string Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public List<Acc> Accomplishments { get; set; }
}
public class Acc
{
public string Id { get; set; }
public List<string> Accomplish { get; set; }
}
public class ActivityAccomplishments
{
public string Id { get; set; }
}
try this:
from UserGroups
where Id = "ActionGroup" AND Accomplishments[].Accomplish != "theIdYouDontWant"
select Accomplishments[].Accomplish as AccomplishStringsList
(not necessary to add the 'as AccomplishStringsList' - it is just a name for the results)

Showing specific data based on the currently logged in user

I have a question that deals with the logistics of returning rows of data in a SQL database (Entity Framework) based on the user that is logged in; I have mainly focused on desktop C# applications and while making the switch to ASP.NET MVC 4 I'm having a bit of difficulty when it comes to figuring this out (I've searched around and none of the answers seem to provide exactly what I'm looking for):
I would like to use the authorization built in to ASP.NET (MVC4), and allow users to post data about their websites (site category, url, age, etc.) with a form, and have the form store the data (using Entity Framework) to a database (called PrimaryDomainsDb) that is tied to their Id in the UserProfile table.
When the user clicks a button to show their list of domains, how can I make the application pull their list of domains (relevant rows of data) while ignoring other users rows?
Again, I'm mainly looking for the logistics and concepts (using foreign keys, for example) and psuedocode rather than actually spoonfeeding me a bunch of code.
If anyone has any best practice ideas (i.e. link the UserProfile to the PrimaryDomainDb this way, and use EF to call the rows matching their Id this way to return the rows to the View), it would be much appreciated.
Some sample code:
I currently have my PrimaryDomain code first set up like this (this doesn't have the decorators that specify min/max length, etc.):
public class PrimaryDomain
{
public virtual int Id { get; set; }
public virtual string SiteName { get; set; }
public virtual string SiteURL { get; set; }
public virtual SitePlatforms SitePlatform { get; set; }
public virtual decimal? SiteDA { get; set; }
public virtual decimal? SitePA { get; set; }
public virtual string SiteAge { get; set; }
public virtual DateTime? LastStatusUpdate { get; set; }
public virtual string SiteIP { get; set; }
}
And I have a User class that is different than the one provided by ASP.NET WebSecurity, that looks like this: (also, I know that "password" should not be in string formatting, this is just for initial set-up purposes - and password should probably be removed altogether and handled by WebSecurity, I think).
public class User
{
public virtual int Id { get; set; }
public virtual string Username { get; set; }
public virtual string Password { get; set; }
public virtual string Email { get; set; }
public virtual string FirstName { get; set; }
public virtual string LastName { get; set; }
public virtual string MozAccessID { get; set; }
public virtual string MozKey { get; set; }
public virtual decimal AccuountBalance { get; set; }
public virtual PrivateProxy PrivateProxies { get; set; }
public virtual PrimaryDomain PrimaryDomains { get; set; }
}
When pulling the data for Views I run everything through a repository using direct injection:
public interface IUserDataSource
{
IQueryable<User> Users { get; }
IQueryable<PrimaryDomain> PrimaryDomains { get; }
void Save();
}
This is my UserDb class, which is fed in whenever the code calls for an IUserDataSource (via direct injection):
public class UserDb : DbContext, IUserDataSource
{
public UserDb()
: base("DefaultConnection")
{
}
public DbSet<User> Users { get; set; }
public DbSet<PrimaryDomain> PrimaryDomains { get; set; }
IQueryable<User> IUserDataSource.Users
{
get { return Users; }
}
IQueryable<PrimaryDomain> IUserDataSource.PrimaryDomains
{
get { return PrimaryDomains; }
}
void IUserDataSource.Save()
{
SaveChanges();
}
}
And this is, for example, how I would pass the PrimaryDomains model to the View:
public class NetworkController : Controller
{
//
// GET: /Network/
private IUserDataSource _db;
public NetworkController(IUserDataSource db)
{
_db = db;
}
public ActionResult ListDomains()
{
var allDomains = _db.PrimaryDomains;
return View(allDomains);
}
}
But instead of pulling the entire PrimaryDomains list from the data source, I would like to add a way to reference the currently logged in user id to make the application only show the domains for that specific user, not all domains, and when adding a new domain via the form to reference the User Id and add it into the table as well.
My original question may have caused some confusion as to what I'm trying to achieve; It's my fault for posing the wrong way of going about what I'm trying to do. After much research and learning, I've found that exactly what I'm looking for is a multi-tenant data architecture approach.
This is probably what you are looking for. If I understood you correctly you want to use WebSecurity to login or register users but you want to use entity framework to store some user-specific data. Code below connects WebSecurity tables with your database CodeFirst created using EntityFramework.
You create class below (from tutorial).
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public sealed class InitializeSimpleMembershipAttribute : ActionFilterAttribute
{
private static SimpleMembershipInitializer _initializer;
private static object _initializerLock = new object();
private static bool _isInitialized;
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
// Ensure ASP.NET Simple Membership is initialized only once per app start
LazyInitializer.EnsureInitialized(ref _initializer, ref _isInitialized, ref _initializerLock);
}
private class SimpleMembershipInitializer
{
public SimpleMembershipInitializer()
{
try
{
if(!WebSecurity.Initialized)
WebSecurity.InitializeDatabaseConnection("ConnectionString", "DbUsers", "UserId", "Email", autoCreateTables: true);
}
catch (Exception ex)
{
throw new InvalidOperationException("The ASP.NET Simple Membership database could not be initialized. For more information, please see http://go.microsoft.com/fwlink/?LinkId=256588", ex);
}
}
}
}
It creates necessary tables for registering and logging your users. The magic is in second, third and fourth parameter. It is respectively table, userId column and userName column from YOUR database that you can create by EntityFramework. WebSecurity uses that table along with other self-generated tables to manage your users and let them register, login and so on.
Then in your code first you simply create table
public class DbUser
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
[MaxLength(40)]
public string Email { get; set; }
[MinLength(3)]
[MaxLength(30)]
[Required]
public string FirstName { get; set; }
[MinLength(3)]
[MaxLength(50)]
[Required]
public string LastName { get; set; }
}
Then you can simply query data from controller. In example below I use UserId stored by WebSecurity membership to retrieve account info from database.
public ActionResult AccountInfo()
{
if (FormsAuthentication.CookiesSupported == true && Request.Cookies[FormsAuthentication.FormsCookieName] != null)
{
var userId = WebSecurity.CurrentUserId;
var userInfo = context.Users.FirstOrDefault(x => x.UserId == userId);
userInfo.Password = "";
return View(userInfo);
}
else
{
ModelState.AddModelError("", "Wystąpił bląd autoryzacji, zaloguj się jeszcze raz.");
return RedirectToAction("Login", "Account");
}
}
EDIT:
Regarding your edited question as I understand besides the fact that you need to integrate WebSecurity with EF as above (I also forgot to mention that after creating InitializeSimpleMmebershipAttribute class as above you need to decorate your controller with that attribute) you also have problems with implementing generic repository. If that line is a problem:
var allDomains = _db.PrimaryDomains;
Then i suggest to read this article about implementing generic repository:
http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application
If you want thing realy simple all you need is just add to your interface method
GetDomainByUserId(int userId)
and just implement that interface like that:
public class UserDb : DbContext, IUserDataSource
{
public UserDb()
: base("DefaultConnection")
{
}
public DbSet<User> Users { get; set; }
public DbSet<PrimaryDomain> PrimaryDomains { get; set; }
IQueryable<User> IUserDataSource.Users
{
get { return Users; }
}
IQueryable<PrimaryDomain> IUserDataSource.PrimaryDomains
{
get { return PrimaryDomains; }
}
IQueryable<PrimaryDomain> GetDomainByUserId(int userId)
{
return PrimaryDomains.Where(x => x.Id == userId).ToQueryable();
}
void IUserDataSource.Save()
{
SaveChanges();
}
}
But this is very bad approach and I strongly recommend reading that article.

Which one is a better data design or object model?

Overview
I am designing a mechanism for generating dynamic controls in an ASP.NET MVC application that uses ADO.NET Entity Framework. However, my question has nothing to do with MVC and a little to do with the Entity Framework. It is about comparing two object models.
Problem Statement
In my app, a user must have the ability to interact with Web page A to specify that he wants to add such and such HTML controls to Web Page B.
When he browses Web Page B next, he must see those controls and be able to use them.
What Is Not The Challenge
I have written the code to generate the controls. That was the easy part. I used the Tag Builder, Partial Views, HtmlHelper extensions and Display & Editor templates.
The Challenge
The challenge is in arriving at a database design and an object model generated by Entity Framework to hold the metadata about the controls that need to be generated.
I have come up with a database design as shown below:
You may ignore the User and Permissions tables. They are not relevant to our discussion.
Entity Framework generates the following entities based on the above database design.
Let's call my database design as Design Option A.
I would have wanted a design that looked more like this:
Let's call this second design as Design Option B.
The code (stripped down version) for this second option would look like this:
namespace DynamicControls
{
public class DynamicControlGroup
{
public long Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string Controller { get; set; }
public IEnumerable<string> Actions { get; set; }
public DateTime StartDate { get; set; }
public DateTime? EndDate { get; set; }
public User CreatedByUser { get; set; }
public DateTime CreationDateTime { get; set; }
public User LastModifiedBy { get; set; }
public DateTime ModificationDateTime { get; set; }
// Navigational
public ICollection<DynamicControl<T>> DynamicControls { get; set; }
}
public class DynamicControl<T>
{
public long Id { get; set; } //db Id
public string HtmlId { get; set; }
public bool ValueRequired { get; set; }
public virtual ControlType ControlType { get; protected set; }
// Every control is capable of having a default value but of a different
// type. Most controls have default values of type text (string). The
// multi-select ones (checkboxes, multi-select lists, etc.) have a default
// value of type IEnumerable<string>. So, I want to leave this generic.
// But I am not that hung-up on this. I am fine if I am required to move
// this property DefaultValue from the base class and make it a concrete
// (not generic) property for each individual child class.
// Mostly I just want the heirarchy. And before that, I want to know
// if it is a good idea to model this heirarchy. Or is it better to just
// work with what my Entity Framework produced for my db?
// Should I change my db? I can because I thought-up the design for
// those tables.
public virtual T DefaultValue { get; set; }
// Navigational
public DynamicControlGroup DynamicControlGroup { get; set; }
}
public class TextBox : DynamicControl<string>
{
public override ControlType ControlType
{
get
{
return DynamicControls.ControlType.TextBox;
}
}
public string Label { get; set; }
public int MaxLength { get; set; }
}
public class PasswordControl : TextBox
{
public override ControlType ControlType
{
get
{
return DynamicControls.ControlType.Password;
}
}
}
public class TextArea : TextBox
{
public override ControlType ControlType
{
get
{
return DynamicControls.ControlType.TextArea;
}
}
public int Rows { get; set; }
}
public class DropDownList: DynamicControl<string>
{
public override ControlType ControlType
{
get
{
return ControlType.DropDownList;
}
}
// I want something like this. That I should be able to say
//
// myDropDownListObject.Options...
//
// You'll notice that given my current database design, I have
// no direct way of accessing the options of a, say, drop down list.
// To do that, I have to make a round-about Linq query.
public ICollection<DynamicControlOption> Options { get; set; }
}
public class DynamicControlOption
{
public long Id { get; set; } // db Id
public string OptionHtmlId { get; set; }
public string OptionValue { get; set; }
public string OptionText { get; set; }
// Navigational property
public DynamicControl<IEnumerable<string>> TheControlWhoseOptionIAm { get; set; }
}
public class User
{
}
public class Permission
{
}
public enum ControlType
{
TextBox,
TextArea,
Password,
RadioButton,
Checkbox,
DropDownList,
MultiSelectList,
DatePicker,
TimePicker,
DateTimePicker
}
}
My Question
1) I feel that I'd like Design Option B better. Am I feeling right?
2) I know I can work with Design Option A just as fine but it'll involve a little round-about way to do some things. For example, to get all the options for a drop down list, there's not navigational property on the DropDownList class in Design Option A. I'll have to write a round-about Linq query to do that.
3) Is it possible to have Entity Framework come close to generating Design Option B? How? What changes will I need to make to my database design to achieve that?
Now we are working on a Project like this at our company...
If I got your meaning correctly and If I were you...I implemented inherited structure as my database design like below.
Now you Classes are inheritance but your database design is not.
I have removed Id in TextBox and I have put ControlId as PK and FK in the same time. (not just FK).
in fact,ControlId is both PK for TextBox and FK from DynamicControl
and also this way for PasswordControl and TextArea
and Now ControlId in TextBox is not Identity. It gets it's ControlId from DynamicControl
I also accept Design Option B .I'm always more comfortable than using Design Option A.in my idea It's true and main structure

Using score field with SolrNet

I'm using SolrNet and have a problem where the score field is conflicting with documents being added or updated in the index.
The class representing my documents looks something like this
class MyDoc
{
[SolrUniqueKey("doc_id")]
public string DocId { get; set; }
[SolrField("foo")]
public string Foo { get; set; }
[SolrField("bar")]
public string Bar { get; set; }
[SolrField("score")]
public double Score { get; set; }
}
In the query being issued to Solr, I've added the 'score' field to the fl parameter, and the score value is returned and set correctly on this class. However, when adding or updating documents, I'm getting an error about the score field not existing in my index, which it doesn't, and shouldn't as this is a dynamic field.
The code doing the add/update is fairly simple:
Startup.Container.GetInstance<ISolrOperations<MyDoc>>().Add(doc);
It looks like I need the score property to be ignored by SolrNet (or Solr) when adding or updating documents, and only use it when retrieving documents.
Is there any way to achieve this?
I have accomplished this by having two separate classes. One that maps to documents being retrieved from the index as search results and another class that is used to add items to the index. So in this scenario you could do the following:
class MyDoc
{
[SolrUniqueKey("doc_id")]
public string DocId { get; set; }
[SolrField("foo")]
public string Foo { get; set; }
[SolrField("bar")]
public string Bar { get; set; }
}
class MyDocResult
{
[SolrUniqueKey("doc_id")]
public string DocId { get; set; }
[SolrField("foo")]
public string Foo { get; set; }
[SolrField("bar")]
public string Bar { get; set; }
[SolrField("score")]
public double Score { get; set; }
}
Be sure you initialize both classes pointing to the same solr url.
Startup.Init("http://localhost:8983/solr");
Startup.Init("http://localhost:8983/solr");
Then you can add with:
ServiceLocator.Current.GetInstance<ISolrOperations<MyDoc>>().Add(doc);
And Query with:
var solr ServiceLocator.Current.GetInstance<ISolrOperations<MyDocResult>>();
var results = solr.Query("foo bar");
You could also look into using the Dynamic or Fully Loose Mapping options for SolrNet if you do not want to create two separate classes.
If you make your POCO class have the Score as nullable you can use the same object for indexing and results
[SolrField("score")]
public double? Score { get; set; }

EF 4.1 Codefirst WPF Eager Loading Data Binding

I am having problems databinding to EF code first. I need to be using Eager Loading, but I am running into some issues with databinding. I have the following classes:
public class Context : DbContext
{
DbSet<A> As;
DbSet<B> Bs;
DbSet<C> Cs;
}
public class A
{
public ICollection<B> Bs { get; set; }
public string Name { get; set; }
}
public class B
{
public ICollection<C> Cs { get; set; }
public string Name { get; set; }
}
public class C
{
public string Name { get; set; }
}
I am data binding Context.As to a Treeview, using the below code:
Context.As.Load();
tvItems.ItemsSource = Context.As.Local;
This works as expected, however, it does not automatically load the child properties, Bs, and subsequently, Cs. So, I found that lazy loading can help with this, like so:
Context.As.Load();
tvItems.ItemsSource = Context.As.Include(u=>u.Bs);
From my reading, this should automatically load at least the first level of child properties. However, this will not data bind, as I did not use .Local
.Include() returns IQueryable, which does not support .Local. I can use .ToList(), but this will not automatically update when I add items.
So, how the hell am I supposed to be doing this?
You could try this:
Context.As.Include(a => a.Bs).Load();
tvItems.ItemsSource = Context.As.Local;

Resources