How to Retrieve Systems Properties from Azure Mobile Services .Net Backend - xamarin

How can I retrieve the System Properties of "__createdAT" and "__updatedAT" from an Azure Mobile Service Table (.Net Backend). I see that these values exist on the Azure SQL Server.
This is my backing Model Class
public class Customer : EntityData
{
public string CustomerName { get; set; }
public string CustomerEmail { get; set; }
public string PhoneNumber { get; set; }
public string CardUid { get; set; }
}
And I can confirm that the columns are created at the Azure Mobile Services backing SQL Backend
And here is my Xamarin Android model class
public class Customer
{
public string id { get; set; }
[JsonProperty(PropertyName = "customerName")]
public string CustomerName { get; set; }
[JsonProperty(PropertyName = "customerEmail")]
public string CustomerEmail { get; set; }
[JsonProperty(PropertyName = "phoneNumber")]
public string PhoneNumber { get; set; }
[JsonProperty(PropertyName = "cardUid")]
public string CardUid { get; set; }
[CreatedAt]
public DateTime EnrollmentDate { get; set; }
[UpdatedAt]
public DateTime LastTransactionDate { get; set; }
}
However, this does not return the values, here is what it returns to the Xamarin.Android client
Even the web Try it out does not return the CreatedAT and UpdatedAT column, how can I return these columns to the clients.
Thanks

In the client SDK you need to specify that you want the system properties returned (they are not by default).
In C# you would do something like this:
customerTable = myAzClient.GetTable<Customer>;
customerTable.SystemProperties = MobileServiceSystemProperties.CreatedAt | MobileServiceSystemProperties.UpdatedAt;
var customers = await customerTable.ReadAsync();
You can see more in Carlos' blog post

Try renaming you CreatedAt and UpdatedAt Properies in your client side DTO classes.
public class Customer
{
....
[CreatedAt]
public DateTime CreatedAt{ get; set; }
[UpdatedAt]
public DateTime UpdatedAt{ get; set; }
}
This worked for me the last time

Related

How to handle char property properly in Hotchocolate Graphql 12.0?

I am trying to implement filtering on Resource table which has MartialStatus of char property in DDL of database.Let my show you my approach first. In my program.cs file, i have the following:
using LIS.ResourcePlanningSystem.API;
using LIS.ResourcePlanningSystem.Data;
using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddDbContext<RpsDbContext>(options => options.UseLazyLoadingProxies().UseNpgsql(builder.Configuration.GetConnectionString("RPSDbContext")));
builder.Services.AddGraphQLServer().
RegisterDbContext<RpsDbContext>().
AddQueryType<Query>().
AddProjections().
AddFiltering().
AddSorting().
BindRuntimeType<char, StringType>().
AddTypeConverter<char, string>(from => from.ToString()).
AddTypeConverter<string, char>(from => from.ToCharArray()[0]);
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.MapGraphQL("/graphql");
app.Run();
Here is my a model Register.cs which has "MaritalStatus" char property.
public class Resource
{
public int Id { get; set; }
public string? FirstName { get; set; }
public string? MiddleName { get; set; }
public string? LastName { get; set; }
public string? FullName { get; set; }
public char? MaritalStatus { get; set; }
public virtual Gender? Gender { get; set; }
public virtual Education? Education { get; set; }
public int? InstitutionId { get; set; }
public string? PerStreet { get; set; }
public DateTime? OfficeJoinDt { get; set; }
public virtual Grade? Grade { get; set; }
public int? PositionId { get; set; }
public virtual Department? Department { get; set; }
public virtual ClientType? ClientType{ get; set; }
public int? ExpOut { get; set; }
public string? ResignedFlag { get; set; }
public string? Email { get; set; }
public virtual BloodGroup? BloodGroup { get; set; }
public virtual ResignedRemarks? ResignedRemark { get; set; }
public virtual Source? Source { get; set; }
}
Now, the program runs just fine until i add [UseFiltering] on the Resource table in query.cs file.
[UseFiltering]
[UseSorting]
public IQueryable<Resource>? GetResources(RpsDbContext context) => context.Resources;
The error i am getting is this:
HotChocolate.SchemaException: For more details look at the `Errors` property.
1. For more details look at the `Errors` property.
1. The type of the member MaritalStatus of the declaring type Resource is unknown
If i remove the [UseFiltering] [UseSorting], the program works fine. I think the problem is related to filtering on resource table. Filtering also work fine on all the other tables which doesn't have char property in its schema definition. Someone has opened a bug issue on github [here] . Tried to solve reading this issue but no luck. Could somebody please tell me how can i get around this problem?

How to create one-to-many related object in ASP.NET Web API?

I have two entities
public class Tax
{
public int Id { get; set; }
public string Name { get; set; }
public int ClientId { get; set; }
public Client Client { get; set; }
}
public class Client
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<Tax> Taxes { get; set; }
}
and in this method, I want to create a relationship between Client and Tax using ClientId, but i am getting The Client field is required error on client side, so I want to ignore field Client.
My question is how to ignore fielf client or if I'm doing something wrong, then how to create one-to-many relationship in Post method? (I'm new to ASP.NET so sorry if this is a stupid question.)
[HttpPost]
public IActionResult Post(Tax tax)
{
tax.Client = (from c in context.Clients
where c.Id == tax.ClientId
select c).FirstOrDefault<Client>();
context.Taxes.Add(tax);
context.SaveChanges();
return Created("api/taxes", tax);
}
you just need to make ClientId nullable. It will do the same as an optioanal.
public int? ClientId { get; set; }
public Client Client { get; set; }
or if you use net 6 you will have to make Client nullable too
public int? ClientId { get; set; }
public Client? Client { get; set; }
but you can remove nullable option from project to avoid all this extra problems forever
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<!--<Nullable>enable</Nullable>-->
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
in this case, if tax has a ClientId already, you only need
context.Taxes.Add(tax);
context.SaveChanges();

Automapper Many to Many Mapping Including Joining Table Data

I am developing an ASP.Net Core Web API using EF Core Code First (C#) and SQL Server.
I have a fairly simple scenario which I just cannot figure out. I have a Form entity and a Site entity. Each Form can have many Sites and each Site can be in many Forms. To enable this I have a SiteForm joining table. For each Site associated with a Form there is a Leaving Date field. So my SiteForm class looks like this:
public class SiteForm
{
public Guid SiteId { get; set; }
public Site Site{ get; set; }
public Guid FormId { get; set; }
public Form Form{ get; set; }
public DateTime? LeavingDate { get; set; }
}
My Form's Data Transfer Object (FormDto) is as follows:
public class FormDto
{
public Guid Id { get; set; }
...
public ICollection<LinkedSiteDto> LinkedSites { get; set; }
= new List<LinkedSiteDto>();
}
And my LinkedSiteDto is like this:
public class LinkedSiteDto
{
public Guid Id { get; set; }
public string Name { get; set; }
public string Ident { get; set; }
public DateTime? LeavingDate { get; set; }
}
Having populated the database I can get the Sites for each Form using the following mapping:
CreateMap<Form, FormDto>()
.ForMember(dto => dto.LinkedSites, opt => opt.MapFrom(
form => form.SiteForms.Select(sf => sf.Site).ToList()));
I just cannot figure out how I would include the LeavingDate value from each joining table entry? Any suggestions would be very gratefully received.

"Not Found" Exception when trying to call UpdateAsync or InsertAsync

I'm creating a pretty basic Azure Mobile App based on the TodoItem example, and i'm running into a weird issue. I can connect to the table controller and call ToEnumerableAsync (GET) without issue, but as soon as I call UpdateAsync or InsertAsync, I get a 404 (Not Found) response. I tried recreating the table controller, disabling authentication etc. to no avail.
Log stream on Azure sees the PATCH message and returns the 404. Not terribly helpful...
my DTO looks like this:
public class Patient : EntityData
{
public string PersonalHealthNumber{ get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime? DateOfBirth { get; set; }
}
and my client-side patient looks like this:
public class Patient
{
public string Id { get; set; }
public string PersonalHeathNumber { get; set; }
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
public DateTime? DateOfBirth { get; set; }
[Version]
public string Version { get; set; }
}
Try derive your client model from that TableData base class and remove the 2 properties Id and Version from your client model because they are in the base class

Updating one of the related entity

I'm developing bulletin board system (as part of my training of asp.net mvc). I have a basic understanding of data modeling, but I have a doubt the way I've created my model. The core logic is to post ad with the following categories realty, auto and service. Initially I tried to use TPH approach, but then faced with problem of binding my models and automapper configuration. Now I think to use zero or one relationship.
I have a Ad model:
public class Ad
{
public int ID { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public virtual Realty Realty { get; set; }
public virtual Auto Auto { get; set; }
public virtual Service Service { get; set; }
}
Realty:
public class Realty
{
[Key]
[ForeignKey("Ad")]
public int AdID { get; set; }
public string Type { get; set; }
public string NumberOfRooms { get; set; }
public virtual Ad Ad { get; set; }
}
Auto and service models have the same foreign key as the Realty model.
My db context:
public DbSet<Ad> Ads { get; set; }
public DbSet<Realty> Realties { get; set; }
public DbSet<Auto> Autos { get; set; }
public DbSet<Service> Services { get; set; }
I need update Ad model with one related model only. I'm using scaffolded controller action, which includes all related models:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create([Bind(Include = "Title,Descirpiton,Realty,Auto,Service")] Ad ad)
{
if (ModelState.IsValid)
{
db.Ads.Add(ad);
await db.SaveChangesAsync();
return RedirectToAction("Index");
}
ViewBag.ID = new SelectList(db.Autos, "AdID", "CarType", ad.ID);
ViewBag.ID = new SelectList(db.Realties, "AdID", "Type", ad.ID);
ViewBag.ID = new SelectList(db.Services, "AdID", "ServiceType", ad.ID);
return View(ad);
}
The problem, that it makes possible to post Ad with all related models together. Before diving deep I wanted to ensure that I'm on a right way of doing this.
Thanks.
You're close. Based on what it looks like you're trying to do you should be using a table-per-type model. You create the base (Ad) and then inherit from it to create the sub-types.
public class Ad
{
[Key]
public int ID { get; set; }
public string Title { get; set; }
public string Description { get; set; }
}
[Table("Realty")]
public class Realty : Ad
{
public string Type { get; set; }
public string NumberOfRooms { get; set; }
}
Your context remains the same. You can now create the appropriate sub-type when you know what kind of ad is being created.
var ad = new Realty();
ad.Title = "...";
ad.Description = "...";
ad.Type = "...";
ad.NumberOfRooms = "...";
You can retrieve specific ad types by using the specific type on the context.
db.Realty.ToList();
Or you can retrieve all the ads and interrogate the types as you loop over them.
var ads = db.Ads.ToList();
foreach(var ad in ads)
{
if(ad is Realty)
// do Realty stuff
else if (ad is Auto)
// do Auto stuff
}

Resources