升级到 MVC4 RC:没有 MediaTypeFormatter 可用于从媒体类型为“未定义"的内容中读取“TestRequestModel"类型的对象 [英] Upgrading to MVC4 RC: No MediaTypeFormatter is available to read an object of type 'TestRequestModel' from content with media type ''undefined''

查看:26
本文介绍了升级到 MVC4 RC:没有 MediaTypeFormatter 可用于从媒体类型为“未定义"的内容中读取“TestRequestModel"类型的对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在使用 MVC4 测试版,目前正在努力升级到最近发布的 RC 版本.

I've been using the MVC4 beta and am currently working to upgrade to the recently released RC version.

模型绑定复杂请求类型似乎发生了变化,但我不知道我做错了什么.

It appears that model-binding complex request types has changed, but I can't figure out how / what I'm doing wrong.

例如,假设我有以下 API 控制器:

For example, say I have the following API controller:

public class HomeApiController : ApiController
{
    public TestModel Get()
    {
        return new TestModel
        {
            Id = int.MaxValue,
            Description = "TestDescription",
            Time = DateTime.Now
        };
    }
}

这产生了预期的结果:

<TestModel xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/xxxx">
    <Description>TestDescription</Description>
    <Id>2147483647</Id>
    <Time>2012-06-07T10:30:01.459147-04:00</Time>
</TestModel>

现在说我只是更改签名,接受请求类型,如下所示:

Now say I just change the signature, taking in a request type, like this:

public TestModel Get(TestRequestModel request)
{
    ...

public class TestRequestModel
{
    public int? SomeParameter { get; set; }
}

我现在收到以下错误:

<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 'TestRequestModel' 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.Net.Http.HttpContentExtensions.ReadAsAsync(HttpContent content, 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>

我已经查看了在 HttpContentExtensions 中抛出此异常的源代码,但它似乎检查了内容标头(我应该有),如果没有让它尝试从 MediaTypeFormatter 集合中获取一个特定类型(它不能)的格式化程序,然后抛出.

I've looked at the source code of where this exception is thrown in the HttpContentExtensions, but it looks like it checks for content headers (which I should have), and if it doesn't have that it tries to get a formatter from the MediaTypeFormatter collection it has for the specific type (which it can't) and then throws.

有其他人遇到过这种情况吗?我缺少某些全局注册?

推荐答案

我看到您原来的问题已得到解答,但要回答另一个问题,模型绑定在 RC 中发生了一些变化.

I see your original question was answered, but to answer the other one, Model binding has changed somewhat in the RC.

http://weblogs.thinktecture.com/cweyer/2012/06/aspnet-web-api-changes-from-beta-to-rc.html

这个链接有一些关于它的细节.但总结一下似乎影响您的更改,模型绑定从请求的正文或 uri 中提取其值.对于以前的版本也是如此,但是对于候选版本,MVC4 将默认查看复杂类型的主体和值类型的 uri.

This link has some details about it. But to sum up the change that appears to be affecting you, Model binding pulls its values from either the body, or the uri of the request. This is true for previous releases as well, but with the release candidate, MVC4 will, by default, look to the body for complex types, and the uri for value types.

因此,如果您提交包含SomeParameter"键的请求的正文,您应该看到它绑定.或者,如果您将声明更改为:

So, if you submit a body with your request containing the "SomeParameter" key, you should see it bind. Or you could bind with the url if you change the declaration to:

 public TestModel Get(int? someParameter)
 {

 }

幸运的是,团队预见到了潜在的问题,并为我们留下了可用于覆盖此行为的属性.

Thankfully, the team foresaw the potential problems with this and left us with attributes we could use to override this behavior.

 public TestModel Get([FromUri]TestRequestModel request)
 {

 }

这里的关键是 [FromUri] 它告诉模型绑定器在 uri 中查找值.如果您想在请求正文中放置值类型,还有 [FromBody].

The key here is the [FromUri] which tells the model binder to look in the uri for the values. There is also [FromBody] if you want to put a value type in the body of a request.

这篇关于升级到 MVC4 RC:没有 MediaTypeFormatter 可用于从媒体类型为“未定义"的内容中读取“TestRequestModel"类型的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆