Expected Behavior:
In the Xamarin.Forms project (MyApp) I am referencing a class library with custom models(Custom.Netcore.Models.dll), contained in a separate project/separate solution. The goal is to serialize the models to json from xml files for our API/Database, retrieve and deserialize them via MyApp's REST using Newtonsoft.Json to fill ViewModel objects, create changes through various interactions via MyApp's UI then serialize them and POST to Custom.Netcore.API.
Actual Behavior:
The expected behavior only functions when running MyApp via UWP. When trying to run the solution via Android/iOS (Emulators) and the application gets to the REST calls to fill MyApp's ViewModels, the Application successfully GETs the serialized data via
var data = await response.Content.ReadAsStringAsync();
then when the application attempts to parse the data and deserialize it to the model via
ObservableCollection<Model> Records = JsonConvert.DeserializeObject<ObservableCollection<Model>>(data);
both Android/iOS at this point give the same error and cause the application to stop running:
Android:
System.TypeLoadException: 'Could not resolve type with token 0100000c from typeref (expected class 'System.Xml.Serialization.XmlRootAttribute' in assembly 'System.Xml.ReaderWriter, Version=4.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a')'
iOS:
Failed to resolve "System.Void System.Xml.Serialization.XmlRootAttribute::.ctor()" reference from "System.Xml.ReaderWriter, Version=4.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
however, I am able to successfully create and fill ViewModel objects defined with Custom.Netcore.Models.Model on all platforms via something simple like
ObservableCollection<Model> Records = new ObservableCollection<Model>()
{
new Model(){ Id = 0, Description = "First Model", Type = "One"},
new Model(){ Id = 1, Description = "Second Model", Type = "Two"}
};
Logs: (Android)
Can't find custom attr constructor image: /storage/emulated/0/Android/data/com.companyname.MyApp/files/.__override__/Custom.Netcore.Models.dll mtoken: 0x0a000010 due to: Could not resolve type with token 0100000c from typeref (expected class 'System.Xml.Serialization.XmlRootAttribute' in assembly 'System.Xml.ReaderWriter, Version=4.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a') assembly:System.Xml.ReaderWriter, Version=4.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a type:System.Xml.Serialization.XmlRootAttribute member:(null) **System.TypeLoadException:** 'Could not resolve type with token 0100000c from typeref (expected class 'System.Xml.Serialization.XmlRootAttribute' in assembly 'System.Xml.ReaderWriter, Version=4.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a')'
Setup:
Custom.Netcore.Api:
<TargetFramework>netcoreapp2.1</TargetFramework>
Microsoft.AspNetCore.App - v2.1.1
Microsoft.NETCore.App - v2.1.0
NETStandard.Library - v.2.0.3
System.Configuration.ConfigurationManager - v5.0.0-preview.4.20251.6
System.Data.SqlClient - v4.8.1
System.Runtime - v4.3.1
XF.MyApp:
<TargetFramework>netstandard2.0</TargetFramework>
Xamarin.Forms - v4.7.0.968
Newtonsoft.Json - v12.0.3
NETStandard.Library - v2.0.3
Custom.Netcore.Models.Model.cs:
namespace Custom.Netcore.Models
{
[Serializable()]
[System.Xml.Serialization.XmlRoot("Model")]
public class Model
{
[System.Xml.Serialization.XmlAttribute("id")]
public int Id { get; set; }
[System.Xml.Serialization.XmlAttribute("description")]
public string Description { get; set; }
[System.Xml.Serialization.XmlElement("Type")]
public string Type { get; set; }
}
}
API Data:
[
{
"id": 0,
"description": "First Model",
"type" = "One"
},
{
"id": 1,
"description": "Second Model",
"type" = "Two"
}
]
Been stuck trying to workaround this issue for a week so any help would be greatly appreciated!
Try like this:
namespace Custom.Netcore.Models
{
[Serializable()]
[JsonProperty("Model")]
public class Model
{
[JsonProperty("id")]
public int Id { get; set; }
[JsonProperty("description")]
public string Description { get; set; }
[JsonProperty("Type")]
public string Type { get; set; }
}
}
Edit:
or try to use:
JsonConvert.DeserializeXmlNode<>
JsonConvert.DeserializeXNode<>
insted of:
JsonConvert.DeserializeObject<>
The logs and errorlist wont directly tell you on iOS and Android, and since I couldnt find a similar issue online I'll leave this for someone in the future. If you are using Xamarin Forms and referencing a Class Library Project in a separate solution be aware that if you get a bad reflection or errors similar to those above, the cause of the issue may be incompatibility between MonoAndroid 9 and NetCore 2.1. The fix for this issue in my case was to use the separate solution NetCore 2.1 version for DB tasks and within the same XF solution, add the same Class Library Project then convert it to target the same NetStandard framework since that's what Xamarin Forms is intended to target.
Related
When the decimal value of "Salary" field of below POCO class is 12000M (a decimal value), the Swagger UI displays the JSON attribute values as 12000.
Whereas, the expected JSON attribute values as 12000.0 (i.e. having a trailing zero).
Used the following code inside "ConfigureServices(IServiceCollection services)" method of startup.cs:
services.AddControllers().AddNewtonsoftJson(options =>
{
options.SerializerSettings.FloatParseHandling = FloatParseHandling.Decimal;
options.SerializerSettings.FloatFormatHandling = FloatFormatHandling.DefaultValue;
});
services.AddControllersWithViews().AddNewtonsoftJson(options =>
{
options.SerializerSettings.FloatParseHandling = FloatParseHandling.Decimal;
options.SerializerSettings.FloatFormatHandling = FloatFormatHandling.DefaultValue;
});
Used the following code snippet as well, but the expected output is not coming in Swagger UI.
(in Swashbuckle.AspNetCore.Newtonsoft V6.1.4.0)
services.AddAwaggerGenNewtonsoftSupport();
When the above code snippet didn't work, tried following as well.
But there is no luck.
services.AddMvc().AddNewtonsoftJson(options =>
{
options.SerializerSettings.FloatParseHandling = FloatParseHandling.Decimal;
options.SerializerSettings.FloatFormatHandling = FloatFormatHandling.DefaultValue;
});
Class:
public class Employee{
public string EmployeeName {get; set;}
public decimal Salary {get; set;}
public string Department {get; set;}
}
It looks like, even after adding the above code snippet, the Swagger UI is not using Newtonsoft.Json to serialize decimal, instead using System.Text.json.
.Net Core Version is 3.1
Install this package
Install-Package Swashbuckle.AspNetCore.Newtonsoft -Version 6.2.3
Then add this line
builder.Services.AddSwaggerGenNewtonsoftSupport();
So, I read all about the new localization system in ASP.Net Core (3.1) and successfully made use of the IStringLocalizer<MyController> and the IViewLocalizer<MyView>. I also could use the localization for the [DisplayName("Property description") in Models.
Below what I seem unable to do:
In good old .Net Framework I could do this:
public class Month
{
public int MonthNumber { get; set; }
public string Name
{
get
{
switch(MonthNumber)
{
case 1:
return Properties.Resources.Jan;
case 2:
return Properties.Resources.Feb;
default:
return "?";
}
}
}
But how can I do this in a Model in ASP.Net Core 3.1?
I solved it thus:
Just add the resource files following the structure you have chosen. All docs and tutorials suggest you take a folder named "Resources" as your base folder, so that is what you see here.
The link that is most probable to survive over time that explains how to use resources in an ASP.Net Core project:
Microsoft docs on Localization for ASP.Net Core
Make sure that you mark all three "Month" resx files as Public:
Visual Studio will at first complain with the message:
Custom tool PublicResXFileCodeGenerator failed to produce an output for input file 'Month.en.resx' but did not log a specific error.
Simply get rid of this error by restarting Visual Studio!
Now you can use the resources as follows:
public string Name
{
get
{
return MonthNumber switch
{
1 => Resources.Models.Month.Jan,
2 => Resources.Models.Month.Feb,
_ => "?"
};
}
}
You need to inject IStringLocalizer to the class:
public class Month
{
public int MonthNumber { get; set; }
private readonly IStringLocalizer Localizer;
public Month(IStringLocalizer localizer)
{
Localizer = localizer;
}
public string Name
{
get
{
switch(MonthNumber)
{
case 1:
return Localizer["Jan"];
case 2:
return Localizer["Feb"]
default:
return "?";
}
}
}
}
Another approach can be done by adding localized month names for the numbers in the resource file, so:
var monthName = Localizer["4"];
// result: April for English culture
// or Nisan for Turkish culture
Just for clarification;
The resource key can have three types of access modifiers:
Internal
Public
No code generation
If the key is marked with Internal or Public you can access it as you mentioned, because the compiler will auto generate a static class .cs linked to the relevant resource file with the key names as accessible properties.
But the common approach with Asp.Net Core is to work with Shared resources, and shared resource has the access modifier as No code generation; so thats mean no peoperty keys will be generated at the backend (.cs will not be generated). And in this case you have to inject the IStringLocalizer or whatever locaizer in use to the class.
So changing the key access modifier to Internal or Public can work as well, but it is not a best practice ;)
I have two models within my model folder called Models, i am trying to pull data from the model to display it in the view, i am aware of only one model statement can be applied to the view. So i have Created a ViewModels which contain the properties that i would like to reference in the view. now when i run the the application im getting a compilation Error which says:
"Compiler Error Message: CS0246: The type or namespace name 'Models' could not be found (are you missing a using directive or an assembly reference?)"
View Models Code
public class MainModelscs <T> where T :class
{
public StoreAudit StoreAudit { get; set; }
public StoreQuestions StoreQuestions { get; set; }
public IPagedList<T> IndexList { get; set; }
}
model properties in view
#model PopMarketing.ViewModel.MainModelscs<Models>
You need to specify the full namespace of the Models type which you are using. Something like this:
#model PopMarketing.ViewModel.MainModelscs<PopMarketing.Models.ListItemType>
I'm desesperated, I'm trying to update an existing service reference to a WCF service (sharing types) and I can't. I've tryied all what I've found on Google (social.msdn, stackoverflow, ...) but I haven't found the solution to my problem.
I've have a ServiceContract and I add a new Operation like the code below:
[ServiceContract]
public partial interface IServiceDTO : IGenericServiceDTO<EntityDTO>
{
// Some OperationContracts working like
[OperationContract]
EntityDTO[] Method(int field);
// NewMethod
[OperationContract]
OtherEntityDTO[] NewMethod(int field);
}
[DataContract]
public class EntityDTO {
// Some properties working
}
[DataContract]
public class OtherEntityDTO {
// Some properties working
[DataMember]
YetAnotherEntity NewProperty {get;set;}
}
When I try to update the service reference it throws me the follwing error:
Attempting to download metadata from 'http://localhost:65499/Services/Acciones/ProcesoServiceDTO.svc' using WS-Metadata Exchange or DISCO.
Error: Cannot import wsdl:portType
Detail: An exception was thrown while running a WSDL import extension: System.ServiceModel.Description.DataContractSerializerMessageContractImporter
Error: Referenced type 'mpm.seg.ServiceModel.DTO.DataContracts.Acciones.ProcesoDTO, mpm.seg.ServiceModel.DTO.DataContracts, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' with data contract name 'ProcesoDTO' in namespace 'http://schemas.datacontract.org/2004/07/mpm.seg.ServiceModel.DTO.DataContracts.Acciones' cannot be used since it does not match imported DataContract.
Need to exclude this type from referenced types.XPath to Error Source: //wsdl:definitions[#targetNamespace='http://tempuri.org/']/wsdl:portType[#name='IProcesoServiceDTO']
First of all, I don't understand exactly the sentence "...cannot be used since it does not match imported DataContract." How the svcutil is trying to match referenced type to imported DataContract? I've referenced the project that have the referenced types on the client project, cause server and client are in the same solution, but I've tried to separate them and reference exactly the same dll too.
Also, when I try, for example, the following situation it works (write "NewProperty" of the "OtherEntityDTO to EntityDTO"), and I don't understand the difference:
[ServiceContract]
public partial interface IServiceDTO : IGenericServiceDTO<EntityDTO>
{
// Some OperationContracts working like
[OperationContract]
EntityDTO[] Method(int field);
// NewMethod
[OperationContract]
OtherEntityDTO[] NewMethod(int field);
}
[DataContract]
public class EntityDTO {
// Some properties working
[DataMember]
YetAnotherEntity NewProperty {get;set;}
}
[DataContract]
public class OtherEntityDTO {
// Some properties working
}
Please, help me and thanks a lot in advance.
Sorry, but after I've posted the question I've found the problem and it was a reported bug (http://blogs.msdn.com/b/distributedservices/archive/2010/02/04/wcf-client-issue-with-reuse-types-from-referenced-assemblies.aspx?wa=wsignin1.0). Another developer had added this attribute (IsReference=true) on a parent class and I didn't know. Now I must to workaround this bug, but that's another battle.
Anyway, I don't understand why sometimes work and sometimes not...
Thanks.
I had a similar error, but my issue seemed to be different.
I had a readonly property and I kept getting that error. When I changed it to a normal property and added a set (that did nothing), the contract worked fine.
I'm fairly new to NH and FNH. I want to map a List of longs, and I'm getting the error:
An invalid or incomplete configuration was used while creating a SessionFactory.
Double inner Exception:
{"(XmlDocument)(15,8): XML validation error: The element 'list' in namespace 'urn:nhibernate-mapping-2.2' has invalid child element 'one-to-many' in Namespace 'urn:nhibernate-mapping-2.2'. List of possible elements expected: 'loader, sql-insert, sql-update, sql-delete, sql-delete-all, filter' in Namespace 'urn:nhibernate-mapping-2.2'."}
My entity:
public class XPTable
{
public virtual int I3D { get; set; }
public virtual IList<long> XPRequired { get; set; }
public XPTable()
{
XPRequired = new List<long>();
}
}
My Mapping:
public class XPTableMaps : ClassMap<XPTable>
{
public XPTableMaps()
{
Table("XPTable");
Id(id => id.I3D);
//this line causes the error
HasMany<long>(many => many.XPRequired).AsList().Element("XPRequired");
}
}
I use NHibernate 3.1.0, FNH 1.0
It's definitely the HasMany mapping that's causing the problem, because when I comment it out, the program runs just fine. The I3D column in the SQL 2008 table is the identity, the names/types of the table and the columns match the mapping. If I leave out the .AsList(), then the error message stays the same except that it refers to 'bag' instead of 'list'. Adding Inverse() and/or Cascade.Whatever() has no effect either.
Any ideas please?