Я думаю, что это похоже на проблемы, с которыми мы сталкивались ранее в наших проектах.
Вы должны изменить почтовый индекс для jQuery на следующий:
$.ajax({
type: 'POST',
url: '/api/api/Test',
data: JSON.stringify({ ID: 29, MyWidget: null }),
contentType: "application/json",
dataType: 'json',
timeout: 30000
})
.done(function (data) {
})
.fail(function() {
});
По умолчанию jQuery 'posts' отправляет параметры в виде данных, закодированных в виде URL-адреса формы.
application/x-www-form-urlencoded
ID 29
MyWidget
ID=29&Мой виджет=
Так что он был десериализован абсолютно правильно. MyWidget — это пустая строка, поэтому она будет иметь пустое значение класса Widget.
Кроме того, я рекомендую вам добавить конфигурацию Formatters для контроллеров WebApi:
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
// Formatters
JsonMediaTypeFormatter json = config.Formatters.JsonFormatter;
config.Formatters.Clear();
config.Formatters.Add(json);
}
Таким образом, вы будете использовать только форматировщик JSON для вызовов API.
ОБНОВЛЕНИЕ
Основное отличие заключается в том, что данные, закодированные в форме URL-адреса, передаваемые контроллеру MVC, будут обрабатываться во время выполнения и, наконец, обрабатываться DefaultModelBinder (если пользовательский связыватель недоступен). Таким образом, данные, закодированные как URL-адрес формы, являются обычными для MVC, потому что обычно данные генерируются публикацией HTML-формы. Но веб-API не полагается на какую-либо конкретную кодировку. Поэтому он использует специальный механизм (форматеры) для анализа данных... например, json, как показано выше. Таким образом, FormUrlEncodedMediaTypeFormatter из System.Net.Http.Formatting и DefaultModelBinder из System.Web.Mvc по-разному обрабатывают пустую строку.
Для DefaultModelBinder пустая строка будет преобразована в null. Анализируя код, я могу решить, что метод BindModel сначала создает пустую модель:
if (model == null)
{
model = CreateModel(controllerContext, bindingContext, modelType);
}
После того, как он заполнит свойства:
// call into the property's model binder
IModelBinder propertyBinder = Binders.GetBinder(propertyDescriptor.PropertyType);
object originalPropertyValue = propertyDescriptor.GetValue(bindingContext.Model);
ModelMetadata propertyMetadata = bindingContext.PropertyMetadata[propertyDescriptor.Name];
propertyMetadata.Model = originalPropertyValue;
ModelBindingContext innerBindingContext = new ModelBindingContext()
{
ModelMetadata = propertyMetadata,
ModelName = fullPropertyKey,
ModelState = bindingContext.ModelState,
ValueProvider = bindingContext.ValueProvider
};
object newPropertyValue = GetPropertyValue(controllerContext, innerBindingContext, propertyDescriptor, propertyBinder);
И, наконец, GetBinder вернет fallbackBinder для типа виджета (типа свойства). И сам fallbackBinder вызовет ConvertSimpleType, где строка обрабатывается следующим образом:
string valueAsString = value as string;
if (valueAsString != null && String.IsNullOrWhiteSpace(valueAsString))
{
return null;
}
Я предполагаю, что нет никаких стандартов, описывающих преобразование из строк в кодировке URL в объекты C#. Так что я не знаю, какой из них правильный. В любом случае я уверен, что вам нужно передавать json через вызовы AJAX, а не данные в формате URL-адреса.
person
Maxim
schedule
06.01.2016
Model
создастWidget
в своем конструкторе по умолчанию и присвоит егоMyWidget
, не так ли? - person dbc   schedule 06.01.2016