Mapping JSON data to model and back in MVC 4 - c#

Pardon any misspeaking I may do. I am just learning asp.net c#, OOP, and MVC 4.
I am using the Annotator plugin on my site and I am trying to store and retrieve the results from a data base. When a new annotation is created it sends information like this to the controller.
{
"text":"asdas sd a dasd as dasd",
"ranges":
[{
"start":"/div/p[3]",
"startOffset":195,
"end":"/div/p[3]",
"endOffset":532
}],
"quote":"Some quote that was selected.",
"UserID":"1",
"ProjectDocID":"1"
}
Now, I hoped something like this would load all the data into a nice easy object.
// GET: /Annotation/Create
public ActionResult Create(Comment comment)
{
db.Comments.Add(comment);
db.SaveChanges();
return Json(comment);
}
The model I had looked like this (and I am change it however it needs to be changed).
public class Comment
{
[Key]
public int CommentID { get; set; }
public int ProjectDocID { get; set; }
public int UserID { get; set; }
public string text { get; set; }
public string Annotation { get; set; }
public string quote { get; set; }
public string start { get; set; }
public string end { get; set; }
public string startOffset { get; set; }
public string endOffset { get; set; }
public DateTime DateCreated { get; set; }
public virtual ICollection<CommentVote> CommentVote { get; set; }
public virtual ICollection<CommentReply> CommentReply { get; set; }
public ProjectDoc ProjectDoc { get; set; }
public virtual User User { get; set; }
}
What do I need to do to get the data from the server and map it to the model. I also need to be able to send it back in the format at the top so the plugin understands it when it asks for it from the Details action in the controller.

Not sure if this is the right way to do it or not, but it lets me store it in the database and that's all that matter for the moment. I updated my model as follows.
public class Comment
{
[Key]
public int CommentID { get; set; }
public int ProjectDocID { get; set; }
public int UserID { get; set; }
public string text { get; set; }
public string quote { get; set; }
public DateTime DateCreated { get; set; }
public virtual ICollection<CommentVote> CommentVote { get; set; }
public virtual ICollection<CommentReply> CommentReply { get; set; }
public ProjectDoc ProjectDoc { get; set; }
public virtual User User { get; set; }
public List<ranges> ranges { get; set; }
}
public class ranges {
public int ID { get; set; }
public string start { get; set; }
public string end { get; set; }
public string startOffset { get; set; }
public string endOffset { get; set; }
}
This matches the JSON object I am sending in to the controller with Ajax. Once it matches exactly the controller action above works.

Related

Query with four tables in ASP.net using lambda expression

I have a web page that allows user to sign petitions, in the user detail page I want to display the petitions the user has signed, including the petition image. The image is specific to the category of the petition.
I have a category model that holds the image
public class Category
{
public int CategoryID { get; set; }
public string Name { get; set;}
public string catImage { get; set; }
public ICollection<Cause> Causes { get; set; }
}
Then I have a cause model that links to the Category through CategoryID
public class Cause
{
public int CauseID { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public int UserID { get; set; }
public string createdBy { get; set; }
public DateTime createdOn { get; set; }
public int Target { get; set; }
public int CategoryID { get; set; }
public virtual ICollection<Signature> Signatures { get; set; }
public Category Category { get; set; }
}
Then a signature model that links the Cause to the User
public class Signature
{
public int SignatureID { get; set; }
public int CauseID { get; set; }
public int UserID { get; set; }
public DateTime signedOn { get; set; }
public virtual Cause Cause { get; set; }
public virtual User User { get; set; }
}
And finally a user model
public class User
{
public int ID { get; set; }
public string Username { get; set; }
public string Email { get; set; }
public string Password { get; set; }
public string UserImage { get; set; }
public Role Role { get; set; }
public virtual ICollection<Signature> Signatures { get; set; }
}
On the user details page I am trying to display a table with a list of all the petitions the user has signed. I have been able to show the name and the date shown, but not the images.
I would really appreciated any help.
Thanks

C# mongodb model like Facebook

I'm working on a project where the MongoDB model will be similar to Facebook. So we all know how FB works, a user "likes" a band/company page, and that user will see all the posts from that page.
Is the below model how I should design this?
If a Page has million likes, then each Post will have a million sub documents of Like. That does not seem right, there must be a better way that I cant think of.
Thanks.
public class Person
{
public ObjectId Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class Page
{
public ObjectId Id { get; set; }
public string Name { get; set; }
public List<Like> PersonLikes { get; set; }
}
public class Like
{
public ObjectId Id { get; set; }
public ObjectId UserId { get; set; }
public DateTime DateLiked { get; set; }
}
public class Post
{
public ObjectId Id { get; set; }
public ObjectId PageId { get; set; }
public string Message { get; set; }
public List<Like> PersonLikes { get; set; }
}
My take assuming you only want to track likes
public class Page
{
public ObjectId Id { get; set; }
public DateTimeOffset Date { get; set; }
public string Name { get; set; }
public int NumberOfLikes { get; set; }
}
public class Post
{
public ObjectId Id { get; set; }
public ObjectId PageId { get; set; }
public DateTimeOffset Date { get; set; }
public string Message { get; set; }
public int NumberOfLikes { get; set; }
}
I would then queue the Reaction (Like or Dislike) for insertion, "sentiment" information doesn't have to be stored in real time, does it? These are not medications, bank transactions, etc.
public class Like
{
public ObjectId Id { get; set; }
public ObjectId ParentId { get; set;}
public ObjectId UserId { get; set; }
public DateTimeOffset Date { get; set; }
}
Queue where? to a collection of Likes. Why not part of the page or post? Because if a post goes viral (as you said even though the majority won't), you may end up with a 1,000,000 likes. Who is going to browse this information other than an analytic engine?
You also have to ensure a user can only express their reaction only once per item.
The post only exists on one page so it´s the page that should own the post, not the post owning the page.
public class Person
{
public ObjectId Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class Page
{
public ObjectId Id { get; set; }
public string Name { get; set; }
public List<Like> PersonLikes { get; set; }
public List<Post> Posts { get; set; }
}
public class Post
{
public ObjectId Id { get; set; }
public string Message { get; set; }
public List<Like> Likes { get; set; }
}
public class Like
{
public ObjectId Id { get; set; }
public ObjectId UserId { get; set; }
public DateTime DateLiked { get; set; }
}

Code-First SQL Server ASP.NET MVC6

I am a VB.NET programmer, but I am trying to learn C# and MVC in my spare time. I am using ASP.NET MVC 5.1.0.0 and I am trying to do code-First database creation in a local instance of SQL Server.
I was able to get the first database table to update in the database when I ran Update-Database from within the IDE, but when I added a second table that has a PK/FK relationship with the first, I am getting a red line under [ForeignKey] which reads
Does not contain a constructor that takes 1 arguments
I have been searching all over and not getting anywhere. Any suggestions or help would be appreciated. By the way, the first table is a PK/FK relationship to the AspNetUsers table.
public class BuildDatabase : IdentityUser
{
public virtual Companies Companies { get; set; }
public virtual NotaryProfile NotaryProfile { get; set; }
}
public class Companies
{
[Key]
[Column("CompanyID")] // Did this as the database will reflect TableName_ColumnName instead.
public int CompanyID { get; set; }
public string CompanyName { get; set; }
public bool IsActive { get; set; }
public bool IsNotary { get; set; }
public virtual ICollection<NotaryProfile> NotaryProfile { get; set; }
}
public class NotaryProfile
{
[Key]
public int NotaryID { get; set; }
public string NamePrefix { get; set; }
public string FirstName { get; set; }
public string MiddleInitial { get; set; }
public string LastName { get; set; }
public string NameSuffix { get; set; }
public bool IsActive { get; set; }
public int DefaultState { get; set; }
public int DefaultCounty { get; set; }
public bool IsSigningAgent { get; set; }
public bool HasABond { get; set; }
public decimal BondAmount { get; set; }
public bool HasEandO { get; set; }
public decimal EandOAmount { get; set; }
public bool ElectronicNotarizationsAllowed { get; set; }
public string ElectronicTechnologyUsed { get; set; }
public string ComissionNumber { get; set; }
public DateTime CommissionIssued { get; set; }
public DateTime CommssionOriginal { get; set; }
public DateTime CommissionExpires { get; set; }
public DateTime CommissionFiledOn { get; set; }
public string SOSAuditNumber { get; set; }
public string CommissionDesc { get; set; }
[Foreignkey("CompanyID")] // Companies.CompanyID = PK
public int CompanyID { get; set; } // PK/FK relationship.
public Companies Companies { get; set; } // Reference to Companies table above.
}
public class SchemaDBContext : IdentityDbContext<BuildDatabase>
{
public SchemaDBContext()
: base("DefaultConnection"){}
public DbSet<Companies> Companies { get; set; }
public DbSet<NotaryProfile> NotaryProfile { get; set; }
}
One of your classes (probably NotaryProfile) needs to reference another object (the foreign key relationship) but there is no constructor in that class that accepts an argument to establish that relationship, e.g.:
public NotaryProfile(int companyId) {
this.companyId = companyId;
}
BTW, a better way to establish that relationship is to use the actual class type rather than the ID, as in:
public class NotaryProfile {
...
public Company Company { get; set; }
// Instead of this:
// public int CompanyID { get; set; } // PK/FK relationship.
...
}
See also:
C# “does not contain a constructor that takes '1' arguments”
Does not contain a constructor that takes 2 arguments

Properly splitting up code for SQL Database in CodeFirst

I've got a little problem with my database design in an EntityFramework6 project. These are my two code first classes I use to create the database with. As you can see the Details class violates all normal forms out there and I want to split it up properly, however I have no idea how to do it properly, since I am totally new to SQLServer and EF.
So what is the best way to get a decent database design which I then could query?
internal class LocationDataContract
{
[Key]
public Guid Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public DbGeography Coordinates { get; set; }
public LocationsDetailsDataContract Details { get; set; }
}
internal class LocationDetailsDataContract
{
[Key, ForeignKey("Location")]
public Guid Id { get; set; }
public string Planet { get; set; }
public bool? IsCapital { get; set; }
public int Population { get; set; }
public string System { get; set; }
public string Sector { get; set; }
public LocationDataContract Location { get; set; }
}
Updated Question below
So following the advice of George I did the following. Would this be a decent solution. I Have to add, that I need to to some converting since the application uses different (completely inheritance based) models, which I have to use since a database is not the only source of data and said data uses yet another format to store data which I can't change.
internal class LocationDataContract
{
[Key]
public Guid Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public DbGeography Coordinates { get; set; }
public LocationsDetails Details { get; set; }
}
internal abstract class LocationDetailDataContract
{
[Key, ForeignKey("Location")]
public Guid Id { get; set; }}
public LocationsDetails Details { get; set; }
}
internal class CityDetailDataContract : LocationDetailDataContract
{
public string Planet { get; set; }
public bool? IsCapital { get; set; }
public int Population { get; set; }
}
internal class PlantDetailDataContract : LocationDetailDataContract
{
public int Population { get; set; }
public string System { get; set; }
}
internal class SystemDetailDataContract : LocationDetailDataContract
{
public string Sector { get; set; }
}
internal class SectorDetailDataContract : LocationDetailDataContract
{
// For now nothing
}
#Ruhrpottpatriot, why all classe are inheriting from LocationDetailDataContract?
Doing this i believe you will have a buch of classes and tables but the data will remain desnormalized (ex: CityDetailDataContract will have the column Planet with repeated strings.
Are you allowed to do something like this from you original question?
internal class LocationDataContract
{
[Key]
public Guid Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public DbGeography Coordinates { get; set; }
public LocationDetailsDataContract Details { get; set; }
}
internal class LocationDetailsDataContract
{
[Key, ForeignKey("Location")]
public Guid Id { get; set; }
public Planet Planet { get; set; }
public System System { get; set; }
public Sector Sector { get; set; }
[Required]
public LocationDataContract Location { get; set; }
}
internal class Planet {
[Key]
public Guid Id { get; set; }
public string Name { get; set; }
public bool? IsCapital { get; set; }
public int Population { get; set; }
}
internal class System {
[Key]
public Guid Id { get; set; }
public string Name { get; set; }
}
internal class Sector {
[Key]
public Guid Id { get; set; }
public string Name { get; set; }
}

Windows 8 C#/XAML SuspensionManager failed

I'm writing simple imageviewer for one imageboard. I'm using these 2 classes for navigation(navigation parameter for Frame.Navigate() method) in my app:
public class KonaParameter
{
public int page { get; set; }
public string tags { get; set; }
public KonaParameter()
{
page = 1;
}
}
public class Post
{
public int id { get; set; }
public string tags { get; set; }
public int created_at { get; set; }
public int creator_id { get; set; }
public string author { get; set; }
public int change { get; set; }
public string source { get; set; }
public int score { get; set; }
public string md5 { get; set; }
public int file_size { get; set; }
public string file_url { get; set; }
public bool is_shown_in_index { get; set; }
public string preview_url { get; set; }
public int preview_width { get; set; }
public int preview_height { get; set; }
public int actual_preview_width { get; set; }
public int actual_preview_height { get; set; }
public string sample_url { get; set; }
public int sample_width { get; set; }
public int sample_height { get; set; }
public int sample_file_size { get; set; }
public string jpeg_url { get; set; }
public int jpeg_width { get; set; }
public int jpeg_height { get; set; }
public int jpeg_file_size { get; set; }
public string rating { get; set; }
public bool has_children { get; set; }
public object parent_id { get; set; }
public string status { get; set; }
public int width { get; set; }
public int height { get; set; }
public bool is_held { get; set; }
public string frames_pending_string { get; set; }
public List<object> frames_pending { get; set; }
public string frames_string { get; set; }
public List<object> frames { get; set; }
public object flag_detail { get; set; }
}
The problem I faced is that suspending doesn't work. SuspensionManager throws "SuspensionManager failed" exception after await SuspensionManager.SaveAsync(); call(I googled that it's because of using complex types).
I tried to use string as a navigation parameter. It works, but I need more than 1 string for my parameter(List<string> doesn't work, I tried to use it).
How to suspend my app correctly?
The problem is that SuspensionManager uses Frame.GetNavigationState() to get the history of the Frame. It then tries to serialise the navigation history to a string, unfortunately it has no way to know how to serialise custom complex types as parameters like Post or KonaParameter and fails with an exception.
If you want to use SuspensionManager then you'll need to restrict yourself to simple types like int or string as parameters.
If you do need complex types then it's best to store them in some background service / repository with an identifier. You can then pass the identifier as the parameter.
The recommended approach is to serialize your "state" object, so it can be saved/restored as a string. You can use Json.NET to do this:
//save state
Post post = //...;
string state = JsonConvert.Serialize(post)
//restore state
Post post = JsonConvert.Deserialize<Post>(state);
If you want to use two objects (a Post and a KonaParameter), I'd consider creating an "aggregate" class that encapsulates both, and serializing/deserializing that instead:
public class State
{
public Post post {get; set;}
public KonaParameter param {get; set;}
}

Categories