Entity null - Linq to SQL - linq-to-sql

I need some help...
I have my entity that i have create manually.
public class Project()
{
public Project Data {get;set;}
public string ProjectID { get; set; }
public string AreaID { get; set; }
public string Country { get; set; }
}
Where property "Project" is the the table created by SQLmetal.
I have also created my class, with SQLmetal, wish there have there own entity.
Now i trying to parse between them in the constructor like:
public Project()
{
ProjectID = Data.ProjectID;
AreaID = Data.AreaID;
Country = Data.Country;
}
But when I use
projects.Select(p => new Project { Data = p });
the Data property in the constructor is null.
Any idea why? and how will I solve this the better way?

Yes, because the initializer
var x = new Project { Data = p };
is equivalent to
var x = new Project();
x.Data = p;
The Data property is set AFTER the constructor.
You can solve it by creating a constructor that takes Data as a parameter
public Project(Data data)
{
this.Data = Data;
ProjectID = Data.ProjectID;
AreaID = Data.AreaID;
Country = Data.Country;
}
and call the constructor
projects.Select(p => new Project(p));

Related

Is Identity Core 2 IdentityRole missing defintions for Users?

Am I missing something or has the definition for Users been removed from IdentityRole in Identity Core 2?
I am using asp.net core 2 and I need to calculate the number of users per role. This worked just fine in Core 1 with the following standard code
public class ApplicationRoleController : Controller
{
private readonly RoleManager<ApplicationRole> roleManager;
public ApplicationRoleController(RoleManager<ApplicationRole> roleManager)
{
this.roleManager = roleManager;
}
[HttpGet]
public IActionResult Index()
{
List<ApplicationRoleListViewModel> model = new List<ApplicationRoleListViewModel>();
model = roleManager.Roles.Select(r => new
{
RoleName = r.Name,
Id = r.Id,
Description = r.Description,
NumberOfUsers = r.Users.Count
}).ToList()
.Select(r => new ApplicationRoleListViewModel
{
RoleName = r.RoleName,
Id = r.Id,
Description = r.Description,
NumberOfUsers = r.NumberOfUsers
}).ToList();
return View(model);
}
In My application using Core 2, the line NumberOfUsers = r.Users.Count, where r is derived from the class ApplicationRole with the error that "ApplicationRole does not contain a definition for Users" The ApplicationRole inherits from IdentityRole.
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using System;
public class ApplicationRole : IdentityRole
{
public string Description { get; set; }
public DateTime CreatedDate { get; set; }
public string IPAddress { get; set; }
}
You can use this
var admins = _userManager.GetUsersInRoleAsync("Admin").Result;
var number = admins.Count;
The issue with Core 2 apparently is that they forgo the navigation properties in
AspNetUsers AspNetUserRoles AspNetRoles. No idea why. Its very frustrating to be honest. Supposedly you can re-implement them, but so far I had no luck. I am here trying to find a way to list all users with all their roles.
I think the above code is what you need tho.
Also _userManager is imported as such in a controller
private readonly UserManager<ApplicationUser> _userManager;
public MyControllerController(DBContext context, UserManager<ApplicationUser> userManager)
{
this.context = context;
_userManager = userManager; ;
}

Don't get data to my list from my model (Table)

I'm trying to get the data from my database in SQL, I use entity. This is my function in my controller:
public JsonResult getProductCategories()
{
List<Categories> category = new List<Categories>();
using (MasterDetailsEntities1 dc = new MasterDetailsEntities1())
{
category = dc.Categories.OrderBy(a => a.CategoryName).ToList(); -- I make a break here and doesn't pass anything and I have data in my table Categories.
}
return new JsonResult { Data = category, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
}
What I want to do is pass all the data from my model or table Categories to the list but it does pass me anything, i'm new doing this I don't know if I'm doing the right way.
This is my model:
public partial class Categories
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Categories()
{
this.Products = new HashSet<Products>();
}
public int CategoryID { get; set; }
public string CategoryName { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Products> Products { get; set; }
}
}
So, your problem here is not related to JSON result..it's for db not returning data from the table.
Please check your connection string for the MasterDetailsEntities1 context.
Do you get data from any other table using the same context? Please check.
Nothing looks improper here.

UWP: Nested Custom Types with DataContractJsonSerializer

I am creating a nested custom type with primitive datatypes.
I am having a Web APi that returns the data in JSON.
using json2csharp.com, I am generating classes for the same.
I have decorated the primitive datatypes in all classes with DataMember and the types with DataContract.
I am using the following code for deserialization:
var resp = httpClient.GetAsync("http://ACTUAL_API_URI").Result;
var res = await resp.Content.ReadAsStringAsync();
var serializer = new DataContractJsonSerializer(typeof(RootObject));
byte[] byteArr= Encoding.ASCII.GetBytes(res);
var ms = new MemoryStream(byteArr);
var deserializedObj= (RootObject)serializer.ReadObject(ms);
I am not getting any exception. but the deserializedObj has null values for all the properties.
Any suggestions ?
You have a couple mistakes.
You returns collection of elements and try to deserialize one element instead collection
public IEnumerable<SampleData> Get()
{
return new SampleData[]
{
new SampleData()
{
Value = 100,
NestedTypeObject1 = new NestedType1()
{
ID = 101,
BD = "Description#1",
UD = "Description#2"
},
NestedTypeObject2 = new NestedType2()
{
Date = DateTime.Now.ToString(),
S1 = "S1 String",
S2 = "S2 String"
}
}
};
}
so you just change your code to
var serializer = new DataContractJsonSerializer(typeof(List<RootObject>));
var deserializedObj= (List<RootObject>)serializer.ReadObject(ms);
You have different model names between service side and client side, just you your SampleData model and all will be good. You must to rename MyNestedType1 to NestedTypeObject1 or add name to DataContractAttribute, e.g:
[DataContract(Name = "NestedTypeObject1")]
public class MyNestedType1
{
[DataMember]
public int Id { get; set; }
[DataMember]
public string BD { get; set; }
[DataMember]
public string UD { get; set; }
}
It belongs for property names too.

jQuery Bootgrid - Ajax Sort Parameter with ASP.NET MVC Actions

I managed to create an ApiController retrieving data from my repositories, and populating a grid in my view through Bootgrid with Ajax. This is an example of request data sent to Api's Action, given by their Docs here (look for POST Body Request tab):
current=1&rowCount=10&sort[sender]=asc&searchPhrase=&id=b0df282a-0d67-40e5-8558-c9e93b7befed
Here is an example URL:
http://localhost/api/SomeController?current=1&rowCount=10&sort%5BName%5D=asc&searchPhrase=&id=b0df282a-0d67-40e5-8558-c9e93b7befed
I created two Helper classes to handle data I must return as response, and sort data (as it's an array):
public class SortData
{
public string Field { get; set; } // FIeld Name
public string Type { get; set; } // ASC or DESC
}
public class BootgridResponseData<T> where T: class
{
public int current { get; set; } // current page
public int rowCount { get; set; } // rows per page
public IEnumerable<T> rows { get; set; } // items
public int total { get; set; } // total rows for whole query
}
Therefore, my action is as follow:
public BootgridResponseData<SomeViewModel> Get(int current, int rowCount, List<SortData> sort, string searchPhrase, string id)
{
// get items and return a bootgrid response data with them...
}
The method is invoked and all parameters come with data properly, except sort, which is always null.
What kind of parameter should I expect for this? I also tried to put object but it comes null anyway.
After learning a bit more, I saw Bootgrid has a requestHandler setting which allows you to manipulate data sent to server.
I did it in my javascript like this:
var grid = $("#my-grid").bootgrid({
ajax: true,
rowCount: 10,
ajaxSettings: {
method: "POST",
cache: true
},
requestHandler: function (request) {
// Scan the original sort object from Bootgrid...
// and populate an array of "SortData"...
request.sortItems = [];
if (request.sort == null)
return request;
for (var property in request.sort) {
if (request.sort.hasOwnProperty(property)) {
request.sortItems.push({ Field: property, Type: request.sort[property] });
}
}
return request;
},
url: "/api/FooApi"
});
Then I created my post action in API like this:
public class FooApiController : ApiController
{
[HttpPost]
public BootgridResponseData<FooModel> Get(BootgridRequestData model)
{
// This would come from some data store, using the request params...
// I use PagedList to make pagination easier...
IPagedList<FooModel> itemsPaged = store.GetPagedFoo();
// Then return the response with data...
return new BootgridResponseData<FooModel>()
{
current = model.current,
rowCount = model.rowCount,
rows = itemsPaged,
total = itemsPaged.TotalItemCount
};
}
}
The BootgridResponseData has already been shown in my question. I just added a BootgridRequestData which the following structure:
public class BootgridRequestData
{
public int current { get; set; }
public int rowCount { get; set; }
public string searchPhrase { get; set; }
public IEnumerable<SortData> sortItems { get; set; }
}
Then I could even use my original SortData helper class:
public class SortData
{
public string Field { get; set; } // FIeld Name
public string Type { get; set; } // ASC or DESC
}
I've struggled with this as well. You are overthinking it. It's nice to create simple models to handle the post call from jquery-bootgrid, but you can also just use simple parameters in the post method. As for the sort, it looks like a Key-Value pair, but that doesn't serialize properly.
I ended up trying a Dictionary object and it works.
Here is my signature:
[HttpPost]
public async Task<ActionResult> GetActiveDogs(int? current, int? rowCount,
Dictionary<string, string> sort, string searchPhrase = null)
I had the same problem passing the sort options to my webservice. The Dictionary object did not solve my problem either.
To solve it, I created a class holding string properties for each field I wanted to pass through the bootgrid sort options. See code excerpt
class TestSort
{
public string field1 { get; set; }
public string field2 { get; set; }
...
}
I use this class as the sort options parameter in my webservice. All fields in this class that are referred to by the bootgrid options are set to "ASC" or "DESC". The others remain null.
I added an 'orderBy' property to this class that returns an orderby clause for the fields that are not null.
Approch1.
consider you have table with columns "col1, col2, col3, ...".
you can use:
public ActionType Get(int current, int rowCount, Sort sort, string searchPhrase) {
//sort.col1 == 'asc' (consider sorted by col1 in ascending order)
}
public class Sort
{
public string col1 { get; set; }
public string col2 { get; set; }
public string col3 { get; set; }
//... other columns
}
Approach 2.
You can use remove you parameters and parse request data manually. i used post here instead of get.
[HttpPost]
public object Post(){
string jsonContent = Request.Content.ReadAsStringAsync().Result;
Dictionary<string, string> keyvalues = new Dictionary<string, string>();
string[] keyvalue_strings = jsonContent.Split('&');
string sort_column = "";
string sort_direction = "";
for (var i = 0; i< keyvalue_strings.Length; i++)
{
var a = keyvalue_strings[i].Split('=');
a[0] = a[0].Replace("%5B", "[").Replace("%5D", "]");
keyvalues.Add(a[0], (a[1]));
if (a[0].Contains("sort"))
{
sort_column = a[0].Replace("sort[", "").Replace("]", "");
sort_direction = a[1];
}
}
//now you have keyvalues, sort_column, sort_direction.
//...
}

BSON Object Being Partially Deserialized

I'm trying to deserialize a BSON HTTP Response Message from a Web API call into a custom type.
using (HttpClient client = new HttpClient())
{
client.BaseAddress = new Uri("http://localhost:1234");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/bson"));
HttpResponseMessage result;
result = await client.GetAsync("/endpoint/");
MediaTypeFormatter[] formatters = new MediaTypeFormatter[] {
new BsonMediaTypeFormatter()
};
if (result.IsSuccessStatusCode)
{
try
{
RootObject res = await result.Content.ReadAsAsync<RootObject>(formatters);
}
catch (Exception e)
{
}
}
I know the Web API is returning BSON, I checked through Fiddler and the above code actually does deserialize most things correctly in the RootObject. It appears that all of the derived classes are not being deserialized and are just being input into the object as null. Here is an example of a derived class that is not being deserialized.
RootObject.Events.Teams.Linescores
RootObject
[DataContract(Namespace = "", Name = "RootObject")]
[Serializable]
public class RootObject: infoBase
{
[DataMember(EmitDefaultValue = false, Order = 30)]
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, Order = 30)]
public IEnumerable<eventInfo> events { get; set; }
public RootObject() { }
}
Events Object
[DataContract(Namespace = "", Name = "event")]
[Serializable]
[KnownType(typeof(subEventTeam))]
public class eventInfo : infoBase
{
[DataMember(EmitDefaultValue = false, Order = 170)]
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, Order = 170)]
public List<eventTeamBase> teams { get; set; }
public eventInfo() { }
}
Teams Base and Specific Team Type
[DataContract(Namespace = "", Name = "team")]
[Serializable]
[KnownType(typeof(bbLinescoreInfo))]
public class eventTeamBase : infoBase {
[DataMember(Order = 20)]
[JsonProperty(Order = 20)]
public string location { get; set; }
[DataMember(Order = 30, EmitDefaultValue = false)]
[JsonProperty(Order = 30, NullValueHandling = NullValueHandling.Ignore)]
public string nickname { get; set; }
[DataMember(EmitDefaultValue = false, Name = "linescores", Order = 130)]
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, Order = 130)]
public IEnumerable<linescoreBase> linescores { get; set; }
public eventTeamBase() { }
}
[DataContract(Namespace = "", Name = "team")]
[Serializable]
public class subEventTeam : eventTeamBase
{
public subEventTeam () { }
}
Linescore Base and Specific Object
[DataContract(Name = "linescores", Namespace = "")]
[Serializable]
[KnownType(typeof(subLinescoreInfo))]
public class linescoreBase : infoBase
{
public bool isProcessing = false;
public int teamId { get; set; }
public linescoreBase() { }
}
[DataContract(Name = "linescores", Namespace = "")]
[Serializable] public class subLinescoreInfo : linescoreBase
{
[DataMember]
public int inning { get; set; }
[DataMember]
public int? score { get; set; }
public subLinescoreInfo() { };
}
Here is the deserialized (and then re-serialized) part of the response that isn't working output into JSON.
{
"status":"OK",
"recordCount":1,
"RootObject":[
{
"events":[
{
"teams":[
{
"location":"Tallahassee",
"nickname":"Razors",
"linescores":[
{},{},{},{},{},{},{},{}]
}
}
}
}
So as you can see, it is filling in some information correctly (There is a lot more, I've cut down significantly just to illustrate the problem). But the linescores are returning null. As mentioned, the data is returning correctly and it is not null.
I feel like I'm doing something wrong with the known types and I've tried numerous combinations of putting them in different places and the results don't change. Any help would greatly appreciated.
After much searching and trying wrong things, I found a similar solution in another thread.
JSON Solution
I solved this by doing pretty much that exact same thing but with BSON instead of JSON.
This is the code that I needed to add in the global config file of the Web API
BsonMediaTypeFormatter bsonFormatter = new BsonMediaTypeFormatter();
bsonFormatter.SerializerSettings.TypeNameHandling = TypeNameHandling.Objects;
bsonFormatter.AddQueryStringMapping("accept", "bson", "application/bson");
GlobalConfiguration.Configuration.Formatters.Add(bsonFormatter);
And this code went into the client.
BsonMediaTypeFormatter bsonFormatter = new BsonMediaTypeFormatter();
bsonFormatter.SerializerSettings.TypeNameHandling = TypeNameHandling.Objects;
MediaTypeFormatter[] formatters = new MediaTypeFormatter[] {
bsonFormatter
};
Everything else remained the same and was deserialized without incident.