ASP.NET Web API不返回XML

tom*_*tom 5 c# xml post json asp.net-web-api

我有一个控制器和方法,可以将用户添加到数据库.

我从Fiddler用请求标题调用它如下 -

Content-Type:application/xml

接受:application/xml

主持人:localhost:62236

内容长度:39

和请求机构 -

<User>
  <Firstname>John</Firstname>
  <Lastname>Doe</Lastname>
</User>
Run Code Online (Sandbox Code Playgroud)

这按预期工作,该方法被调用,用户对象在PostUser方法中处理.

 public class UserController : ApiController
    {
        public HttpResponseMessage PostUser(User user)
        {
            // Add user to DB
            var response = new HttpResponseMessage(HttpStatusCode.Created);
            var relativePath = "/api/user/" + user.UserID;
            response.Headers.Location = new Uri(Request.RequestUri, relativePath);
            return response;
        }
    }
Run Code Online (Sandbox Code Playgroud)

我在它自己的类中执行模型验证

public class ModelValidationFilterAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        if (actionContext.ModelState.IsValid == false)
        {
            // Return the validation errors in the response body.
            var errors = new Dictionary<string, IEnumerable<string>>();
            foreach (KeyValuePair<string, ModelState> keyValue in actionContext.ModelState)
            {
                errors[keyValue.Key] = keyValue.Value.Errors.Select(e => e.ErrorMessage);
            }

            actionContext.Response =
                actionContext.Request.CreateResponse(HttpStatusCode.BadRequest, errors);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

但如果我发布以下内容

<User>
  <Firstname></Firstname> **//MISSING FIRST NAME**
  <Lastname>Doe</Lastname>
</User>
Run Code Online (Sandbox Code Playgroud)

模型无效,即使我声明Accept:application/xml,也会返回JSON响应.

如果我在UserController中执行模型验证,我会得到一个正确的XML响应,但是当我在ModelValidationFilterAttribute中执行它时,我得到了JSON.

nem*_*esv 6

你有以下代码的问题:

var errors = new Dictionary<string, IEnumerable<string>>();
actionContext.Request.CreateResponse(HttpStatusCode.BadRequest, errors);
Run Code Online (Sandbox Code Playgroud)

因此,您尝试errors从其类型所在的对象创建响应Dictionary<string, IEnumerable<string>>();.

Web.API将尝试自动找到MediaTypeFormatter您的响应类型的权限.但是,默认的XML序列化程序(DataContractSerializer)无法处理该类型,Dictionary<string, IEnumerable<string>>();因此它将使用JSON序列化程序进行响应.

实际上你应该使用CreateErrorResponse并直接创建响应ModelState(它将创建一个HttpErrorXML可串行的对象)

public class ModelValidationFilterAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        if (actionContext.ModelState.IsValid == false)
        {
            actionContext.Response =
                actionContext.Request.CreateErrorResponse(
                    HttpStatusCode.BadRequest, 
                    actionContext.ModelState);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)