I hovered over an object in the debugger and saw this:
All the properties on the object are of type int? and I would have expected them all to have the spanner (wrench) icon. What do the blue brick with a no-entry sign (if that's even what it is) mean?
Here is the source code, just in case:
public class QuestionnaireDestinationViewModel
{
public int? TicketID { get; set; }
public int? TicketTemplateID { get; set; }
public int? T
{
get { return this.TicketID; }
set { this.TicketID = value; }
}
public int? TT
{
get { return this.TicketTemplateID; }
set { this.TicketTemplateID = value; }
}
}
Related
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.
I am attempting to deserialize a json object using JsonConvert - the data is coming from a 3rd party API
return JsonConvert.DeserializeObject<UserRegistration>(content,
JsonSnakeCaseNameStrategySettings.Settings());
The UserRegistration class:
public class UserRegistration
{
public UserRegistrationData UserRegistration { get; set; }
}
public class UserRegistrationData
{
public int UserId { get; set; }
public string Email { get; set; }
public UserRegistrationCustomFields CustomFields { get; set; }
}
public class UserRegistrationCustomFields
{
private bool emailDelivery;
public string DeliveryTime { get; set; }
public bool EmailDelivery {
get
{
return emailDelivery;
}
set
{
emailDelivery = value.ToString() == "1";
}
}
public bool SmsDelivery { get; set; }
public string PhoneNumber { get; set; }
}
I've tried several ways, this is my current iteration. The goal is to have "EmailDelivery" be a boolean, the value from the API will always be "1" or "0". This throws a JsonReaderException: Could not convert string to boolean: 0. Path 'user_registration.custom_fields.email_delivery', line 1, position 208.
You need custom JsonConverter to modify the deserialize principle.
Change your model like below:
public class UserRegistrationCustomFields
{
public string DeliveryTime { get; set; }
public bool EmailDelivery{get;set;}
public bool SmsDelivery { get; set; }
public string PhoneNumber { get; set; }
}
Custom a JsonConverter:
public class JsonBooleanConverter : JsonConverter
{
public override bool CanWrite { get { return false; } }
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var value = reader.Value.ToString().ToLower().Trim();
switch (value)
{
case "1": return true;
}
return false;
}
public override bool CanConvert(Type objectType)
{
if (objectType == typeof(Boolean))
{
return true;
}
return false;
}
}
How to use:
JsonConvert.DeserializeObject<UserRegistration>(json, new JsonBooleanConverter());
I'm developing a Blazor WASM project and I'm stuck in this point.
I'm using a DataAccess Service to make the requests to EndPoints;
The endpoints return a ResultList, that is a Generic Object that needs to be parsed in Client side. The object definition:
public class ResultList
{
public ResultList(List<object> resultados, string codigoErro = null, string mensagemErro = null)
{
this.Resultados = resultados;
this.CodigoErro = codigoErro;
this.MensagemErro = mensagemErro;
}
public string MensagemErro { get; set; }
public List<object> Resultados { get; set; }
public string CodigoErro { get; set; }
}
In the client side, I receive the same type:
public async Task<ResultList> GetEmpresas()
{
try
{
ResultList Result = await _httpClient.GetFromJsonAsync<ResultList>("api/EmpCadBasico/GetEmpresas");
return Result;
}
catch (Exception ex)
{
return new ResultList(null, null, ex.Message);
}
}
The problem is: I can't convert the List<Object> to other type like List<Empresa>.
The C# compilation doesn't notify bug, but in execution time, it happens.
I tried Serialize and Deserialize, and it doesn't work too:
public async Task GetEmpresas()
{
ResultList Resultado = await _dataAccess.GetEmpresas();
if (await RetornoOk(Resultado))
{
string x = JsonSerializer.Serialize(Resultado.Resultados); // Here, that's fine.
List<Empresa> y = JsonSerializer.Deserialize<List<Empresa>>(x); // Here, it finds the objects, but all of them with null values.
}
}
The X value: '[{"id":1,"nomeEmpresa":"Alamo","cnpj":"00072619000101","dataCadastro":"2020-01-01T00:00:00","colaborador":[],"marca":[]}]'
The Y value: Y value after Deserialization
According to the json return data you provided, I did the following restoration and successfully returned the data, you can refer to it.
Model:
public class TestModel
{
public int id { get; set; }
public string nomeEmpresa { get; set; }
public string cnpj { get; set; }
public string dataCadastro { get; set; }
public List<colaborador> colaborador { get; set; }
public List<marca> marca { get; set; }
}
public class colaborador
{
public int id { get; set; }
public string test { get; set; }
}
public class marca
{
public int id { get; set; }
public string test { get; set; }
}
Then I gave values to individual attributes, and the results are as follows:
I have the following class:
public class Widget {
public virtual int Id { get; set; }
[Required]
public virtual WidgetType Type { get; set; }
public virtual string SerializedParameters {
get {
return new XmlSerializer(Parameters.GetType()).Serialize(Parameters);
} set {
Parameters = new XmlSerializer(Assembly
.LoadFrom(Server.MapPath(Type.ModelAssembly))
.GetType(Type.ModelClass)
).Deserialize(value);
}
}
private object _parameters;
public virtual object Parameters {
get {
if (_parameters == null)
_parameters = Activator.CreateInstance(Assembly
.LoadFrom(Server.MapPath(Type.ModelAssembly))
.GetType(Type.ModelClass)
);
return _parameters;
} set { _parameters = value; }
}
}
The Parameters property is not mapped to the database but the SerializedParameters property is. However when it tries to get the information from the database and set the SerializedParameters (which subsequently sets the Parameters) the Type property is null and therefore an exception is thrown. I guess this depends on the order in which NHibernate sets the properties for the Widget but i can't get it to work.
I was wondering if there was a way around this. Appreciate the help. Thanks
moved the deserialization in the getter from the setter because as you said the type is not there yet
public class Widget
{
public virtual int Id { get; set; }
public virtual WidgetType Type { get; set; }
private string _serializedParameters;
private virtual string SerializedParameters {
get
{
return new XmlSerializer(Parameters.GetType()).Serialize(Parameters);
}
set
{
_serializedParameters = value;
}
}
private object _parameters;
public virtual object Parameters
{
get
{
if (_parameters == null)
{
if (!string.IsNullOrEmpty(serializedParameters))
{
// code to deserialize the Parameters and set to Parameters
_parameters = new XmlSerializer(Assembly
.LoadFrom(Server.MapPath(Type.ModelAssembly))
.GetType(Type.ModelClass)
).Deserialize(value);
}
else
{
// no existing parameters, then create new object
_parameters = Activator.CreateInstance(Assembly.LoadFrom(Server.MapPath("~/bin/" + widget.Type.ParametersAssembly + ".dll")).GetType(widget.Type.ParametersClass));
}
}
return _parameters;
}
set { _parameters = value; }
}
}
Say I have a class like this:
public class MyClass
{
public int Id { get; set; }
public DateTime Date { get; set; }
public string String1 { get; set; }
public string String2 { get; set; }
public string String3 { get; set; }
public string String4 { get; set; }
}
Is it possible to get NHibernate to store it in the following schema?
CREATE TABLE [dbo].[MyClass](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Xml] [varchar](max) NOT NULL,
)
Where the Id maps to Id, but then all other fields get serialized into XML (or otherwise)? I don't mind if these other fields have to go on a child object like the below, if that helps:
public class MyClass
{
public int Id { get; set; }
public AllOtherOptions Options { get; set; }
}
public class AllOtherOptions
{
public DateTime Date { get; set; }
public string String1 { get; set; }
public string String2 { get; set; }
public string String3 { get; set; }
public string String4 { get; set; }
}
I am thinking about doing something similar for an upcoming project. The project requires collecting a lot of data but only a few elements need to be stored in a relational database. I haven't started experimenting but these are my thoughts so far.
You can map an XML data type by creating a type that implements IUserType. If the child class (AllOtherOptions) is serializable, you should be able to map the XML field as a private member in MyClass and serialize/deserialize AllOtherOptions as needed. You could either dynamically maintain the XML field (sounds like a lot of work) or create an interceptor to do it. My thinking is that MyClass would implement an interface such as
public interface IXmlObjectContainer
{
void SerializeChildObjects();
void DeSerializeChildObjects();
}
and the interceptor would call those methods as needed. That's a proof of concept idea. I would probably refine that by exposing pairs of xml fields and serializable objects to remove the work of serializing from IXmlObjectContainer implementers. Or maybe handle serialization through the XML field's get/set accessors.
More info:
Working with XML Fields in NHibernate
Another XML implementation of IUserType
I had the same idea to save object in XML column. My idea was other. I took code from links and changed it to generic IUserType implementation. So any field/prop which is [Serializable] can be saved in XML column.
public class XmlUserType<T> : IUserType where T : class
{
public new bool Equals(object x, object y)
{
return x == y;
}
public int GetHashCode(object x)
{
return x.GetHashCode();
}
public object NullSafeGet(IDataReader rs, string[] names, object owner)
{
if (names.Length != 1)
throw new InvalidOperationException("names array has more than one element. can't handle this!");
var val = rs[names[0]] as string;
if (string.IsNullOrWhiteSpace(val) == false)
{
return KRD.Common.GenericXmlSerialization.Deserialize<T>(val);
}
return null;
}
public void NullSafeSet(IDbCommand cmd, object value, int index)
{
var parameter = (DbParameter)cmd.Parameters[index];
T toSave = value as T;
if (toSave != null)
{
parameter.Value = KRD.Common.GenericXmlSerialization.Serialize(toSave);
}
else
{
parameter.Value = DBNull.Value;
}
}
public object DeepCopy(object value)
{
T toCopy = value as T;
if (toCopy == null)
return null;
string serialized = KRD.Common.GenericXmlSerialization.Serialize(toCopy);
return KRD.Common.GenericXmlSerialization.Deserialize<T>(serialized);
}
public object Replace(object original, object target, object owner)
{
throw new NotImplementedException();
}
public object Assemble(object cached, object owner)
{
var str = cached as string;
if (string.IsNullOrWhiteSpace(str) == false)
{
return null;
}
return KRD.Common.GenericXmlSerialization.Deserialize<T>(str);
}
public object Disassemble(object value)
{
var toCache = value as T;
if (toCache != null)
{
return KRD.Common.GenericXmlSerialization.Serialize(toCache);
}
return null;
}
public SqlType[] SqlTypes
{
get
{
return new SqlType[] { new SqlXmlType() };
}
}
public Type ReturnedType
{
get { return typeof(XmlDocument); }
}
public bool IsMutable
{
get { return true; }
}
}
public class SqlXmlType : SqlType
{
public SqlXmlType()
: base(DbType.Xml)
{
}
}
Usage with FluentNHibernate:
public class MainObject
{
public int Id { get; set; }
public ObjectAsXml Data { get; set; }
}
public class ObjectAsXml
{
public string Name { get; set; }
public int Date { get; set; }
public ObjectAsXml OtherObject { get; set; }
}
private class MainObjectMap : ClassMap<MainObject>
{
public MainObjectMap()
{
Id(id => id.Id);
Map(m => m.Data).CustomType<XmlUserType<ObjectAsXml>>().Nullable();
}
}
Maybe it will help somebody.