Windows 2003 Server 上没有可用的 MediaTypeFormatter

Posted

技术标签:

【中文标题】Windows 2003 Server 上没有可用的 MediaTypeFormatter【英文标题】:No MediaTypeFormatter is available on Windows 2003 Server 【发布时间】:2012-05-11 10:04:23 【问题描述】:

我有一个非常简单的 ApiController,它在 Win7 上运行良好,但在 Windows 2003 Server 上却出现错误。

获取请求(来自浏览器或 $.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 nightly build 包。在 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 服务器上,请求永远不会到达控制器操作。

有没有办法指定一个默认的媒体格式化程序来处理“'undefined'”媒体类型?

编辑:

这是输入模型:

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();
    

【问题讨论】:

这个运气好吗?我也有同样的问题。 【参考方案1】:

您能显示配置的格式化程序以及您的 InputModel 类吗?看起来序列化程序无法处理您的课程。您是否在任何属性上使用接口?

【讨论】:

我已经添加了输入模型和配置。在 Win7 下运行时确实绑定了 InputModel,只是在 Windows 2003 Server 下不绑定

以上是关于Windows 2003 Server 上没有可用的 MediaTypeFormatter的主要内容,如果未能解决你的问题,请参考以下文章

Windows server 2003高可用NLB和服务器群集配置

安全模式下windows server 2003中sql server服务如何启动

Windows Server 2003服务器集群技术 (完整版)

Windows Server 2003 enterprise edition是啥版本

System x 服务器制作ServerGuide U盘安装Windows Server 2003 操作系统

在Windows2003 server 64位系统上使用ArcEngine开发的WCF服务