Url encoded slash in URL - Stack Overflow
この投稿から始まって、以下のエントリにたどり着く。
Allowing special characters (forward slash, hash, asterisk etc) in ASP.Net MVC URL parameters
まさに、同じ問題に直面した内容。
Double/incomplete Parameter Url Encoding - Stack Overflow
↑ここへのリンクもあったから覗いてみたら、Uri.EscapeDataString メソッド (System)を使ったエンコーディングがあるということを初めて知る。なにこれ~、と思って試したけど、Server.UrlEncodeと同じだった。ガッカリ。いや、違う方が驚きか。
結局、Philさんの投稿のように"/"か他の文字に置換して区切ってしまうか、Base64エンコードで渡すのがいいのかな。Base64といえばFuturesに入ってるLinqBinaryModelBinderが使えるんだもんね。
というわけで試してみた。
登録するルートは以下の通り。
routes.MapRoute(null,
"Proxy/{*base64url}",
new { controller = "Images", action = "Proxy" }
); Controllerはシンプルに以下。LinqBinaryModelBinderを使うので、参照設定にFuturesのアセンブリを含めるのを忘れずに(単純に文字列で渡しておいて、Binary型にしなくてもConvert.FromBase64Stringでも可)。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;
using System.Net;
using System.Text;
using System.Data.Linq;
namespace Mvc.RC.Controllers
{
public class ImagesController : Controller
{
public ActionResult Proxy(Binary base64url)
{
var web = new WebClient();
var url = Encoding.UTF8.GetString(base64url.ToArray());
var bytes = web.DownloadData(url);
return File(bytes, web.ResponseHeaders["Content-Type"]);
}
}
}Viewでリンクを作る時にBase64エンコードしたパラメータを渡す。
<% = Html.ActionLink("いぬ", "Proxy", "Images", new {
base64url = Convert.ToBase64String(Encoding.UTF8.GetBytes(
@"http://farm1.static.flickr.com/131/353753310_1ed04f694c_m.jpg"
))
}, null)%>これが出力されると以下のHTML。
<a href="/Proxy/aHR0cDovL2Zhcm0xLnN0YXRpYy5mbGlja3IuY29tLzEzMS8zNTM3NTMzMTBfMWVkMDRmNjk0Y19tLmpwZw==">いぬ</a>
リンクをクリックする。
ちゃんと犬が表示されました。一応、ブレークポイントセットして変数の中身を確認。ちょと見にくいけど、引数のbase64UrlにはBase64エンコードされたBinary型の値が入ってて、変数urlには元のURLがデコードされてる。
問題はぱっと見どこのURLを参照してるのかを判断出来ないところ。フレンドリURLとは言い難し。
ところで、Windows Live Writerから投稿すると、毎回無駄な改行が入るのはなんでなんだろう。