How to deserialize object as single item list? - asp.net-core

I need to make a service that allows both next jsons as request body
{
"id": 1,
...
"foo": null
}
and
{
"id": [1, 2, 3],
...
"foo": null
}
I tried making the model like this
public class MyModel
{
public List<int> Id { get; set; }
//...
public string Foo { get; set; }
}
which works for the second case, but not for the first one, as an int is not a list of ints.
What can I do to be able to parse both bodies correctly?

You could deserialize into a dynamic object instead.
dynamic result = JsonConvert.DeserializeObject<dynamic>(json);
Another approach I'm not sure would work is to make the Id property dynamic.
public class MyModel
{
public dynamic Id { get; set; }
public string Foo { get; set; }
}

You can create Models like the following(Model includes all the properties except id):
public class MyModel
{
public List<int> id { get; set; }
public Model model { get; set; }
}
public class Model
{
//...
public string foo { get; set; }
}
And ckeck id in requestbody,if id is int type,create a new list and add id to the list.
MyModel myModel = new MyModel();
myModel.model=JsonConvert.DeserializeObject<Model>(jsonResult);
var mydata = JsonConvert.DeserializeObject<JObject>(jsonResult);
if (!mydata["id"].ToString().Contains("["))
{
myModel.id = new List<int> { Convert.ToInt32(mydata["id"]) };
}
else {
myModel.id = JsonConvert.DeserializeObject<List<int>>(mydata["id"].ToString());
}
result:

Related

How to deserialize Graphql Response

Hi I have a graphql Response after Mutating
{{
"carCreate": {
"car": {
"id": "TestId"
}
}
}}
I want to Desealize it I am using The following Code
var graphQlClient = new GraphQLHttpClient(AppConfig.GraphQlUrl, new NewtonsoftJsonSerializer());
I have tried to resolve with the following code
var response = await graphQlClient.SendMutationAsync<CarCreate>(request);
My Created Model is :
public class Car
{
public string Id { get; set; }
}
public class CarCreate
{
public Car Car { get; set; }
}
Your class should be something like this,
// Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(myJsonResponse);
public class Car
{
public string id { get; set; }
}
public class CarCreate
{
public Car car { get; set; }
}
public class Root
{
public CarCreate carCreate { get; set; }
}

Getting navigation properties of your entity when you return a CreatedAtRouteResult

Request:
namespace mediere_API.Requests
{
public class LocalitateRequest
{
public string Nume { get; set; }
public int JudetId { get; set; }
}
}
DTO
namespace mediere_API.Dtos
{
public class LocalitateDTO
{
public int Id { get; set; }
public string Nume { get; set; }
public JudetDTO Judet { get; set; }
}
}
Entity
using mediere_API.Dtos;
using System.ComponentModel.DataAnnotations;
namespace mediere_API.DataLayer.Entities
{
public class Localitate : BaseEntity
{
[Required]
public string Nume { get; set; }
[Required]
public int JudetId { get; set; }
public virtual Judet judet { get; set; }
public Localitate() { }
}
}
Processor method
async Task<ActionResult> ILocalitatiProcessor.AddLocalitate(LocalitateRequest localitateRequest)
{
var record = _mapper.Map<Localitate>(localitateRequest);
_unitOfWork.Localitati.Insert(record);
if (await _unitOfWork.SaveChangesAsync() == false)
{
return new BadRequestResult();
}
return new CreatedAtRouteResult("GetByIdLocalitate", new {Id = record.Id}, _mapper.Map<LocalitateDTO>(record));
}
So, I have these pieces of code.
The way I'm using my front-end, I need to have the navigation properties filled in when I get the response on the POST request.
Right now I get:
{
"id": 12777,
"nume": "test",
"judet": null
}
On the get requests it works properly, but with CreatedAtRouteResult it doesn't, and I know why, but I don't know how should I fix it.
Record doesn't have the navigation properties filled in because it is a mapping of localitateRequest (which doesn't have the navigation properties) to Localitate.
So, how should I approach this problem?
Thanks.

How to pass routeValues to Html.ActionLink in asp.net razor

We can pass single int parameter as below.
#Html.ActionLink(item.RemoteAgent.Name, "Details", "RemoteAgent", new { id = item.RemoteAgent.Id })
But what if we want to pass complex object?
what can be done here?
You can serialize the model in client side,and then deserialize it in action.Here is a demo.
Model:
public class TestModel
{
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
}
View:
#{ TestModel m=new TestModel { FirstName="f1",MiddleName="m1",LastName="l1"};}
#Html.ActionLink("Index1", "Index1", "A", new { model = Json.Serialize(m)})
Action:
public IActionResult Index1(string model)
{
TestModel testModel = JsonConvert.DeserializeObject<TestModel>(model);
return Ok();
}
result:

How to replace null collections in input model with empty ones in ASP.NET core

I have an input model from body:
public class User
{
public string Name { get; set; }
public List<string> Books { get; set; }
}
When user sends
{
"name": "John",
"books": null
}
I Books property is null, but I want it to be empty list. How to do it once for all the controllers and models?
ASP.NET Core knows how to bind the the parameters to the constructor.
This is not the best approach, but it is the one I decided to go with:
public class User
{
public User(string name, List<string> books)
{
Name = name;
Books = books ?? new List<string>();
}
public string Name { get; set; }
public List<string> Books { get; set; }
}
You can also use private field:
public class User
{
private List<string> _books;
public string Name { get; set; }
public List<string> Books
{
get => _books ?? new List<string>();
set { _books = value; }
}
}

How to bind custom model class in mvc

I am new in MVC. I am working on a project where i have created a model class and also context class which is working good if i view the record in normal view.
but if i try to get the data in group by "Series_Name" and bind it into same model class it gives error. here is my code
Here is Model class and DBContextClass
[Table("tblvideo")]
public class TVSerial
{
[Key]
public Int64 Video_ID { get; set; }
public string Series_Name { get; set; }
public string Season_No { get; set; }
public string Episode_No { get; set; }
public string Episode_Name { get; set; }
public string Time_Duration { get; set; }
public string File_Url_480p { get; set; }
public string File_Url_720p { get; set; }
public string Description { get; set; }
public bool Is_Active { get; set; }
public string Image_Url_Small { get; set; }
public string Image_Url_Big { get; set; }
}
public class TvSerialContext : DbContext
{
public DbSet<TVSerial> TvSerials { get; set; }
}
Here is controller class:
public class TvSerialController : Controller
{
public ActionResult ListAllTvSerial()
{
try
{
TvSerialContext tvContext = new TvSerialContext();
List<TVSerial> tv = tvContext.TvSerials.ToList();
return View(tv);
}
catch (Exception ex)
{
return Content(ex.Message);
}
}
}
Above code works as expected, but if i am doing this :
public ActionResult ListAllSeason(string serial)
{
try
{
TvSerialContext tvContext = new TvSerialContext();
List<TVSerial> tv = tvContext.TvSerials.Where(tvs => tvs.Series_Name == serial).Distinct().ToList();
return View(tv);
}
catch (Exception ex)
{
return Content(ex.Message);
}
}
it return all rows , i just want single row from every series_name and custom field "Series_Name,Season_No,Image_Url_Big"
i don't know how to achieve this.
getting result :
Expected result:-
You could do this by creating a view model and using a .GroupBy() clause
public class TVSerialVM
{
public string SeriesName { get; set; }
public string SeasonNo { get; set; }
public string ImageUrl { get; set; }
}
and the query to project into your view model
List<TVSerialVM> model = tvContext.TvSerials.Where(t => t.Series_Name == serial)
.GroupBy(t => new { t.Series_Name, t.Season_No, t.Image_Url_Big })
.Select(t => new TVSerialVM
{
SeriesName = t.Key.Series_Name,
SeasonNo = t.Key.Season_No,
ImageUrl = t.Key.Image_Url_Big
}).ToList();
Side note: Your duplicating data in the database (the season number and the image url). You should consider moving the image urls to another table with a relationship to the season number.
The reason you are getting multiple values even though you are using distinct is the Distinct method does not know what "equal" is for TVSerial.
You can use Distinct with IEqualityComparer.
https://msdn.microsoft.com/en-us/library/vstudio/bb338049(v=vs.100).aspx
Distinct is not guaranteed to on custom objects it doesn't know what to compare. I have used this SO in the past to make my custom object work with Distinct.
Creating a distinct list of custom type in C#