Get image files from Local Folder to display in the UI at runtime fails - mvvm

I used below codes to retrieve image files from LocalFolder
Total images files is 20 in LocalFolder
The problem:
Only 8 images are displayed and the rest is blank.
Why the rest can not be displayed?
Can bind the BitmapImage file to the image Control as below base on MVVM ?
Example : imageURL ="ms-appdata:///local/imgfile.jpg"
---- In XAML : PhotoView.xaml
<Image x:Name="Img" Source="{Binding ImageUrl}" Stretch="UniformToFill"/>
<TextBlock FontSize="23" Text="{Binding Unit_Price}" Height="23" Margin="3,1,3,0"/>
<TextBlock FontSize="23" Text="{Binding Description}" Height="23" Width="300" Margin="1,1,1,0/>
--- In code behind: PhotoView
ItemsViewModel itemsViewModel = null;
ObservableCollection items = null;
itemsViewModel = new ItemsViewModel();
items = itemsViewModel.GetItems();
//-- GridViewControl
ItemsViewSource.Source = items;
ItemsGridView.SelectedItem = null;
-------------MVVM
--------- Model :
class ItemViewModel : ViewModelBase
{
private string imageurl = string.Empty;
public string ImageUrl
{
get
{ return imageurl; }
set
{
if (imageurl == value)
{ return; }
imageurl = value;
isDirty = true;
RaisePropertyChanged("ImageUrl");
}
}
private decimal unit_price = 0;
public decimal Unit_Price
{
get
{ return unit_price; }
set
{
if (unit_price == value)
{ return; }
unit_price = value;
isDirty = true;
RaisePropertyChanged("Unit_Price");
}
}
}
---------- View Model
class ItemsViewModel : ViewModelBase
{
private ObservableCollection items;
public ObservableCollection Items
{
get
{
return items;
}
set
{
items = value;
RaisePropertyChanged("Items");
}
}
public ObservableCollection GetItems()
{
items = new ObservableCollection();
using (var db = new SQLite.SQLiteConnection(App.DBPath))
{
var query = db.Table().Where(c=> c.CompanyName == Company).OrderBy(c => c.No);
foreach (var _item in query)
{
var item = new ItemViewModel()
{
No = _item.No,
ImageUrl = "ms-appdata:///local/" + _item.PictureFilename,
Unit_Price = _item.Unit_Price,
Description = _item.Description
};
items.Add(item);
}
}
return items;
}

Try to bind ImageSource (not string)

Try to copy the Image folder in the Folder wherever you are using or Register the Every image in Register.resx and call the image by its name given in the Register

Related

How do I populate Items in collection view from model view if I am using file picker?

I am trying to select some files from file picker . Once I select them I want to show them in my collection view. If I am trying to achieve this thing from code behind then it is working fine but if I am trying it from MVVM then it is not populating the files I have selected.
and the reason I am trying to do it with MVVM is that I want to navigate to the next page with all selected files.
Thanks.
Here is my code:
MainPage.xaml
<CollectionView Grid.ColumnSpan="2" Grid.Row="1"
SelectionMode="Single" x:Name="myCollection"
VerticalOptions="FillAndExpand"
VerticalScrollBarVisibility="Always"
ItemTemplate="{StaticResource appDataTemplate}"
ItemsSource="{Binding Items}">
</CollectionView>
Here I have binded my context.
MainPage.Xaml.cs
public MainPage(FileViewModel vm)
{
InitializeComponent();
BindingContext = vm;
}
And this is my viewModel:`[ObservableProperty]
List sourceData;
public List<Item> Items
{
get { return sourceData; }
set
{
sourceData = value;
}
}
public FileViewModel(IFolderPicker folderPicker)
{
sourceData = Items ;
_folderPicker = folderPicker;
}`
public async void Add_File(object sender, EventArgs e)
{
var CustomFileType = new FilePickerFileType(new Dictionary<DevicePlatform,
IEnumerable<String>>
{
//logic
});
var results = await FilePicker.PickMultipleAsync(new PickOptions
{
FileTypes = CustomFileType,
});
sourceData = null;
foreach (var result in results)
{
FileInfo fileInfo = new FileInfo(result.FullPath);
double size = fileSize(fileInfo);
bool fileExist = false;
if (Items != null)
{
foreach (Item item in Items)
{
if (item.FilePath.Equals(result.FullPath))
{
fileExist = true;
break;
}
}
}
else
{
Items= new ObservableCollection<Item>();
}
if (!fileExist)
{
Items.Add(new Item
{
FilePath = result.FullPath,
FileSize = size
});
}
else
{
Items= sourceData;
// await DisplayAlert("Alert", "File already exist!", "Ok");
}
}
Items = sourceData;
}
Same code is working file if I put the view models code in code behind like below:
private async void Add_File(object sender, EventArgs e)
{
var CustomFileType = new FilePickerFileType(new Dictionary<DevicePlatform,
IEnumerable<String>>
{
{ DevicePlatform.WinUI, new[]{"ics"} },
});
var results = await FilePicker.PickMultipleAsync(new PickOptions
{
FileTypes = CustomFileType,
});
myCollection.ItemsSource = null;
foreach (var result in results)
{
FileInfo fileInfo = new FileInfo(result.FullPath);
double size = fileSize(fileInfo);
bool fileExist = false;
foreach (Item item in Items)
{
if (item.FilePath.Equals(result.FullPath))
{
fileExist = true;
break;
}
}
if (!fileExist)
{
Items.Add(new Item
{
FilePath = result.FullPath,
FileSize = size
});
}
else
{
myCollection.ItemsSource = Items;
await DisplayAlert("Alert", "File already exist!", "Ok");
}
}
myCollection.ItemsSource = Items;
}
But it is not working with file view model.
I am not able to populate the collection view from view model.

swashbuckle openapi 3 write example and description for the dynamically generated model classes

My model properties definition is coming from a json file so using reflection to write the classes to be shown under schema on resulting swagger page.
foreach (var model in Models)
{
if (!ModelTypes.ContainsKey(model.Key))
{
anyNonCompiledModel = true;
BuildModelCodeClass(modelComponentBuilder, model.Value);//Build model classes
}
}
BuildModelCodeEnd(modelComponentBuilder);
if (anyNonCompiledModel)
{
CSharpCompiler compiler = new CSharpCompiler();
compiler.AddReference(typeof(object));
compiler.AddReference(typeof(ResourceFactory));
compiler.AddReference(typeof(System.Runtime.Serialization.DataContractResolver));
compiler.AddReference(typeof(System.Runtime.Serialization.DataContractAttribute));
var types = compiler.Compiler(modelComponentBuilder.ToString()); //write model classes
foreach (var type in types)
{
ModelTypes.Add(type.Name, type);
}
}
public void BuildModelCodeClass(StringBuilder modelComponentBuilder, MetadataModelEntity model)
{
modelComponentBuilder.AppendLine($"public class {model.Name} {{");
foreach (var p in model.Data.Properties)
{
if (p.Obsoleted) continue;
if (p.Type.Type == "array")
{
modelComponentBuilder.AppendLine($" public {p.Type.ArrayType.ObjectName}[] {p.Name} {{get;set;}}");
}
else
{
//primitive types
modelComponentBuilder.AppendLine($" public {p.Type.ObjectName} {p.Name} {{get;set;}}");
}
}
modelComponentBuilder.AppendLine(
#"}
");
}
If i provide the description and example like following (in BuildModelCodeClass, inside the loop) then the example and description displays for me.
if (!string.IsNullOrWhiteSpace((string)p.Example))
{
modelComponentBuilder.AppendLine($" ///<example>{p.Example}</example>");
}
if (!string.IsNullOrWhiteSpace((string)p.Description))
{
modelComponentBuilder.AppendLine($" ///<description>{p.Description}</description>");
}
However, i dont want to do above.
I want to write my models via the open api and not via the C# Compiler, is it possible?
I want to show example and description via schema (may be under paths some where). How can i do this? Context has my models info available that i can interact with here.
public class SwaggerDocumentFilter : IDocumentFilter
{
SwaggerDocument _swaggerDocument;
public SwaggerDocumentFilter(object apiConfigure)
{
_swaggerDocument = ((ApiGatewayConfiguration)apiConfigure).SwaggerDocument;
}
public void Apply(OpenApiDocument document, DocumentFilterContext context)
{
if (document.Info.Extensions == null || !document.Info.Extensions.ContainsKey(SwaggerEndpoint.ExtensionDocName)) return;
var openIdString = document.Info.Extensions[SwaggerEndpoint.ExtensionDocName] as OpenApiString;
if (openIdString == null) return;
var docName = openIdString.Value;
SwaggerEndpoint endpoint = _swaggerDocument.SwaggerEndpoints.SingleOrDefault(x => x.Name == docName);
if (endpoint == null) return;
//Add server objects
document.Servers = endpoint.ServerObjects;
//Add Tags objects
document.Tags = endpoint.Tags;
//Set swagger paths objects
var pathsObjects = _swaggerDocument.GetPathsObject(docName, context);
if (pathsObjects.IsValid())
{
pathsObjects.ToList().ForEach(
item => document.Paths.Add(item.Key, item.Value)
);
}
//Add Schema components
//Add Example/Examples
}
}
Following helped
https://github.com/domaindrivendev/Swashbuckle.WebApi/issues/162
AddSchemaExamples.cs
public class AddSchemaExamples : ISchemaFilter
{
public void Apply(Schema schema, SchemaRegistry schemaRegistry, Type type)
{
if (type == typeof(Product))
{
schema.example = new Product
{
Id = 123,
Type = ProductType.Book,
Description = "Treasure Island",
UnitPrice = 10.0M
};
}
}
}
SwaggerConfig.cs
httpConfig
.EnableSwagger(c =>
{
c.SchemaFilter<AddSchemaExamples>()
});
My implementation for the Apply since model is dynamic
if (model != null)
{
schema.Description = model.Description;
foreach (var p in schema.Properties)
{
var mp = model.Data.Properties.SingleOrDefault(x => x.Name == p.Key);
if (mp != null)
{
if (!string.IsNullOrWhiteSpace(mp.Description))
{
p.Value.Description = mp.Description;
}
if(!string.IsNullOrWhiteSpace(mp.Example))
{
p.Value.Example =
new Microsoft.OpenApi.Any.OpenApiString(mp.Example.ToString());
}
}
}
}

Xamarin.Forms Help loading Images from Url/Uri directly from viewmodel

Im currently working on a cross-platform App (iOS & Android) on Xamarin.Forms My current goal is to develop a slider with images for multiple services.
Something like:
IMAGE | IMAGE | IMAGE | IMAGE
label | label | label | label
scrollable to the sides.
For this I created:
-The Services class
string ID
string Name
string ServiceType
ImageSource ImgUrl
-A ViewModel (HLandingVM)
Here I prepare the lists objects and load them into the page
-HLandingPage.xaml for the view
-HLandingPage.cs to load the viewmodel
The main issue is that I do see my labels correctly displayed and scrolling as they are supposed to. But the images are not displaying at all.
Ive tryed passing to the model:
An ImageSource , Image by itself, passing just an Uri for the Binding. But the Image will not display at all.
-Class
`private string id;
public string Id
{
get { return id; }
set
{
id = value;
OnPropertyChange("Id");
}
}
private string name;
public string Name
{
get { return name; }
set
{
name = value;
OnPropertyChange("Name");
}
}
private string servicetype;
public string ServiceType
{
get { return servicetype; }
set
{
servicetype = value;
OnPropertyChange("ServiceType");
}
}
private ImageSource imgUrl;
public ImageSource ImgUrl
{
get { return imgUrl; }
set
{
imgUrl = value;
OnPropertyChange("ImgUrl");
}
}`
-VIEW
`
<StackLayout Margin="10,0,5,0" WidthRequest="150" HeightRequest="150">
<Image HorizontalOptions="Start" WidthRequest="150" HeightRequest="150" >
<Image.Source>
<UriImageSource Uri="{Binding ImgUrl}" />
</Image.Source>
</Image>
<Label Style="{StaticResource BoldLabel}" HorizontalTextAlignment="Center" FontSize="13" LineBreakMode="TailTruncation" Text="{Binding Name}" TextColor="Black"/>
</StackLayout>
`
-VM
Adding Services and ImageSources
`
Services.Add(
new Services
{
Name = "Service1",
ServiceType = "Owner",
ImgUrl = new UriImageSource()
{
Uri= new Uri("https://via.placeholder.com/150 "),
CachingEnabled = false
}
});
Services.Add(
new Services
{
Name = "Service2",
ServiceType = "Owner",
ImgUrl = new UriImageSource()
{
Uri = new Uri("https://via.placeholder.com/100 "),
CachingEnabled = false
}
});
Services.Add(
new Services
{
Name = "Service3",
ServiceType = "Owner",
ImgUrl = new UriImageSource()
{
Uri = new Uri("https://via.placeholder.com/250 "),
CachingEnabled = false
}
});
`
-Trying (not working) to load a Resource Image if the URI returns empty
`
foreach (var service in List)
{
if (service.ImgUrl.IsEmpty)
{
var assembly = typeof(HLandingPage);
service.ImgUrl = ImageSource.FromResource("App.Images.150.png", assembly);
}
OwnerServices.Add(service);
`
No aparent erros triggered. Just empty pictures.
first, you can simplify your Image
<Image HorizontalOptions="Start" WidthRequest="150" HeightRequest="150" Source="{Binding ImgUrl}" />
second, make your ImgUrl property a string
Services.Add(
new Services
{
Name = "Service1",
ServiceType = "Owner",
ImgUrl = "https://via.placeholder.com/150"
});
finally, be sure you're not actually including a trailing space in your url
Generally, we usually define the imgUrl as a string type ,just as follows
private string imgUrl;
public string ImgUrl
{
get { return imgUrl; }
set
{
imgUrl = value;
OnPropertyChange("ImgUrl");
}
}
And binding like this:
<Image Source="{Binding ImgUrl}" />
Of course, when you init the value of ImgUrl. it should be also be string type.
And there is a sample to display image from internet, you can refer to it.
https://github.com/xamarin/xamarin-forms-samples/tree/master/GetStarted/Tutorials/ListViewTutorial
Thank you guys for your help!
Indeed a string for the image did the trick for the souce binding.
Another detail I was missing that I noticed
was setting the ItemsSource in the xaml.cs
protected override void OnAppearing()
{
base.OnAppearing();
viewModel.UpdateServices();
OwnerServicesSlider.ItemsSource = viewModel.OwnerServices;
}
After this Image started showing on the first Item
private string imgUrl;
public string ImgUrl
{
get { return imgUrl; }
set
{
imgUrl = value;
OnPropertyChange("ImgUrl");
}
}
I also added the ItemSource to the xaml
<controls:HorizontalScrollView HeightRequest="200"
SelectedCommand="{Binding OpenPageCommand}"
Orientation="Horizontal"
ItemsSource="{Binding OwnerServices}"
x:Name="OwnerServicesSlider">
<controls:HorizontalScrollView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Margin="10,0,5,0" WidthRequest="150" HeightRequest="150">
<Image HorizontalOptions="Start" Source="{Binding ImgUrl}" WidthRequest="150" HeightRequest="150"/>
<Label Style="{StaticResource BoldLabel}" HorizontalTextAlignment="Center" FontSize="13" LineBreakMode="TailTruncation" Text="{Binding Name}" TextColor="Black"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</controls:HorizontalScrollView.ItemTemplate>
</controls:HorizontalScrollView>
And Im filling my list with different links
Services.Add(
new Services
{
Name = "Service1",
ServiceType = "Owner",
ImgUrl = "http://lorempixel.com/150/150"
});
Services.Add(
new Services
{
Name = "Service2",
ServiceType = "Owner",
ImgUrl = "https://via.placeholder.com/150"
}); ;
Services.Add(
new Services
{
Name = "Service3",
ServiceType = "Owner",
ImgUrl = "https://www.stevensegallery.com/150/150"
});
The Image from https://via.placeholder.com/150 always show but the other two are not showing with the Binding.
Is there somethign Im missing?
I tryed moving the image in the list to be second or even third but only the placeholder shows in any of the positions.

How to update list view from another class in Xamarin forms?

I have created a list view in one class and called delete method from another class. Listview getting call but not updating list view if i call from another class. But its getting update when i call inside the same class. How to solve this issue?
namespace New
{
public partial class WishesPage : ContentPage
{
ListView listView = new ListView();
public WishesPage()
{
InitializeComponent();
var arr = JToken.Parse(ids);
foreach (var ite in arr.Children())
{
var itemProperties = ite.Children<JProperty>();
string contactElement = itemProperties.FirstOrDefault(x => x.Name == "contact").Value.ToString();
sample.Add(contactElement);
}
listView.ItemTemplate = new DataTemplate(typeof(CustomListCell));
listView.ItemsSource = sample;
Content = new StackLayout
{
Children =
{
listView,
}
};
}
public async Task delete(string wishid)
{
indicator.IsRunning = true;
var client = new HttpClient();
client.BaseAddress = new Uri("http:……”);
if (response == "success")
{
listView.ItemsSource = null;
listView.ItemsSource = sample;
}
}
}
public class CustomListCell : ViewCell
{
public CustomListCell()
{
wishIdLabel.SetBinding(Label.TextProperty, new Binding("contact"));
horizontalLayout.Children.Add(wishIdLabel);
var deleteAction = new MenuItem { Text = "Delete", IsDestructive = true };
deleteAction.Clicked += async (sender, e) =>
{
WishesPage wishes = new WishesPage();
wishes.delete(wishId);
};
ContextActions.Add(deleteAction);
}
}
}
I have updated this repo that explain how to use Commands inside a ViewCell.
In your case, you should move the construction of ViewCell inside the ContentPage. Something like
lv.ItemTemplate = new DataTemplate(() =>
{
StackLayout slView = new StackLayout();
Label lDesc = new Label();
lDesc.SetBinding(Label.TextProperty, "Description", stringFormat: "DESCRIPTION: {0}");
var deleteAction = new MenuItem { Text = "Delete", IsDestructive = true }; // red background
deleteAction.SetBinding(MenuItem.CommandProperty, new Binding("BindingContext.TrashCommand", source: this));
deleteAction.SetBinding(MenuItem.CommandParameterProperty, ".");
slView.Children.Add(lDesc);
ViewCell vc = new ViewCell() {View = slView };
vc.ContextActions.Add(deleteAction);
return vc;
}
Now, when you longpress the row, a ContextAction "Delete" appears and a TrashCommand in your ViewModel is executed (you should use MVVM...), a "these" parameter is passed (the selected obj) so you can delete it from the List
this.TrashCommand = new Command(async (object obj) => {
try
{
if (_isTapped)
return;
if (obj != null)
System.Diagnostics.Debug.WriteLine("Obj is not null");
else
System.Diagnostics.Debug.WriteLine("Obj IS null");
_isTapped = true;
var ret = await Application.Current.MainPage.DisplayAlert("Attention", "Delete this row?", "Yes", "No");
if (ret)
{
// List is your "sample" list... Removing the obj, is it reflected to ListView if you use ObservableCollection instead of List
List.Remove((Model)obj);
Count = List.Count;
}
_isTapped = false;
}
catch (Exception ex) {
_isTapped = false;
await Application.Current.MainPage.DisplayAlert("Attention", ex.Message, "Ok");
}
});
}

web.api only serializing hidden fields

I'm experiencing a strange behaviour.
My web.api is returning only hiddenfields from my ObjectCollection on a GET request.
This is my controller:
// GET: api/UserDocuments
[Route("api/UserDocuments/User/{userName}")]
public List<DocIndex> Get(string userName)
{
User usuari = Humanisme.User.LoadByUserName(userName);
List<DocIndex> resposta = DocumentCollection.LoadIndexPerUsuari(usuari);
return resposta;
}
And this is the object as it gets generated from the BOM:
namespace Humanisme
{
using CodeFluent.Runtime;
using CodeFluent.Runtime.Utilities;
// CodeFluent Entities generated (http://www.softfluent.com). Date: Tuesday, 01 March 2016 11:52.
// Build:1.0.61214.0820
[System.CodeDom.Compiler.GeneratedCodeAttribute("CodeFluent Entities", "1.0.61214.0820")]
[System.SerializableAttribute()]
[System.ComponentModel.DataObjectAttribute()]
public partial class DocIndex : CodeFluent.Runtime.ICodeFluentLightEntity
{
private int _id = -1;
[System.NonSerializedAttribute()]
private Humanisme.User _user = ((Humanisme.User)(null));
private string _lat = default(string);
private string _lon = default(string);
private string _etapaVital = default(string);
private string _solvencia = default(string);
private int _valoracio = CodeFluentPersistence.DefaultInt32Value;
private System.DateTime _data = CodeFluentPersistence.DefaultDateTimeValue;
private string _nom = default(string);
public DocIndex()
{
}
[System.ComponentModel.DefaultValueAttribute(((int)(-1)))]
[System.Xml.Serialization.XmlElementAttribute(IsNullable=false, Type=typeof(int))]
[System.ComponentModel.DataObjectFieldAttribute(true)]
public int Id
{
get
{
return this._id;
}
set
{
this._id = value;
}
}
[System.Xml.Serialization.XmlIgnoreAttribute()]
public Humanisme.User User
{
get
{
return this._user;
}
set
{
this._user = value;
}
}
[System.ComponentModel.DefaultValueAttribute(default(string))]
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true, Type=typeof(string))]
public string Lat
{
get
{
return this._lat;
}
set
{
this._lat = value;
}
}
[System.ComponentModel.DefaultValueAttribute(default(string))]
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true, Type=typeof(string))]
public string Lon
{
get
{
return this._lon;
}
set
{
this._lon = value;
}
}
[System.ComponentModel.DefaultValueAttribute(default(string))]
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true, Type=typeof(string))]
public string EtapaVital
{
get
{
return this._etapaVital;
}
set
{
this._etapaVital = value;
}
}
[System.ComponentModel.DefaultValueAttribute(default(string))]
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true, Type=typeof(string))]
public string Solvencia
{
get
{
return this._solvencia;
}
set
{
this._solvencia = value;
}
}
[System.ComponentModel.DefaultValueAttribute(CodeFluentPersistence.DefaultInt32Value)]
[System.Xml.Serialization.XmlElementAttribute(IsNullable=false, Type=typeof(int))]
public int Valoracio
{
get
{
return this._valoracio;
}
set
{
this._valoracio = value;
}
}
[System.Xml.Serialization.XmlElementAttribute(IsNullable=false, Type=typeof(System.DateTime))]
public System.DateTime Data
{
get
{
return this._data;
}
set
{
this._data = value;
}
}
[System.ComponentModel.DefaultValueAttribute(default(string))]
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true, Type=typeof(string))]
public string Nom
{
get
{
return this._nom;
}
set
{
this._nom = value;
}
}
protected virtual void ReadRecord(System.Data.IDataReader reader, CodeFluent.Runtime.CodeFluentReloadOptions options)
{
if ((reader == null))
{
throw new System.ArgumentNullException("reader");
}
if ((((options & CodeFluent.Runtime.CodeFluentReloadOptions.Properties)
== 0)
== false))
{
this._id = CodeFluentPersistence.GetReaderValue(reader, "Id", ((int)(-1)));
this._user = new Humanisme.User();
CodeFluent.Runtime.CodeFluentLightWeightPersistence.ReadRecord(reader, this._user, null, new CodeFluent.Runtime.Utilities.Pair<string, string>("Id", "User_Id"));
this._lat = CodeFluentPersistence.GetReaderValue(reader, "Lat", ((string)(default(string))));
this._lon = CodeFluentPersistence.GetReaderValue(reader, "Lon", ((string)(default(string))));
this._etapaVital = CodeFluentPersistence.GetReaderValue(reader, "EtapaVital", ((string)(default(string))));
this._solvencia = CodeFluentPersistence.GetReaderValue(reader, "Solvencia", ((string)(default(string))));
this._valoracio = CodeFluentPersistence.GetReaderValue(reader, "Valoracio", ((int)(CodeFluentPersistence.DefaultInt32Value)));
this._data = CodeFluentPersistence.GetReaderValue(reader, "Data", ((System.DateTime)(CodeFluentPersistence.DefaultDateTimeValue)));
this._nom = CodeFluentPersistence.GetReaderValue(reader, "Nom", ((string)(default(string))));
}
}
void CodeFluent.Runtime.ICodeFluentLightEntity.ReadRecord(System.Data.IDataReader reader)
{
this.ReadRecord(reader, CodeFluent.Runtime.CodeFluentReloadOptions.Default);
}
}
}
Calling the web.api get method returns this JSON:
[
{
"_id": 1,
"_lat": null,
"_lon": null,
"_etapaVital": null,
"_solvencia": null,
"_valoracio": 0,
"_data": "0001-01-01T00:00:00",
"_nom": null
}
]
Serializer (from WebApiConfig.cs)
JsonMediaTypeFormatter jsonFormatter = (JsonMediaTypeFormatter)config.Formatters.FirstOrDefault(f => f is JsonMediaTypeFormatter);
if (jsonFormatter != null)
{
// jsonFormatter.SerializerSettings.NullValueHandling = NullValueHandling.Include;
jsonFormatter.UseDataContractJsonSerializer = true;
}
The classes generated by CodeFluent Entities are decorated by SerializableAttribute. This attribute changes the way Json.NET serialize or deserialize the object. You can configure Json.NET to ignore this attribute:
JsonMediaTypeFormatter jsonFormatter = (JsonMediaTypeFormatter)config.Formatters.FirstOrDefault(f => f is JsonMediaTypeFormatter);
if (jsonFormatter != null)
{
jsonFormatter.SerializerSettings.ContractResolver = new DefaultContractResolver()
{
IgnoreSerializableAttribute = true
};
}
http://james.newtonking.com/archive/2012/04/11/json-net-4-5-release-2-serializable-support-and-bug-fixes
Json.NET now detects types that have the SerializableAttribute and serializes all the fields on that type, both public and private, and ignores the propertie
So you can use the service producer which will add the DataMemberAttribute or you can use the Json.NET Aspect to automatically add specific Json.NET attribute: Newtonsoft.Json.JsonObjectAttribute and Newtonsoft.Json.JsonPropertyAttribute.
Finally found!
When dealing with web.api never, never, never forget to add the "Service Producer" subproducer attached to the standard BOM Producer in your model project.
You'll never notice any problem but at serializing when no attributes will be processed and only hidden properties (object fields) will be serialized at output.
Sorry for the nerd mistake, happy for the lesson learned.
Again, thanks Meziantou. You would never figured where the issue was originated, mainly because I didn't carried all the project details to the question.