2011-09-13 3 views
4

많은 코드에 사과드립니다. 가능한 한 짧게 유지하려고 노력했습니다.MVC3 LowerCase 라우트 값이 UpperCase와 다르게 동작합니까?

나는 (여기에서 주로 도난당했습니다) HtmlHelper 확장 프로그램을 작성하여 (그룹화 된) RadioButton을 작성했습니다 enum. 대신 "ID"등의 열거를 사용 그래서 나는 또한 내 노선도를 설정 한

나는이 두 가지 열거의 (이 예를 들어) CurrencyType 및 StatusType

나는 URL/GBP/열기를 호출 할 때 내 HtmlHelper가 올바르게 작동하고 라디오 버튼의 값을 GBP 및 열기로 설정합니다.

URL/gbp/open을 호출하면 도우미가 값을 확인하고 작동하는 것처럼 보이지만 RadioButton(). ToHtmlString()이 호출되면 "checked"가 표시되지 않습니다 ???? 기본 라우팅을 사용하면 라디오 버튼이 여전히 올바르게 설정됩니다. ???

반환 된 SelectList를 중단하면 선택한 옵션이 올바르게 설정되어있는 것을 볼 수 있습니다. 그래서 문제가 발생하는 곳을 좀 덜어 보았습니까?


Empty MVC3 website called Area36...Area 51 was taken ;) 


using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using System.Web.Mvc; 
using System.Web.Mvc.Html; 
using System.Linq.Expressions; 
using System.Text; 

namespace Area36.Models 
{ 
    public static class Extensions 
    { 
     public static SelectList ToSelectList<TEnum>(this TEnum enumObj) 
     { 
      var values = from TEnum e in Enum.GetValues(typeof(TEnum)) 
         select new { ID = e, Name = e }; 
      return new SelectList(values, "Id", "Name", enumObj); 
     } 

     public static void AppendFormatLine(this StringBuilder sb, string format, params object[] args) 
     { 
      sb.AppendFormat(format, args); 
      sb.AppendLine(); 
     } 

     public static MvcHtmlString RadioButtonForEnum<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, string fieldSet) 
     { 
      var metaData = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData); 
      var e = (TProperty)Enum.Parse(typeof(TProperty), metaData.Model.ToString()); 
      var selectList = e.ToSelectList(); 
      var sb = new StringBuilder(); 

      if (selectList != null) 
      { 
       sb.AppendFormatLine("<fieldset><legend>{0}</legend>", fieldSet); 
       foreach (SelectListItem item in selectList) 
       { 
        var id = string.Format("{0}_{1}", metaData.PropertyName, item.Value); 
        if (htmlHelper.ViewData.TemplateInfo.HtmlFieldPrefix != string.Empty) 
         id.Insert(0, string.Format("{0}_", htmlHelper.ViewData.TemplateInfo.HtmlFieldPrefix)); 

        var label = htmlHelper.Label(id, HttpUtility.HtmlEncode(item.Text)); 
        var radio = htmlHelper.RadioButton(name: metaData.PropertyName, value: item.Value, isChecked: item.Selected, htmlAttributes: new { id = id }).ToHtmlString(); 

        sb.AppendFormatLine("<div class=\"radio_{0}\">{1}{2}</div>", metaData.PropertyName, radio, label); 
       } 
       sb.AppendLine("</fieldset>"); 
      } 

      return MvcHtmlString.Create(sb.ToString()); 
     } 
    } 
} 

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using System.Web.Mvc; 
using Area36.Models; 

namespace Area36.Controllers 
{ 
    public class HomeController : Controller 
    { 
     // 
     // GET: /Home/ 

     public ActionResult Index(CurrencyType currency, StatusType status) 
     { 
      return View(new ViewModel { Currency = currency, Status = status }); 
     } 

    } 
} 

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 

namespace Area36.Models 
{ 
    public class ViewModel 
    { 
     public CurrencyType Currency { get; set; } 
     public StatusType Status { get; set; } 
    } 
} 

@using Area36.Models 
@model Area36.Models.ViewModel 


@{ 
    ViewBag.Title = "Index"; 
} 

<h2>Index</h2> 
@Html.RadioButtonForEnum(m => m.Currency, "Currency") 
@Html.RadioButtonForEnum(m => m.Status, "Status") 

public static void RegisterRoutes(RouteCollection routes) 
     { 
      routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 

      routes.MapRoute(
       "Default", // Route name 
       "{currency}/{status}", // URL with parameters 
       new { controller = "Home", action = "Index", currency = CurrencyType.EUR, status = StatusType.Closed} // Parameter defaults 
      ); 

     } 

답변

1

나는 이것을 해결하기 위해 다양한 옵션을 시도했다. UpperCase 값을 강제로 전달했습니다. 가장 놀랍게도 다음과 같이 모든 라디오 버튼에 'true'를 전달했을 때도 출력은 같았고 버튼은 대문자 URL 만 검사했습니다.

var radio = htmlHelper.RadioButton(metaData.PropertyName, item.Value, true, new { id = id }).ToHtmlString(); 

일부 코드에서는이 코드와 일부 검색 결과로 this을 발견했습니다. 다음을 확인하는 경우 다음은 MVC3-rtm의 코드입니다. 여기에서 isChecked의 값이 ModelState에 따라 수정되었는지 확인할 수 있으며 디버그 모드에서 modelState.Values ​​[index] .AttemptedValue의 값을 확인하면 분명히 소문자로 표시됩니다 ("gbp/open"의 경우). 그래서 소문자 url은 checked 속성을 렌더링하지 않습니다.

private IHtmlString BuildRadioButton(string name, object value, bool? isChecked, IDictionary<string, object> attributes) { 
     string valueString = ConvertTo(value, typeof(string)) as string; 

     TagBuilder builder = new TagBuilder("input"); 
     builder.MergeAttribute("type", "radio", true); 
     builder.GenerateId(name); 
     builder.MergeAttributes(attributes, replaceExisting: true); 

     builder.MergeAttribute("value", valueString, replaceExisting: true); 
     builder.MergeAttribute("name", name, replaceExisting: true); 

     var modelState = ModelState[name]; 
     string modelValue = null; 
     if (modelState != null) { 
      modelValue = ConvertTo(modelState.Value, typeof(string)) as string; 
      isChecked = isChecked ?? String.Equals(modelValue, valueString, StringComparison.OrdinalIgnoreCase); 
     } 

     if (isChecked.HasValue) { 
      // Overrides attribute values 
      if (isChecked.Value) { 
       builder.MergeAttribute("checked", "checked", true); 
      } 
      else { 
       builder.Attributes.Remove("checked"); 
      } 
     } 

     AddErrorClass(builder, name); 

     return builder.ToHtmlString(TagRenderMode.SelfClosing); 
    } 
+0

감사합니다.이 지식을 바탕으로 결과 문자열에 대한 검사를 추가했으며 항목이 선택되었지만 "checked = checked"를 포함하지 않으면 수동으로 추가합니다. – BlueChippy

관련 문제