2017-02-22 10 views
0

У меня есть один интерфейс и два класса, которые его реализуют.ошибка отправки интерфейса реализации как json от клиента

namespace FirebaseNet.Messaging 
{ 
    public interface INotification 
    { 
     string Title { get; set; } 
    } 

    public class AndroidNotification : INotification 
    { 
     public string Title { get; set; } 
    } 

    public class IOSNotification : INotification 
    { 
     public string Title { get; set; } 
    } 
} 

Теперь у меня есть другой класс.

public class Message 
{ 
    public INotification Notification { get; set; } 
} 

Параметр Сообщение передается в класс, как этот

[HttpPost] 
public async Task<JsonResult> SendMessage(Message message) 

Этот параметр может быть либо

var message = new Message() 
{ 
    Notification = new AndroidNotification() 
    { 
     Title = "Portugal vs. Denmark" 
    } 
}; 

или

var message = new Message() 
{ 
    Notification = new IOSNotification() 
    { 
     Title = "Portugal vs. Denmark" 
    } 
}; 

До сих пор все работает. Теперь я хочу получить AJAX POST до SendMessage. Я попытался использовать этот DTO.

JavaScript код

var message = { 
    Notification : { 
     Title : "Portugal vs. Denmark" 
    } 
}; 

Это, очевидно, не удалось с

Не удается создать экземпляр интерфейса.

Что было бы идеальным обходным путем?

P.S: Мысль изменения Message класс

public class Message 
{ 
    public INotification Notification { get; set; } 
    public AndroidNotification AndroidNotification { get; set; } 
    public IOSNotification IOSNotification { get; set; } 
} 

Это DLL третья сторона, и я не хочу прикоснуться к ней идеально.

ответ

2

Один из способов добиться того, что бы написать собственную модель связующий:

public class NotificationModelBinder : DefaultModelBinder 
{ 
    protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType) 
    { 
     var typeValue = bindingContext.ValueProvider.GetValue("ModelType"); 
     var type = Type.GetType(
      (string)typeValue.ConvertTo(typeof(string)), 
      true 
     ); 

     if (!typeof(INotification).IsAssignableFrom(type)) 
     { 
      throw new InvalidOperationException("Bad Type"); 
     } 

     var model = Activator.CreateInstance(type); 
     bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, type); 
     return model; 
    } 
} 

, что вы регистрируетесь бы когда развернув приложение:

ModelBinders.Binders.Add(
    typeof(INotification), 
    new NotificationModelBinder() 
); 

это будет теперь позволяет клиенту указать конкретный тип уведомления:

var message = { 
    ModelType: "WebApplication1.Models.AndroidNotification", 
    Notification : { 
     Title : "Portugal vs. Denmark" 
    } 
}; 

или:

var message = { 
    ModelType: "WebApplication1.Models.IOSNotification", 
    Notification : { 
     Title : "Portugal vs. Denmark" 
    } 
}; 

Конечно, вы можете настроить привязку к модели для точного имени свойства, которое указывает конкретный тип и возможные значения. В моем примере должно использоваться полное имя типа, но вы можете иметь некоторое сопоставление с более дружественными именами.

+0

У меня есть проект 'p1.FirebaseNet', на который ссылаются в' WebApp1'. Я попробовал 'p1.FirebaseNet.Messaging.AndroidNotification' (а также' FirebaseNet.Messaging.AndroidNotification') как 'ModelType' в json-вызове. Это не удалось с исключением: «Не удалось загрузить тип« p1.FirebaseNet.Messaging.AndroidNotification »из сборки« WebApp1, Version..' Что я могу делать неправильно? – naveen

 Смежные вопросы

  • Нет связанных вопросов^_^