Win7 では正常に動作する非常に単純な ApiController がありますが、Windows 2003 Server ではエラーが発生します。
get リクエスト (ブラウザまたは $.getJson から):
https://site.com:61656/AD/Authenticate?UserName=xxxx&Password=xxxxx&AuthKey=xxxxxx
次のエラーが表示されます。
<Exception xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/System.Web.Http.Dispatcher">
<ExceptionType>System.InvalidOperationException</ExceptionType>
<Message>
No MediaTypeFormatter is available to read an object of type 'InputModel' from content with media type ''undefined''.
</Message>
<StackTrace>
at System.Net.Http.HttpContentExtensions.ReadAsAsync[T](HttpContent content, Type type, IEnumerable`1 formatters, IFormatterLogger formatterLogger) at System.Web.Http.ModelBinding.FormatterParameterBinding.ReadContentAsync(HttpRequestMessage request, Type type, IEnumerable`1 formatters, IFormatterLogger formatterLogger) at System.Web.Http.ModelBinding.FormatterParameterBinding.ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken) at System.Web.Http.Controllers.HttpActionBinding.<>c__DisplayClass1.<ExecuteBindingAsync>b__0(HttpParameterBinding parameterBinder) at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() at System.Threading.Tasks.TaskHelpers.IterateImpl(IEnumerator`1 enumerator, CancellationToken cancellationToken)
</StackTrace>
</Exception>
2012 年 5 月 1 日の nuget ナイトリー ビルド パッケージを使用しています。HttpContentExtensions.cs の次の行で、objectContent.Value が Windows 2003 Server では null を通過しているように見えますが、Windows 7 ではそうではありません。
if (objectContent != null && objectContent.Value != null && type.IsAssignableFrom(objectContent.Value.GetType()))
{
return TaskHelpers.FromResult((T)objectContent.Value);
}
コントローラーのアクション:
[AcceptVerbs("GET", "POST")]
public ResultModel Authenticate(InputModel inputModel)
{
var test = ControllerContext.Request.Content.Headers.ContentType;
//Console.WriteLine(test.MediaType);
try
{
Console.WriteLine("AD Authorize request received: " + inputModel.UserName);
var ldap = new LdapAuthentication();
return ldap.Authenticate(inputModel);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return new ResultModel();
}
}
MediaType は、Win7 では null を介して取得されますが、Windows 2003 サーバーでは、要求がコントローラー アクションに送信されることはありません。
「未定義」のメディア タイプを処理するデフォルトのメディア フォーマッタを指定する方法はありますか?
編集:
入力モデルは次のとおりです。
public class InputModel {
public string UserName { get; set; }
public string Password { get; set; }
public string AuthKey { get; set; }
}
そして、ここに(セルフホスト)構成があります:
var config = new HttpsSelfHostConfiguration(ConfigurationManager.AppSettings["serviceUrl"]);
config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
config.Routes.MapHttpRoute("default", "{controller}/{action}");
var server = new HttpSelfHostServer(config);
try
{
server.OpenAsync().Wait();
Console.WriteLine("Waiting...");
編集#2:
私は、Win7 と Windows 2003 Server のより興味深い動作に気付きました。コントローラ アクションの InputModel パラメータを削除すると、Win7 と Windows 2003 Server の両方で実行中にアクションが呼び出されます。ただし、Win7 では、GET と POST の両方の要求から JSON を返します。Windows 2003 Server では、GET から XML を返し、POST から JSON を返します。
これにより、POST を使用して InputModel パラメーターをテストすることになりました。アクションが正しく呼び出され、InputModel パラメータが Windows 2003 Server でバインドされていることを確認しましたが、POST を使用している場合のみです。したがって、回避策は、GET でパラメーターを手動で取得することです。これにより、jQuery の $.getJSON は、Windows 2003 Server の下で自己ホスト型サーバーに対して機能することができます。
[AcceptVerbs("GET")]
public ResultModel Authenticate()
{
try
{
var inputModel = new InputModel();
var query = ControllerContext.Request.RequestUri.ParseQueryString();
inputModel.UserName = query.GetValues("UserName") != null ? query.GetValues("UserName")[0] : null;
inputModel.Password = query.GetValues("Password") != null ? query.GetValues("Password")[0] : null;
inputModel.AuthKey = query.GetValues("AuthKey") != null ? query.GetValues("AuthKey")[0] : null;
Console.WriteLine("AD Authorize request received: " + inputModel.UserName);
var ldap = new LdapAuthentication();
return ldap.Authenticate(inputModel);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return new ResultModel();
}
}