POSTリクエストで送信されたXMLデータが特定のカスタムXMLスキーマを満たしているかどうかを検証するためのソリューションを見つけようとしています。
ASP.NET Web APIで提供されているものを使用する場合XmlMediaTypeFormatter
、私が見る限り、利用可能なスキーマ検証がありません。例:モデルタイプがある場合...
public class Order
{
public string Code { get; set; }
public int Quantity { get; set; }
}
ApiController
...および...のPOSTアクション
public HttpResponseMessage Post(Order order)
{
if (ModelState.IsValid)
{
// process order...
// send 200 OK response for example
}
else
// send 400 BadRequest response with ModelState errors in response body
}
...次の「間違った」XMLデータを投稿できますが、それでも200OKの応答が返されます。
User-Agent: Fiddler
Host: localhost:45678
Content-Type: application/xml; charset=utf-8
<Order> <Code>12345</Nonsense> </Order> // malformed XML
または:
<Order> <CustomerName>12345</CustomerName> </Order> // invalid property
または:
<Customer> <Code>12345</Code> </Customer> // invalid root
または:
"Hello World" // no XML at all
などなど。
リクエストの検証を行う唯一のポイントはモデルバインディングです。リクエストの例1、3、4では、メソッドにorder
渡されるのは、例2では、プロパティをテストするか、プロパティにマークを付けることで無効にできるプロパティです。属性。この検証結果を、400の「BadRequest」Httpステータスコードと応答本文の検証メッセージとともに応答に送り返すことができます。しかし、何が間違っているのか正確にはわかりません。たとえば、例1、3、4の間違ったXMLを区別することはできません(投稿されていません。私が見ることができるのはそれだけです)。Post
null
order.Code
null
order == null
Code
[Required]
order
Order
たとえば、を特定のカスタムXMLスキーマで投稿する必要があるxmlns="http://test.org/OrderSchema.xsd"
場合、投稿されたXMLがこのスキーマに関して有効かどうかを検証し、有効でない場合は、スキーマ検証エラーを応答で送り返します。これを達成するために、私はカスタムから始めましたMediaTypeFormatter
:
public class MyXmlMediaTypeFormatter : MediaTypeFormatter
{
// constructor, CanReadType, CanWriteType, ...
public override Task<object> ReadFromStreamAsync(Type type, Stream stream,
HttpContentHeaders contentHeaders, IFormatterLogger formatterLogger)
{
var task = Task.Factory.StartNew(() =>
{
using (var streamReader = new StreamReader(stream))
{
XDocument document = XDocument.Load(streamReader);
// TODO: exceptions must the catched here,
// for example due to malformed XML
XmlSchemaSet schemaSet = new XmlSchemaSet();
schemaSet.Add(null, "OrderSchema.xsd");
var msgs = new List<string>();
document.Validate(schemaSet, (s, e) => msgs.Add(e.Message));
// msgs contains now the list of XML schema validation errors
// I want to send back in the response
if (msgs.Count == 0)
{
var order = ... // deserialize XML to order
return (object)order;
}
else
// WHAT NOW ?
}
});
return task;
}
}
これは、すべてが正しい限り機能します。
しかし、私はどうしたらいいのかわかりませんmsgs.Count > 0
。この検証結果リストをPost
アクションに「転送」するにはどうすればよいですか、またはそれらのXMLスキーマ検証メッセージを含むHttp応答を作成するにはどうすればよいですか?
また、カスタムMediaTypeFormatter
がそのようなXMLスキーマ検証の最良の拡張ポイントであるかどうか、そして私のアプローチが間違った方法ではないかどうかもわかりません。おそらくカスタムHttpMessageHandler
/DelegatingHandler
これのためのより良い場所でしょうか?それとも、箱から出してもっと簡単なものがあるのでしょうか?