2017-01-04 6 views
1

В моем веб-приложении ASP.NET MVC я использую встроенный метод Controller.Json() для сериализации объекта и отправки его обратно клиенту в ответ на вызов AJAX. Класс сериализуемого объекта наследуется от другого класса с некоторыми именами общих свойств. Это преднамеренно, так как мне нужны имена свойств, чтобы они соответствовали некоторому отражению, которое происходит. Я «затеняю» те свойства в производном классе, чтобы они могли быть другого типа от их одноименного аналога в базовом классе. Вот упрощенный пример:Как получить только теневое свойство, а не базовое свойство, чтобы получить JSON-сериализацию?

public class BaseModel 
{ 
    public string Title { get; set; } 
    public decimal CleanUpHours { get; set; } 
    public decimal InstallHours { get; set; } 
} 

public class DerivedModel : BaseModel 
{ 
    public new BucketHoursWithCalculations CleanUpHours { get; set; } 
    public new BucketHoursWithCalculations InstallHours { get; set; } 
} 

Когда я сериализовать экземпляр DerivedModel, мой JSON объект на клиенте содержит только decimal версии CleanUpHours и InstallHours, а не мой собственный класс BucketHoursWithCalculations.

Проверка объекта в Visual Studio до его сериализации показывает как базовую, , но принцип тот же):

Visual Studio

Вот что этот объект выглядит как на стороне клиента, как только это сериализовать в формате JSON:

ng-inspector in Chrome

Как вы можете видеть, производные/тенированные свойства не были сериализованы, а базовые свойства были, но только в тех случаях, когда был конфликт имен (например, свойство Title в базовой модели сериализовалось просто отлично).

Как я могу сериализовать только тенированные свойства, где есть конфликт имен? Я не считаю, что изменение модификаторов доступа (то есть от public до protected или что-то) в базовых свойствах будет работать в моем случае, потому что BaseModel используется Entity Framework и должен иметь общедоступные свойства. Любая помощь будет оценена по достоинству.

+0

Как украсить ненужные свойства атрибутом '' '[NonSerialized()]' ''? – uncoder

+0

@uncoder К сожалению, этот атрибут не работает в унаследованных классах, где живут нежелательные свойства –

+1

Вы не скрываете свойства, вы их скрываете. У вас есть два полностью отдельных экземпляра переменной с именем CleanUpHours и InstallHours. Согласно JSON, который основан исключительно на строках, которые следует сериализовать где? У вас не должно быть двух разных типов объектов с тем же именем. – Dispersia

ответ

3

Одна из идей - определить параметр типа в базовой модели, который используется для свойств часов. Затем определите производные модели для decimal и BucketHoursWithCalculations. Мне было бы интересно увидеть, как BucketHoursWithCalculations сериализуется в JSON, но в любом случае свойства CleanUpHours и InstallHours должны быть сериализованы.

// use a type parameter on the base model that must be specified 
// in derived models. 
public class BaseModel<THours> 
{ 
    public string Title { get; set; } 
    public THours CleanUpHours { get; set; } 
    public THours InstallHours { get; set; } 
} 

// hours are specified as decimals 
public class DecimalModel : BaseModel<decimal> 
{ 
} 

// hours are specified as BucketHoursWithCalculations  
public class BucketHoursWithCalculationsModel : BaseModel<BucketHoursWithCalculations> 
{ 
} 

// usage 
DecimalModel d = new DecimalModel(); 
d.CleanUpHours = 1.0M; // CleanUpHours is a decimal here 

BucketHoursWithCalculationsModel b = new BucketHoursWithCalculationsModel(); 
b.CleanUpHours = new BucketHoursWithCalculations(); 
b.CleanUpHours.SomeProperty = 1.0M; 
+0

Это сделало трюк, спасибо! Кажется, сериализатор Microsoft просто не знает, как обрабатывать скрытые свойства, и этот ответ отлично подходит к этой проблеме. https://s28.postimg.org/uaxvwcmrx/2017_01_06_19_23_44.png –

+0

Рад слышать, что сработало для вас :) – dana