I followed the Windows Azure mobile service guide given by Microsoft over here.
I create a category class which represented the category table as follows:
public class category
{
public int Id { get; set; }
//// TODO: Add the following serialization attribute.
[JsonProperty(PropertyName = "name")]
public string Name { get; set; }
//// TODO: Add the following serialization attribute.
[JsonProperty(PropertyName = "subscribers")] //Number of Subscribers
public int Subscribers { get; set; }
[JsonProperty(PropertyName = "posts")] //Number of posts inside this category
public int Posts { get; set; }
}
I then inserted an entry into the database as give:
private IMobileServiceTable<category> categoryTable = App.MobileService.GetTable<category>();
category temp = new category() { Name = "test", Posts = 1, Subscribers = 2 };
await categoryTable.InsertAsync(temp);
All worked fine till here. Then i created a users class to represent the users table as follows:
class users
{
public int Id { get; set; } //the generated ID by the mobile service.
//// TODO: Add the following serialization attribute.
[JsonProperty(PropertyName = "name")]
public string Name { get; set; }
//// TODO: Add the following serialization attribute.
[JsonProperty(PropertyName = "nusnet")]
public string NUSNET { get; set; }
[JsonProperty(PropertyName = "email")]
public string Email { get; set; }
[JsonProperty(PropertyName = "faculty")]
public string Faculty { get; set; }
}
Now when I try to add in a user:
await userTable.InsertAsync(loggedInUser);
where logged in user is the details of the user. As given in the guide, i leave the Id filed empty and during debugging I notice that the Id is set as 0.
I get an error:
NewtonSoft.JSON.JsonSerializationException: {"Error getting value from 'Id' on 'NUSocial.users'."}
I have been trying fixing this for a while now but I have no clue on what is going wrong.
I think you'll need to apply the JSON attribute to the Id property. This is a sample of what my code, doing the same thing, looks like:
[DataContract]
public class Scores
{
[JsonProperty(PropertyName = "id")]
[DataMember]
public int Id { get; set; }
[JsonProperty(PropertyName = "UserName")]
[DataMember]
public string UserName { get; set; }
...
await scoresTable.InsertAsync(new Scores
{
UserName = _userName,
Score = (int) Score
});
Related
I am still new at ASP.NET MVC. I'm trying to add two objects to two different tables via one JSON POST request.
Here's more explanation:
I have this CAR entity:
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int CarId { get; set; }
[Required]
public double Price { get; set; }
[Required]
public DateTime Expiry { get; set; }
[Required]
public ICollection<Owner> Owners{ get; set; } = new List<Owner>();
}
I made a DTO for my CAR class which will help me create Cars normally. This is it, called CarForCreationDTO:
[Required(ErrorMessage = "Price is a required field.")]
public double Price{ get; set; }
[Required(ErrorMessage ="Expiry is a required field.")]
public DateTime Expiry { get; set; }
[Required(ErrorMessage ="Owners is a required field.")]
public ICollection<OwnerDTO> Owners { get; set; } = new List<OwnerDTO>();
Here is the OwnerDTO:
public string Name { get; set; }
public DateTime DateOfBirth { get; set; }
public int CarId { get; set; }
Now, when I post a request to add a Car, I need to provide a price, an expiry date and a list of owners.
So, normally, my JSON request should like this:
{
"Price": "2020-03-28T00:00:00",
"Expiry": "2020-05-28T00:00:00",
"Owners": [
{
"Name":"Some Name",
"DateOfBirth":"2001-03-28T00:00:00"
}
]
}
In my CarController.cs, I did this to be able to add to the database both the Owner object and then the Car object :
[HttpPost]
public IActionResult CreateCar([FromBody] CarForCreationDTO car)
{
//Some validation ...
var finalCar = _mapper.Map<Entities.Car>(car);
foreach(var o in finalCar.Owners)
{
var finalOwner = _mapper.Map<Entities.Owner>(o);
o.CarId= finalCar.CarId;
_repository.AddOwner(finalOwner);
_repository.Save();
}
_repository.AddCar(finalCar);
_repository.Save();
var createdCar = _mapper.Map<Entities.Car>(finalCar);
return CreatedAtRoute("GetCar", new { id = createdCar.CarId},
createdCar);
I am sadly getting a 500 Bad Request and I know it's from the "Owners" list but I don't know why that's happening. Does anyone have any idea how I can fix this because I am not finding any solutions to my problem.
Am I doing something wrong?
Thanks a lot,
Jane
I'm trying to add a group Id to the database but my data model has type "Group" how can I achieve adding a GroupId without sending the whole object
Here is my Data model class
public class Tool : IObjectBase
{
public Group Group { get; set; } // My problem is here
public string Code { get; set; }
public string Name { get; set; }
public string Statut { get; set; }
public string StorageLocation { get; set; }
public string Description { get; set; }
public DateTime? CalibrationDate { get; set; }
public string InventoryNumber { get; set; }
public string SerialNumber { get; set; }
public string Contact { get; set; }
public string Image { get; set; }
public string StandardLoanPeriod { get; set; }
using Entity Framework core I was able to add this class as a table to the database and of course ef will make that group object as an GroupId in the table
So now in my angular application, I am trying to add a new Tool to the database using this Method
AddNewTool(form: NgForm) {
this.tool = {
Id : form.value.Id,
Code: form.value.Code,
Name: form.value.Name,
Description: form.value.Description,
Image: '',
Group: this.Group // Probleme is here
};
this.service.AddTool(this.tool).subscribe(
res => {
this.ToolToReload.emit(this.service.getTools());
this.toolRowInformation = null;
console.log(res);
form.resetForm();
} ,
err => {
console.log(err);
});
}
Now, whenever I add a new tool it works and the groupId get filled with that group but at the same time, that group added to the group table in the database.
I tried sending only the GroupId from angular but I get an error telling that the Tool is Expecting a Group object not a string.
My question is is it possible to add a tool with a groupId without sending the whole Group Object?
You need to have a GroupId property in your data model class as well as the group object.
This way, you can send the GroupId to and from the client and also access the Group navigation property in your data model class:
public int GroupId { get; set; }
I'll try to explain this the best that I can so it makes sense.
I have two Models - BuyerProfile and Producerprofile
BuyerProfile
public class BuyerProfile : IAuditTrack
{
[KeyProperty(Identity = true)]
public int Id { get; set; }
[Required]
public string UserId { get; set; }
[Required]
public string Name { get; set; }
[Required]
public int BuyerTypeId { get; set; }
[Required]
public string Address { get; set; }
[Required]
public string City { get; set; }
[Required]
public string State { get; set; }
public string Zipcode { get; set; }
public string Description { get; set; }
[NonStored]
public string BuyerTypeDisplay { get; set; }
}
ProducerProfile
public class ProducerProfile : IAuditTrack
{
[KeyProperty(Identity = true)]
public int Id { get; set; }
[Required]
public string UserId { get; set; }
[Required]
public string Name { get; set; }
[Required]
public string Address { get; set; }
[Required]
public string City { get; set; }
[Required]
public string State { get; set; }
public string Zipcode { get; set; }
public string Description { get; set; }
}
I have a simple method on my controller that retrieves all of the profiles in the database and concatenates them together.
[HttpGet]
public JsonResult GetAllProfiles()
{
var buyerProfiles = _profileService.GetAllBuyerProfiles();
var producerProfiles = _profileService.GetAllProducerProfiles();
var profiles = buyerProfiles.Concat(producerProfiles);
return Json(profiles, JsonRequestBehavior.AllowGet);
}
Now what I would like to do is be able to find every BuyerProfile and ProducerProfile that share the same UserId and merge them together into a new model that would look like this:
public class BuyerProducerprofile
{
public string UserId { get; set; }
public string BuyerName { get; set; }
public string ProducerName { get; set; }
}
The current system that I'm building only allows users to complete 1 BuyerProfile and 1 ProducerProfile.
So for example, in the result set I might have a BuyerProfile that contains the following information:
Id -> 1543
UserId -> abc123
Name -> Bob's Buying Company
and a ProducerProfile that contains the following information:
Id -> 1678
UserId -> abc123
Name -> Bob's Produce Company
I would like to be able to combine the two into my new model so that it looks something like this:
UserId -> abc123
BuyerName -> Bob's Buying Company
ProducerName -> Bob's Produce Company
I'm not sure if this is at all possible without using some kind of Nuget package but it would be awesome if I didn't have to use one that I don't already have.
I also am currently using AutoMapper to do some of my mapping but I couldn't find any documentation that shows being able to use it to do this.
what you want to do is called a join. you can do it like this
var buyerProfiles = _profileService.GetAllBuyerProfiles();
var producerProfiles = _profileService.GetAllProducerProfiles();
var combinedProfiles =
from bp in buyerProfiles
join pp in producerProfiles on bp.UserId equals pp.UserId
select new BuyerProducerprofile()
{
UserId = pp.UserId,
BuyerName = bp.Name,
ProducerName = pp.Name
}
note: if the same user can have more than one of a type of profile, this will return a result for every combination of buyer profile and producer profile that can be made for that user.
other note: this is what is called an "inner join", and it will only give you results for users that have both profiles. You can do other kinds of joins too, but syntax for those joins doesn't feel very natural, and I don't have them committed to memory. I'm sure a google search can find the syntax for you.
I have problems with gerenating types, it returns error
500 - InvalidDataException
I can't understand whats wrong as my project builds fine and API works.
None of the types works except the metadata
https://testapi.bokamera.se/types/
Please help as i'm stuck
Regards Kristian
Here you can see my call using Postman
and here you can see my DTO causing the problem
namespace BokaMera.API.ServiceModel.Dtos
{
[Route("/customfields",
Verbs = "GET",
Summary = "Find custom fields",
Notes =
"Find custom fields defined for the bookings that the current admin user is authorized to view."
)]
[ApiResponse(HttpStatusCode.Unauthorized, "You were unauthorized to call this service")]
[ApiResponse(HttpStatusCode.Forbidden, "You have too low privilegies to call this service")]
public class CustomFieldQuery :
QueryBase<CustomFieldConfig, CustomFieldQueryResponse>
{
[ApiMember(
Description =
"One or multiple id's of custom fields to find",
ParameterType = "query",
IsRequired = false)]
public int[] Ids { get; set; }
[ApiMember(
Description =
"Company id to find custom fields for",
ParameterType = "query",
IsRequired = false)]
public Guid? CompanyId { get; set; }
[ApiMember(
Description =
"Table to which the custom field belongs to",
ParameterType = "query",
IsRequired = false)]
public string Table { get; set; }
[ApiMember(
Description =
"Active or removed fields, empty parameter includes both",
ParameterType = "query",
IsRequired = false)]
public bool? Active { get; set; }
}
public class CustomFieldQueryResponse
{
[ApiMember(Description = "Custom field id")]
public int Id { get; set; }
[ApiMember(Description = "Reference to company that owns the custom field configuration")]
public Guid CompanyId { get; set; }
[ApiMember(Description = "Group id")]
public int? GroupId { get; set; }
[ApiMember(Description = "Config id")]
public int ConfigId { get; set; }
[ApiMember(Description = "Configuration name. Example: \"Number of persons\".")]
public string ConfigName { get; set; }
[ApiMember(Description = "Field width. Example: 20")]
public int Width { get; set; }
[ApiMember(Description = "Column in database where to store the information. Example: \"TextField1\"")]
public string Column { get; set; }
[ApiMember(Description = "Custom field description. Example: \"For how many persons is this booking?\"")]
public string Description { get; set; }
[ApiMember(Description = "Data field of custom field. Valid values are: TextBox, ... Example: \"TextBox\"")]
public string DataType { get; set; }
[ApiMember(Description = "Default value of the field. Example: \"3\"")]
public string DefaultValue { get; set; }
[ApiMember(Description = "Determines if the field is required to have a value or not")]
public bool Required { get; set; }
[ApiMember(Description = "Error message shown to the user if the field data is required but not entered")]
public string MandatoryErrorMessage { get; set; }
[ApiMember(Description = "Max lenght of the field")]
public int MaxLength { get; set; }
[ApiMember(Description = "")]
public bool MultipleLineText { get; set; }
[ApiMember(Description = "Regular expression used for validation of the field")]
public string RegEx { get; set; }
[ApiMember(Description = "Error message shown if the regular expression validation failed")]
public string RegExErrorMessage { get; set; }
[ApiMember(Description = "If the custom field is active or have been removed")]
public bool Active { get; set; }
[ApiMember(Description = "Table to which the field belongs")]
public string Table { get; set; }
[ApiMember(Description = "")]
public List<CustomFieldLookupResponse> Values { get; set; }
}
[Alias("V_FreeFieldFieldLookUp")]
public class CustomFieldLookupResponse
{
[PrimaryKey]
[Alias("FieldLookupId")]
public int? Id { get; set; }
[Alias("FreeFieldId")]
public int CustomFieldId { get; set; }
[Alias("FieldlookupActive")]
public bool? Active { get; set; }
[Alias("FieldLookupGroupId")]
public int GroupId { get; set; }
[Alias("FieldlookupSortOrder")]
public int? SortOrder { get; set; }
[Alias("FieldlookupValue")]
public string Value { get; set; }
}
//Used when sending in values on a DTO request object to the services to save on the tables.
public class CustomFieldDataValue
{
public int Id { get; set; }
public string Column { get; set; }
public string Value { get; set; }
}
//Used to list all values on a DTO response object
public class CustomFieldData
{
public int Id { get; set; }
public string Column { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string Value { get; set; }
}
//Used when post or put values for different DTOS, see example Resource Dtos
public class AddCustomField
{
public int Id { get; set; }
public string Value { get; set; }
}
}
And my service
namespace BokaMera.API.ServiceInterface.Services
{
public class CustomFieldService : AppServiceBase
{
public IAutoQueryDb AutoQuery { get; set; }
[Authenticate]
[RequiredRole(Role.ApplicationAdmin)]
public object Get(CustomFieldQuery request)
{
// Get the autoquery that we will append to
var q = AutoQuery.CreateQuery(request, Request.GetRequestParams());
// The user can only see his/her own time exceptions
q = q.Where(te => te.CompanyId == UserSession.CompanyId);
// Execute counts and return the query response
var response = AutoQuery.Execute(request, q);
return response;
}
}
}
If you were on v4.0.58, it had an issue with Add ServiceStack Reference which can be resolved by upgrading to any release after that.
The issue with your DTOs was because they contained illegal " character in the Metadata attributes, i.e:
[ApiMember(Description = "Configuration name. Example: \"Number of persons\".")]
public string ConfigName { get; set; }
We validate metadata attributes to prevent an attacker from potentially injecting illegal data that they could use to generate malicious in Service consumers.
So to prevent the error you can remove double quotes (") from strings in your metadata attributes, replacing them with single quotes (') is fine, otherwise you can disable token verification in your AppHost.Configure() with:
NativeTypesFeature.DisableTokenVerification = true;
Incidentally Exception details from Code Generation will be more visible in the next release from this commit, so it will be clearer to tell what the error was.
Deprecated Warnings
Please take note of the Deprecation messages (also covered in Breaking changes in each Release Notes). QueryBase has been renamed to QueryDb, e.g:
public class CustomFieldQuery :
QueryDb<CustomFieldConfig, CustomFieldQueryResponse>
Also it's better for your custom AutoQuery implementations to pass the entire IRequest instead of just the parameters, e.g:
var q = AutoQuery.CreateQuery(request, base.Request);
This has the same behavior except it also allows this AutoQuery Service to participate in Multitenancy requests.
First, sorry for my english ;)
I have the next classes that represents a person which can have many email accounts and each of those accounts have its respective email messages
public class Person
{
public string Id { get; set; }
public string Name { get; set; }
public EmailAccount[] Accounts { get; set; }
}
public class EmailAccount
{
public string Id { get; set; }
public string Name { get; set; }
public Message[] Messages { get; set; }
}
public class Message
{
public string Date { get; set; }
public string Content { get; set; }
}
I need to replace the messages of particular email account, but i need first do a select by person id and account id, how can i do this with Mongodb c# driver, I made something like this but without success:
var collection = _mongoDatabase.GetCollection<Person>("Person");
var query = Query.EQ("Person._id", "20");
var bsonMessages = BsonDocumentWrapper.CreateMultiple(new[]
{
new Message(DateTime.Now.ToString(CultureInfo.InvariantCulture), "Test 55"),
new Message(DateTime.Now.ToString(CultureInfo.InvariantCulture), "Test 66")
});
var messageArray = new BsonArray(bsonMessages);
var update = Update.Set("Accounts.$.Messages", messageArray);
collection.Update(query, update, UpdateFlags.Upsert);
As you can see, I do the filter the person by its Id but I don't know how to add the second filter to select an account by its Id
I appreciate any help ;)