asp.net json string to de-serialize into varibales - asp.net

I'm new to json and I need help with following json string, I need to fetch values into string variables to save into db.
{
"message_id": {"8624389": "447123456789"},
"sent_text": "Test message",
"parts_count": 1
}
how can I get values of message_id, sent_text and parts_count into variables?
Thanks

I use this website:https://app.quicktype.io/
It uses newtonsoft nuget package. With a little tweaking it saves alot of time.
// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do:
//
// using MyNamespace;
//
// var myObject = MyObject.FromJson(jsonString);
namespace MyNamespace
{
using System;
using System.Net;
using System.Collections.Generic;
using Newtonsoft.Json;
public partial class MyObject
{
[JsonProperty("message_id")]
public MessageId MessageId { get; set; }
[JsonProperty("sent_text")]
public string SentText { get; set; }
[JsonProperty("parts_count")]
public long PartsCount { get; set; }
}
public partial class MessageId
{
[JsonProperty("8624389")]
public string The8624389 { get; set; }
}
public partial class MyObject
{
public static MyObject FromJson(string json) => JsonConvert.DeserializeObject<MyObject>(json, MyNamespace.Converter.Settings);
}
public static class Serialize
{
public static string ToJson(this MyObject self) => JsonConvert.SerializeObject(self, MyNamespace.Converter.Settings);
}
public class Converter
{
public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
{
MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
DateParseHandling = DateParseHandling.None,
};
}
}

Related

WEB API .NET 5 Stream JSON objects to the client fetch request

With the following source code I am able to stream JSON objects via ASP.NET Web API, that's fine & cool !
I would like to migrate this source code to .NET 5. Since PushStreamContent class is not provided any more, Can anyone help me to facing with solution ? Any reference or examples are kindly accepted.
Mersi
using Newtonsoft.Json;
using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
namespace WebApplication1.Controllers
{
public class ValuesController : ApiController
{
[HttpGet]
public HttpResponseMessage GetMultipartData()
{
var response = new HttpResponseMessage();
var content = new PushStreamContent(new Action<Stream, HttpContent, TransportContext>(WriteContent), "application/json");
response.Headers.TransferEncodingChunked = true;
response.Content = content;
return response;
}
public static void WriteContent(Stream stream, HttpContent content, TransportContext context)
{
var serializer = JsonSerializer.CreateDefault();
using (var sw = new StreamWriter(stream))
using (var jw = new JsonTextWriter(sw))
{
jw.WriteStartArray();
foreach (var id in Enumerable.Range(1, 100000))
{
serializer.Serialize(jw, new TestModel()
{
Alias = "rvhuang",
BirthDate = new DateTime(1985, 02, 13),
FirstName = "Robert",
LastName = "Huang",
ID = id,
MiddleName = "Vandenberg",
});
}
jw.WriteEndArray();
}
}
}
public class TestModel
{
public string FirstName
{
get; set;
}
public string MiddleName
{
get; set;
}
public DateTime BirthDate
{
get; set;
}
public string LastName
{
get; set;
}
public string Alias
{
get; set;
}
public int ID
{
get; set;
}
}
}

Can't Figure Out How To Use AutoMapper With Post Action In RESTful Api

I have a simple RESTful API and this is the post route handler I'm trying to apply AutoMapper in:
[HttpPost]
[Route("[action]")]
public async Task<IActionResult> CreateHotel([FromBody]Hotel hotelCreateDto)
{
var hotel = _mapper.Map<Hotel>(hotelCreateDto);
var createdHotel = await _hotelService.CreateHotel(hotel);
var hotelReadDto = _mapper.Map<HotelReadDto>(createdHotel);
return CreatedAtAction("GetHotelById", new { id = hotelReadDto.Id }, hotelReadDto);
}
So in the request I get a hotelCreateDto which looks like that:
public class HotelCreateDto
{
[StringLength(50)]
[Required]
public string Name { get; set; }
[StringLength(50)]
[Required]
public string City { get; set; }
}
and I map this to Hotel entity:
public class Hotel
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[StringLength(50)]
[Required]
public string Name { get; set; }
[StringLength(50)]
[Required]
public string City { get; set; }
}
and a new hotel object is created in the next line. However when hotelReadDto is going to be assigned to the new mapped object, a 500 error occurs: "AutoMapper.AutoMapperMappingException: Missing type map configuration or unsupported mapping."
Could you catch a mistake here? I don't know where I'm doing wrong.
Edit: there'S also this things after the error above: "Mapping types:
Object -> HotelReadDto
System.Object -> HotelFinder.DTO.DTOs.HotelReadDto"
Edit2: Here is the code in the Configure Services:
services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
And in the Profile class:
public class HotelProfile : Profile
{
public HotelProfile()
{
CreateMap<Hotel, HotelReadDto>();
CreateMap<HotelCreateDto, Hotel>();
}
}
Add this in your services in startup :
it's reusable and cleaner
public void ConfigureServices(IServiceCollection services)
{
services.AddAutoMapper(Assembly.GetExecutingAssembly());
}
add these interface and class in your project
public interface IMapFrom<T>
{
void Mapping(Profile profile) => profile.CreateMap(typeof(T), GetType());
}
using AutoMapper;
using System;
using System.Linq;
using System.Reflection;
public class MappingProfile : Profile
{
public MappingProfile()
{
ApplyMappingsFromAssembly(Assembly.GetExecutingAssembly());
}
private void ApplyMappingsFromAssembly(Assembly assembly)
{
var types = assembly.GetExportedTypes()
.Where(t => t.GetInterfaces()
.Any(i =>i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IMapFrom<>)))
.ToList();
foreach (var type in types)
{
var instance = Activator.CreateInstance(type);
var methodInfo = type.GetMethod("Mapping")
?? type.GetInterface("IMapFrom`1").GetMethod("Mapping");
methodInfo?.Invoke(instance, new object[] { this });
}
}
}
and your dto be like this (map hotel to HotelDto):
public class HotelCreateDto : IMapFrom<HotelCreateDto>
{
[StringLength(50)]
[Required]
public string Name { get; set; }
[StringLength(50)]
[Required]
public string City { get; set; }
public void Mapping(Profile profile)
{
profile.CreateMap<Hotel,HotelCreateDto>();
}
}

create Multiple tables using Sqlite-net-pcl

I am using xamarin forms and Sqlite-net-pcl (nuget). I need help on creating multiple tables. I have set up the requirements as below. I need to do the following:
1) I need to create tables and database when the App launches. How to do this in App.cs?
Update Problem:
1) Tables are not created. Why?
---1--- in PCL : add these
-- classes for table
using SQLite;
namespace MyApp.Model
{
[Table("TblCountry")]
public class Country
{
public string Country { get; set; }
public string CountryCode { get; set; }
public string OfficialLanguage { get; set; }
}
[Table("TblEmployees")]
public class Employee
{
[PrimaryKey, AutoIncrement]
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address { get; set; }
}
}
--- interface class
using System;
using System.Collections.Generic;
using System.Text;
using SQLite;
namespace MyApp.DataAccessHelpers
{
public interface ISQLite
{
SQLiteConnection GetConnection();
}
}
---2---in Xamarin.Droid: I add this class
using SQLite;
using System.IO;
using Xamarin.Forms;
using MyApp.Droid.Implementation;
using MyApp.DataAccessHelpers;
[assembly: Xamarin.Forms.Dependency(typeof(AndroidSQLite))]
namespace MyApp.Droid.Implementation
{
class AndroidSQLite : ISQLite
{
public SQLite.SQLiteConnection GetConnection()
{
string documentsPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments);
var path = Path.Combine(documentsPath, DatabaseHelper.DbFileName);
var conn = new SQLite.SQLiteConnection(path);
return conn;
}
}
}
------- Update :
public class DatabaseHelper
{
static SQLiteConnection sqliteconnection;
public const string DbFileName = "MyDb.db3";
public DatabaseHelper()
{
try
{
sqliteconnection = DependencyService.Get<ISQLite>().GetConnection();
sqliteconnection.CreateTable<CountryModel>();
sqliteconnection.CreateTable<EmployeeModel>();
}
catch (Exception ex)
{
string strErr = ex.ToString();
}
}
public List<CountryModel> GetAllCountry()
{
return (from data in sqliteconnection.Table<CountryModel>()
select data).ToList();
}
public CountryModel GetCountryByHuNbr(string name)
{
return sqliteconnection.Table<CountryModel>().FirstOrDefault(c => c.Name == name);
}
public void DeleteAllCountry()
{
sqliteconnection.DeleteAll<CountryModel>();
}
public void DeleteCountryByid(int ID)
{
sqliteconnection.Delete<CountryModel>(ID);
}
public void InsertCountry(CountryModel country)
{
sqliteconnection.Insert(country);
}
public void UpdateCountry(CountryModel country)
{
sqliteconnection.Update(country);
}
//------- CRUD for employee
public void InsertEmployee(EmployeeModel employee)
{
sqliteconnection.Insert(employee);
}
.....
... and all the CRUD for employee
}
}
Thanks in advance.
I created a helper class which contains all methods I need in order to interact with SQLite Database. I use the CreateTable() to create a table.
In App.xaml.cs file, I create an instance of my DataAccess helper class and I call the CreateLocalDbTables() method.
DataAccessHelper
public class DataAccess : IDisposable
{
private SQLiteConnection Connection;
#region Constructor
public DataAccess(ISQLitePlatform sQLitePlatform, string dbPath)
{
this.Connection = new SQLiteConnection(sQLitePlatform, dbPath);
}
#endregion
#region Methods
public void CreateLocaldbTables()
{
this.Connection.CreateTable<Registration>();
this.Connection.CreateTable<TransmissionLog>();
this.Connection.CreateTable<Parameters>();
this.Connection.CreateTable<Guest>();
}
In APP.xaml.cs
public partial class App : Application
{
#region Properties
public static DataAccess DBConnection { get; set; }
#endregion
public App(string localDbPath, ISQLitePlatform sqlitePlatform)
{
InitializeComponent();
DBConnection = new DataAccess(sqlitePlatform,localDbPath);
DBConnection.CreateLocaldbTables();
Model
namespace AppRegistration.Models
{
using SQLite;
using System;
[Table("Activity")]
public class Actividad
{
[Column("IdActivity")]
[PrimaryKey, Autoincrement]
public int IdActivity { get; set; }
[Column("IdEvent")]
[PrimaryKey]
public int IdEvent { get; set; }
[Column("ActivityDescription")]
[NotNull]
public string ActivityDescription { get; set; }
[Column("Status")]
[NotNull]
public string Status { get; set; }
[Column("UserId")]
[NotNull]
public int UserId { get; set; }
}
}

Add tags to talk for many to many relationship in Entity Framework

I am creating an API endpoint that creates a new Talk with the tags that should be associated to the talk. I have a many to many relationship set up between tags and talks in my domain, see below for the relationship.
Tag.cs
using System;
using System.Collections.Generic;
namespace Conferency.Domain
{
public class Tag : IAuditable
{
public int Id { get; set; }
public string Name { get; set; }
public List<TalkTag> TalkTags { get; set; }
public DateTime ModifiedAt { get; set; }
public DateTime CreatedAt { get; set; }
}
}
Talk.cs
using System;
using System.Collections.Generic;
namespace Conferency.Domain
{
public class Talk : IAuditable
{
public int Id { get; set; }
public string Name { get; set; }
public string Url { get; set; }
public List<TalkTag> TalkTags { get; set; }
public DateTime Presented { get; set; }
public DateTime ModifiedAt { get; set; }
public DateTime CreatedAt { get; set; }
}
}
TalkTag.cs
using System;
using System.Collections.Generic;
using System.Text;
namespace Conferency.Domain
{
public class TalkTag
{
public int TalkId { get; set; }
public Talk Talk { get; set; }
public int TagId { get; set; }
public Tag Tag { get; set; }
}
}
ConferencyContext.cs (Deleted irrelevant code)
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;
using System;
using Conferency.Domain;
namespace Conferency.Data
{
public class ConferencyContext: DbContext
{
public DbSet<Talk> Talks { get; set; }
public DbSet<Tag> Tags { get; set; }
public DbSet<TalkTag> TagTalks { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<TalkTag>()
.HasKey(s => new { s.TalkId, s.TagId });
modelBuilder.Entity<TalkTag>()
.HasOne(pt => pt.Talk)
.WithMany(p => p.TalkTags)
.HasForeignKey(pt => pt.TalkId);
modelBuilder.Entity<TalkTag>()
.HasOne(pt => pt.Tag)
.WithMany(t => t.TalkTags)
.HasForeignKey(pt => pt.TagId);
base.OnModelCreating(modelBuilder);
}
}
}
TalkViewModel.cs
using System;
using System.Collections.Generic;
namespace Conferency.Application.Models
{
public class TalkViewModel
{
public string Name { get; set; }
public string Url { get; set; }
public List<String> Tags { get; set; }
}
}
The problem is I can't figure out how to create a talk and its tags (attach if they exists, create if they don't). I am not sure in what order to accomplish this. Do I have to query each tag to check if they exist or is there a findOrCreate method I could use? How do I create a TalkTag record if the Talk isn't created yet? Is there an elegant way to accomplish this that I am not understanding?
TalkRepository.cs
using System.Collections.Generic;
using Conferency.Domain;
using Microsoft.EntityFrameworkCore;
using System;
using System.Linq;
using System.Threading.Tasks;
namespace Conferency.Data
{
public class TalkRepository : ITalkRepository
{
private ConferencyContext _context;
public TalkRepository(ConferencyContext context)
{
_context = context;
}
public void Add(Talk entity)
{
_context.Add(entity);
}
public void AddWithTags(Talk entity, List<String> tags)
{
// Create Talk
// Query for each tag
// Create if they don't exist
// Attach to talk
// ??
}
public IEnumerable<Talk> GetAllTalks()
{
return _context.Talks
.Include(c => c.TalkTags)
.OrderBy(c => c.Presented)
.ToList();
}
public Talk GetTalk(int id)
{
return _context.Talks
.Include(c => c.TalkTags)
.Where(c => c.Id == id)
.FirstOrDefault();
}
public async Task<bool> SaveAllAsync()
{
return (await _context.SaveChangesAsync()) > 0;
}
}
}
I am new to c# and I'm trying to learn best practices and familiarizing myself with EF and ASP.NET Core so hopefully somebody can help guide me in the right path. The full solution is here if you want to take a look https://github.com/bliitzkrieg/Conferency
I tried solving it myself but Im getting a NullPointerException, here is my attempt at a solution:
TalksController.cs
[HttpPost()]
public async Task<IActionResult> Post([FromBody]TalkViewModel model)
{
try
{
_logger.LogInformation("Creating a new Talk");
List<Tag> tags = _tagRepo.FindOrCreateTags(model.Tags);
Talk talk = new Talk { Name = model.Name, Url = model.Url };
List<TalkTag> talkTags = new List<TalkTag>();
tags.ForEach(tag =>
{
var talkTag = new TalkTag { TagId = tag.Id, Talk = talk };
talkTags.Add(talkTag);
});
talk.TalkTags.AddRange(talkTags); // Exception being thrown here
_repo.Add(talk);
if (await _repo.SaveAllAsync())
{
string newUri = Url.Link("TalkGet", new { id = talk.Id });
return Created(newUri, talk);
}
else
{
_logger.LogWarning("Could not save Talk");
}
}
catch (Exception ex)
{
_logger.LogError($"Threw exception while saving Talk: {ex}");
}
return BadRequest();
}
}
TagRepository.cs
using System;
using System.Collections.Generic;
using Conferency.Domain;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using System.Linq;
namespace Conferency.Data
{
public class TagRepository: ITagRepository
{
private ConferencyContext _context;
public TagRepository(ConferencyContext context)
{
_context = context;
}
public void Add(Tag entity)
{
_context.Add(entity);
}
public List<Tag> FindOrCreateTags(List<string> tags)
{
List<Tag> _tags = new List<Tag>();
tags.ForEach(t =>
{
try
{
var tag = _context.Tags
.Where(c => c.Name == t)
.FirstOrDefault();
if (tag != null)
{
_tags.Add(tag);
}
else
{
Tag created = new Tag { Name = t };
this.Add(created);
_tags.Add(created);
}
}
catch (Exception ex)
{
}
});
return _tags;
}
public async Task<bool> SaveAllAsync()
{
return (await _context.SaveChangesAsync()) > 0;
}
}
}
On your TalkViewModel add a List<TagViewModel> property with the following properties:
public int TagId { get; set; }
public string TagName { get; set; }
public bool Selected { get; set; }
When you pass the TalkViewModel to your repo, filter out the selected TagViewModels and for each one, add a TalkTag with the proper TagId to your TalkTags property on your Talk. EF should take care of adding the proper TalkId upon _context.SaveChanges().
If the Tag doesn't exist, create a TalkTag with a new Tag and the new Talk as its properties, then add it to your _context. EF should take care of the rest.
You haven't initialized your TalkTags collection which causes the nullpointer. Try this when initializing the Talk object:
Talk talk = new Talk { Name = model.Name, Url = model.Url, TalkTags = new List<TalkTag>() };
Do you need more properties on a TalkTag object? Otherwise you could just have List<Talk> in the Tag class and List<Tag> in the Talk class and the mapping will be done by EF (a TalkTag table will be created in the DB).
Michael Tranchida already described the approach for adding the objects to the context.

Cannot Parse Json sub object

I am using JObject to parse Json object below
string Jstring = #"{
"PolicyId" :"xxxxxx",
"PolicyHolder" :{"title":"Mr", "FirstName":"test", "LastName":"testLast"}
}";
I can get the PolicyId value through below code
Jobject jobj = Jobject.parse(Jstring);
string PolicyId = jobj.value<string>("PolicyId");
But, I always get null using below code:
string Holder = jobj.value<string>("PolicyHolder");
I have debugged the code below:
jobj.Properties()
I can find PolicyHolder in the List. I have tried code below also, the value is always null
JProperty jproperty = jobj.Properties().SingleOrDefault(x => x.Name == "PolicyHolder");
Can anyone know what happen?
string Holder = jobj.value<string>("PolicyHolder");
Above line fails because PolicyHolder is not string. You are trying to cast it to string. It's an object. You must create a class with the properties of the PolicyHolder and use that as a type instead of string.
Here's the working dotNetFiddle: https://dotnetfiddle.net/xOOl5m
Console Output:
Here are the classes I ended up declaring and using.
public class PolicyHolder
{
public string title { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class Policy
{
public string PolicyId { get; set; }
public PolicyHolder PolicyHolder { get; set; }
}
Like Sam has mentioned, PolicyHolder is an Object not a string.
Here's the complete code listing (so that the answer is self-contained).
using System;
using System.Linq;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
public class Program
{
// Solution to SO Question: https://stackoverflow.com/q/27159478/325521
// This Answer: https://stackoverflow.com/a/
// Author: Shiva Manjunath
// SO Profile: https://stackoverflow.com/users/325521/shiva
public static void Main()
{
string Jstring = #"{
""PolicyId"" :""xxxxxx"",
""PolicyHolder"" :{""title"":""Mr"", ""FirstName"":""test"", ""LastName"":""testLast""}
}";
JObject jObject = JObject.Parse(Jstring);
JProperty jProperty = jObject.Properties().SingleOrDefault(x => x.Name == "PolicyHolder");
Console.WriteLine("Printing Policy Holder Details....");
Console.WriteLine(jProperty.Value);
}
}
public class PolicyHolder
{
public string title { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class Policy
{
public string PolicyId { get; set; }
public PolicyHolder PolicyHolder { get; set; }
}

Resources