私はこれまでのプロジェクトで経験した問題と似ていると思います。あなたは、次のいずれかに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の「ポスト」によっては、フォームのURLエンコードされたデータなどのパラメータを送信します。
アプリケーション/ x-www-form-urlencodedで
ID 29
はMyWidget
ID = 29 &はMyWidget =
だから、それが絶対的に正しくデシリアライズされました。 MyWidgetは空文字列なので、Widgetクラスの値は空になります。また
私は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);
}
ですから、APIコールにのみJSON-フォーマッタを使用します。MVCコントローラに渡さ
UPDATE
主な違いは、そのフォームのURLエンコードされたデータは、ランタイムによって処理され、最終的にDefaultModelBinderによって処理される(カスタムバインダーが使用できない場合)。したがって、通常はHTMLフォームのポストによってデータが生成されるため、form-urlとしてエンコードされたデータはMVCでは通常です。しかし、Web APIは設計によって特定のエンコーディングに依存していません。したがって、データを解析するために特定のメカニズム(フォーマッタ)を使用します。例えば、上記のようなjsonです。 System.Net.Http.FormattingのFormUrlEncodedMediaTypeFormatterとSystem.Web.MvcのDefaultModelBinderは、空の文字列を異なる方法で処理します。
DefaultModelBinderの空の文字列はnullに変換されます。それがプロパティを記入します後
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を返します の解析コードIはBindModel方法は、まず、空のモデルを作成することを決定することができます。そして、文字列は次のように処理されるfallbackBinder自体がConvertSimpleTypeを呼び出します:
string valueAsString = value as string;
if (valueAsString != null && String.IsNullOrWhiteSpace(valueAsString))
{
return null;
}
を私はC#のオブジェクトへのURLエンコードされた文字列からの変換を記述していない任意の基準があると思います。だから私はどちらが正しいかわからない。いずれにしても、form-url-encodedデータではなくAJAX呼び出しを介してjsonを渡す必要があると確信しています。
'Model'がデフォルトのコンストラクタに' Widget'を作成し、それを 'MyWidget'に代入することはありません。 – dbc
どのWeb APIのバージョンを使用していますか? –
@dbc、クラスはあなたがそれを見るのとまったく同じものではありません。コンストラクタは指定されていません。さらに、それがコンストラクタベースの問題であれば、両方のコントローラで発生します。 –