mvc c# asp net tutorial
「パブリックアクションメソッドがコントローラに見つかりませんでした」という例外が表示されるのはなぜですか? (2)
私は次の記事を使用しています。ASP.NET MVCローカリゼーションへの追加 -マルチカルチャールートをサポートするためにルーティングを使用しています 。
「ルートの登録」セクションを見ると、現在のルートが({RegisterRoutes}メソッドの){culture}セグメントで更新されていることがわかります。
違いは、現在のルートを維持し、それぞれに "{カルチャー}"セグメントを持つ複製を追加したいので、 "foo / bar"のようなルートでは、 "{culture} / foo / bar "
私はまた、新しいルートが最初に来ることを確認しているのを見ることができます。
public static void MapMvcMultiCultureAttributes(this RouteCollection routes, bool inheritedRoutes = true, string defaultCulture = "en-US", string cultureCookieName = "culture")
{
routes.MapMvcAttributeRoutes(inheritedRoutes ? new InheritedRoutesProvider() : null);
var multiCultureRouteHandler = new MultiCultureMvcRouteHandler(defaultCulture, cultureCookieName);
var initialList = routes.ToList();
routes.Clear();
foreach (var routeBase in initialList)
{
var route = routeBase as Route;
if (route != null)
{
if (route.Url.StartsWith("{culture}"))
{
continue;
}
var cultureUrl = "{culture}";
if (!String.IsNullOrWhiteSpace(route.Url))
{
cultureUrl += "/" + route.Url;
}
var cultureRoute = routes.MapRoute(null, cultureUrl, null, new
{
culture = "^\\D{2,3}(-\\D{2,3})?$"
});
cultureRoute.Defaults = route.Defaults;
cultureRoute.DataTokens = route.DataTokens;
foreach (var constraint in route.Constraints)
{
cultureRoute.Constraints.Add(constraint.Key, constraint.Value);
}
cultureRoute.RouteHandler = multiCultureRouteHandler;
route.RouteHandler = multiCultureRouteHandler;
}
routes.Add(routeBase);
}
}
"InheritedRoutesProvider"は次のようになります。
private class InheritedRoutesProvider : DefaultDirectRouteProvider
{
protected override IReadOnlyList<IDirectRouteFactory> GetActionRouteFactories(ActionDescriptor actionDescriptor)
{
return actionDescriptor.GetCustomAttributes(typeof(IDirectRouteFactory), true)
.Cast<IDirectRouteFactory>()
.ToArray();
}
}
私のコントローラは次のようになります:
public class MyBaseController: Controller
{
[HttpGet]
[Route("bar")]
public virtual ActionResult MyAction(){
{
return Content("Hello stranger!");
}
}
[RoutePrefix("foo")]
public class MyController: MyBaseController
{
}
私の "RegisterRoutes"メソッドは次のようになります:
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapMvcMultiCultureAttributes();
routes.LowercaseUrls = true;
}
さて、もし私がしたら:
- / foo / bar - WORKS!
- / en-US / foo / bar - HttpExceptionパブリックアクションメソッド 'MyAction'がコントローラ 'MyController'に見つかりませんでした
私はあなたに私がそれをやる方法の例を与えることができます。 あなたが使用している例はかなり古いです。
以下のようにBeginExecuteCoreメソッドをあなたのコントローラに実装する(継承を使用する):
protected override IAsyncResult BeginExecuteCore(AsyncCallback callback, object state) { string cultureName = RouteData.Values["culture"] as string; if (cultureName == null) cultureName = Request.UserLanguages != null && Request.UserLanguages.Length > 0 ? Request.UserLanguages[0] : // obtain it from HTTP header AcceptLanguages null; // Validate culture name cultureName = CultureHelper.GetImplementedCulture(cultureName); // This is safe if (RouteData.Values["culture"] as string != cultureName) { // Force a valid culture in the URL RouteData.Values["culture"] = cultureName.ToLower(); // lower case too // Redirect user Response.RedirectToRoute(RouteData.Values); } // Modify current thread's cultures Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(cultureName); Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture; return base.BeginExecuteCore(callback, state); }
いくつかのルートを追加する
routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( name: "Custom", url: "{controller}/{action}/{culture}", defaults: new { culture = CultureHelper.GetDefaultCulture(), controller = "Coordinate", action = "Index" }
カルチャーヘルパークラスを実装する
public static class CultureHelper {private static readonly List _cultures =新しいリスト{"listOfClutures"};
public static bool IsRighToLeft()
{
return System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.IsRightToLeft;
}
public static string GetImplementedCulture(string name)
{
if (string.IsNullOrEmpty(name))
return GetDefaultCulture(); // return Default culture
if (!CultureInfo.GetCultures(CultureTypes.SpecificCultures).Any(c => c.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase)))
return GetDefaultCulture(); // return Default culture if it is invalid
if (_cultures.Any(c => c.Equals(name, StringComparison.InvariantCultureIgnoreCase)))
return name; // accept it
var n = GetNeutralCulture(name);
foreach (var c in _cultures)
if (c.StartsWith(n))
return c;
return GetDefaultCulture(); // return Default culture as no match found
}
public static string GetDefaultCulture()
{
return "en-GB"; // return Default culture, en-GB
}
public static string GetCurrentCulture()
{
return Thread.CurrentThread.CurrentCulture.Name;
}
public static string GetCurrentNeutralCulture()
{
return GetNeutralCulture(Thread.CurrentThread.CurrentCulture.Name);
}
public static string GetNeutralCulture(string name)
{
if (!name.Contains("-")) return name;
return name.Split('-')[0]; // Read first part only. E.g. "en", "es"
}
public static List<KeyValuePair<string, string>> GetImplementedLanguageNames()
{
List<KeyValuePair<string, string>> languageNames = new List<KeyValuePair<string, string>>();
foreach (string culture in _cultures)
{
languageNames.Add(new KeyValuePair<string, string>(culture, CultureInfo.GetCultureInfo(culture).EnglishName));
}
languageNames.Sort((firstPair, nextPair) =>
{
return firstPair.Value.CompareTo(nextPair.Value);
});
string currCulture = GetCurrentCulture();
languageNames.Remove(new KeyValuePair<string, string>(currCulture, CultureInfo.GetCultureInfo(currCulture).EnglishName));
languageNames.Insert(0, new KeyValuePair<string, string>(currCulture, CultureInfo.GetCultureInfo(currCulture).EnglishName));
return languageNames;
}
public static string GetDateTimeUsingCurrentCulture(DateTime dateToConvert)
{
CultureInfo ci = new CultureInfo(GetCurrentCulture());
return dateToConvert.ToString(ci.DateTimeFormat.ShortDatePattern + ' ' + ci.DateTimeFormat.ShortTimePattern);
}
}
RegisterRoutesとそれに続くRouteDataに渡されるRouteCollectionがかなり違っていて、あなたが到達できない内部クラスを使用するため、属性ルーティングでこれを達成できるとは思いません。
私はRouteDataがRouteDataのコレクションである値 "MS_DirectRouteMatches"と呼ばれるキーを期待していると判断しました。 Google MS_DirectRouteあなたがさらに掘り下げたいと思ったら。
最終的に、私はこれが拡張ポイントではないと仮定します。
従来のルーティングに従えば、より多くの成功を収めることができます。 私はあなたのコードがこのシナリオではうまくいきましたが、あなたがすでにそれを知っていることを期待しています。 申し訳ありませんが、私はあなたに良い解決策を与えることができませんでした。