5

DBにユーザーを追加するコントローラーとメソッドがあります。

私は次のようにリクエストヘッダーを使用してFiddlerから呼び出します-

コンテンツタイプ:application / xml

受け入れる:application / xml

ホスト:localhost:62236

コンテンツの長さ:39

そして-のリクエスト本文

<User>
  <Firstname>John</Firstname>
  <Lastname>Doe</Lastname>
</User>

これは期待どおりに機能し、メソッドが呼び出され、ユーザーオブジェクトがメソッド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;
        }
    }

独自のクラスでモデル検証を実行しています

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

しかし、私が以下を投稿した場合

<User>
  <Firstname></Firstname> **//MISSING FIRST NAME**
  <Lastname>Doe</Lastname>
</User>

モデルが無効であり、Accept:application / xmlと述べても、JSON応答が返されます。

UserController内でモデル検証を実行すると、適切なXML応答が得られますが、ModelValidationFilterAttributeで実行すると、JSONが得られます。

4

2 に答える 2

6

次のコードに関する問題:

var errors = new Dictionary<string, IEnumerable<string>>();
actionContext.Request.CreateResponse(HttpStatusCode.BadRequest, errors);

したがってerrors、タイプがであるオブジェクトから応答を作成しようとしますDictionary<string, IEnumerable<string>>();

MediaTypeFormatterWeb.APIは、応答タイプに適したものを自動的に見つけようとします。ただし、デフォルトのXMLシリアライザー(DataContractSerializer)は型を処理できないDictionary<string, IEnumerable<string>>();ため、応答にJSONシリアライザーを使用します。

実際には、CreateErrorResponseModelStateを使用して、直接から応答を作成する必要があります( 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);
        }
    }
}
于 2013-01-30T20:35:47.917 に答える
1

Web APIは、コントローラーメソッドの外部の応答のデフォルトタイプとしてJSONを返すと思います。

この記事で提案されているように、JSONフォーマッターを無効にしてみましたか?

http://www.asp.net/web-api/overview/formats-and-model-binding/json-and-xml-serialization

すなわち

void ConfigureApi(HttpConfiguration config)
{

    // Remove the JSON formatter
    config.Formatters.Remove(config.Formatters.JsonFormatter);
}
于 2013-01-30T20:33:23.933 に答える