アプリケーション内の任意のモデルが を実装している可能性があります。IHasOpenGraphMetadata
その場合、@Html.Partial("_OpenGraphMetadata")
レイアウト内で を呼び出すと、そのインターフェイスを介してモデルにアクセスすることで、関連するメタデータがレンダリングされます。
すべてがきれいです。それは、部分的なアクションからそれをやりたいと思ったまでです。
次/Home/Index
の呼び出しがあります。@Html.Action("List", "Posts")
これは以下を返します:
public ActionResult List(long? timestamp = null, int count = 8)
{
IEnumerable<Post> posts = postService.GetLatest(timestamp, count);
PostListModel model = mapper.Map<IEnumerable<Post>, PostListModel>(posts);
return PartialView(model);
}
ここで問題が明らかになります: の実際のモデルは/Home/Index
ですがnull
、実際のメタデータは/Posts/List
部分ビューの結果にあります
og:data
( "_OpenGraphMetadata"
)をレンダリングするパーシャルでこれを使用しました。
@{
OpenGraphModel openGraph = GetOpenGraphMetadata();
if (openGraph != null)
{
@OpenGraphMetaProperty("title", openGraph.Title)
@OpenGraphMetaProperty("description", openGraph.Description)
@OpenGraphMetaProperty("url", openGraph.Url)
@OpenGraphMetaProperty("image", openGraph.Image)
}
}
@helper OpenGraphMetaProperty(string property, string value)
{
if (!value.NullOrBlank())
{
<meta property="og:@property" content="@value" />
}
}
@functions
{
private OpenGraphModel GetOpenGraphMetadata()
{
IHasOpenGraphMetadata model = Model as IHasOpenGraphMetadata;
if (model != null)
{
return model.OpenGraph;
}
return Context.Items[Constants.OpenGraphContextItem] as OpenGraphModel;
}
}
これはかなりまともだと思います。実際のモデルからメタデータを抽出してみてください。インターフェースが実装されていない場合は、 にアクセスしてHttpContext
そこでメタデータを探します。問題は、このメタデータを にどのように配置する必要があるかということHttpContext
です。
次のような呼び出しでアクション メソッドを汚染したくありません。
HttpContext.Items[Constants.OpenGraphContextItem] = model.OpenGraph;
しかし、他にどのようなオプションがありますか? グローバル アクション フィルターでこれを行う必要がありますか? 結果フィルター?これらのオプションに代わるものはありますか?
更新
アクション フィルターでこれを行うことはできないようです。私がこれを行うことができるとわかった方法は、ベース コントローラーの PartialView と両方の View オーバーロードをオーバーライドすることでしたが、これは本当に洗練されていないアプローチのようです。より良い方法が必要です。これを達成する方法。