2017-01-24 10 views
4

В приложении .netcore, я хотел бы предложить следующее (упрощенно):.NetCore MVC десериализации

// Create a new record, assume it returns an ID=1 
https://site/MyController/Save?FirstName=John&LastName=Doe&Status=Active 

// Update the record without full state 
PUT https://site/MyController/1 
{ 
    'DOB': '1/1/1970', 
    'Status': null 
} 

Я хотел бы перевести этот второй вызов:

UPDATE MyModel SET DOB = '1/1/1970' AND Status=NULL WHERE Id = 1 

я могу конечно, код мой Create метод в MyController для анализа запроса (querystring/form/body) для представленных значений и создания моего SQL соответственно.

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

public async Task<MyModel> Save(string id, [FromBody]MyModel instance) 
{ 
    await _MyRepository.UpdateAsync(id, message); 
    return message; 
} 

Проблема здесь состоит в том, что экземпляр будет выглядеть следующим образом:

{ 
    'FirstName': null, 
    'LastName': null, 
    'DOB': '1/1/1970', 
    'Status': null 
} 

В этот момент I не может определить, какие поля должны быть NULLED в Db, и которые следует оставить в покое.

Я реализовал класс-оболочку, которая:

  • на десериализации, устанавливает любые «грязные» свойства и
  • При сериализации, пишет только грязные свойства

Это изменение будет мой методу, но не налагать бремя на разработчиков:

public async Task<MyModel> Save(string id, [FromBody]MyWrapper<MyModel> wrapper 
{ 
    await _MyRepository.UpdateAsync(id, wrapper.Instance, wrapper.DirtyProperties); 
    return wrapper.Instance; 
} 

Моих два вопроса:

  1. ли я повторно изобрести отработанную схему?
  2. Могу ли я перехватить дезактивацию MVC (элегантным образом)?
+0

Не используйте модели устойчивости в качестве возвращаемых или входных значений действий контроллера. Он кричит о неприятностях – Tseng

ответ

1

Вы можете ознакомиться с пользовательской привязкой модели.

  • создать собственную модель связующего: класс, который реализует IModelBinder интерфейс:

    /// <summary> 
    /// Defines an interface for model binders. 
    /// </summary> 
    public interface IModelBinder 
    { 
        /// <summary> 
        /// Attempts to bind a model. 
        /// </summary> 
        /// <param name="bindingContext">The <see cref="ModelBindingContext"/>.</param> 
        /// <returns> 
        /// <para> 
        /// A <see cref="Task"/> which will complete when the model binding process completes. 
        /// </para> 
        /// <para> 
        /// If model binding was successful, the <see cref="ModelBindingContext.Result"/> should have 
        /// <see cref="ModelBindingResult.IsModelSet"/> set to <c>true</c>. 
        /// </para> 
        /// <para> 
        /// A model binder that completes successfully should set <see cref="ModelBindingContext.Result"/> to 
        /// a value returned from <see cref="ModelBindingResult.Success"/>. 
        /// </para> 
        /// </returns> 
        Task BindModelAsync(ModelBindingContext bindingContext); 
    } 
    
  • зарегистрировать связующий:

    services.AddMvc().Services.Configure<MvcOptions>(options => { 
        options.ModelBinders.Insert(0, new YourCustomModelBinder()); 
    }); 
    

MVC GitHub репо и "Custom Model Binding" статья может помочь :

+0

Это действительно достигает того, о чем я просил. Тем не менее, это также оставляет меня в соблазн просто создавать Middleware, так как я (до сих пор) использовал очень мало добавочных значений MVC. Что, конечно, противоречит моему вопросу! –

0

Глагол PUT требует всего объекта, но вы можете отправить HTTP PATCH с дельта. Существует немного официальной документации о том, как именно это делается, но я нашел это link, в котором описано, как это сделать с помощью JSONPatchDocument, который делает в основном то, что делает ваш класс перехвата.

+0

Элегантный с точки зрения сервера! Для моих случаев использования я пытаюсь сделать жизнь простой для клиента/потребителя, и заставить их принять довольно подробный документ PATCH будет проблемой. [link] (http://jsonpatch.com/) –

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