2012-08-23 3 views
0

내 모델의 문자열 특성을 암시 적 연산자와 사용자 정의 유형 EngNum을 가진 클래스로 변환했습니다. 타입이 동작해야하고 문자열처럼 사용 되더라도 모든 타입의이 커스텀 에디터를 가질 수 있도록이 작업을 수행했습니다.MVC2 바인딩이 사용자 정의 유형에 작동하지 않습니다.

제 문제는 POST의 양식에 값이 있어도 속성이 더 이상 내 모델에 올바르게 바인딩되어 있지 않다는 것입니다. 여기

public class EngNum 
{ 
    private string internalString; 

    public EngNum() { } 

    public EngNum(string number) 
    { 
     internalString = number; 
    } 

    public static implicit operator string(EngNumnumber) 
    { 
     return number == null ? null : number.internalString; 
    } 

    public static implicit operator EngNum(string number) 
    { 
     return new EngineerNumber() { internalString = number }; 
    } 
} 

그리고 지금은보기에 표시되는 :

EngNum 유형은 아래를 참조하십시오

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<ThreeSixtyScheduling.Models.EngineerNumber>" %> 
<%@ Import Namespace="ThreeSixtyScheduling.BLL.Utilities" %> 
<%= Html.ComboBoxFor(m => m, 
        new { @class = "EngineerNumber" }, 
        Url.Action("MasternautEngineers", "Data", new { area = (string)null }), 
        Model, 0) %> 

ComboBoxFor가 렌더링 : 여기

<%= Html.EditorFor(m => m.EngineerNumber) %> 

그리고 그것을 위해 편집기의 어떤 jquery와 함께 TextBoxFor.

보기에서이 코드를 가져 와서 편집기에 넣기 전에 제대로 작동했습니다.

게시판에서 내 속성을 올바르게 바인딩하려면 어떻게해야합니까?


EngineerNumber 속성에 관련된 다음과 같은 예외가있다 컨트롤러 액션의 ModelState :

{System.InvalidOperationException : 형식 '선택 System.String'로부터의 파라미터 전환 'ThreeSixtyScheduling를 입력하기를 .Models.EngNum '은 형식 변환기가 이러한 형식간에 변환 할 수 없기 때문에 에 실패했습니다. System.Web에서 System.Web.Mvc.ValueProviderResult.UnwrapPossibleArrayType에서 System.Web.Mvc.ValueProviderResult.ConvertSimpleType (CultureInfo를 문화, 개체 값을 입력하는 DestinationType) (CultureInfo를 문화, 개체 값을 입력하는 DestinationType)에서. Mvc.ValueProviderResult.ConvertTo (종류 형은 CultureInfo 문화) System.Web.Mvc.DefaultModelBinder.ConvertProviderResult에서 (ModelStateDictionary modelState, 문자열 modelStateKey, valueProviderResult valueProviderResult, 입력하는 DestinationType)}


,

컨트롤러 방법 (모델의 종류) :

[HttpPost] 
public ActionResult CreateStockcheckJob(CreateStockcheckJobModel viewModel) 

public class CreateStockcheckJobModel 
{ 
    [Required] 
    [DisplayName("Engineer Number")] 
    public EngNum EngineerNumber { get; set; } 

    [Required] 
    [DisplayName("Date and Time")] 
    public DateTime DateAndTime { get; set; } 

    public bool JobCreated { get; set; } 

    public CreateStockcheckJobModel() 
    { 
     DateAndTime = DateTime.Today.WithTimeOfDay(8, 0, 0); 
    } 
} 

코드 ComboBoxFor에 대한 :

public static MvcHtmlString ComboBoxFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, 
                   Expression<Func<TModel, TProperty>> expression, 
                   object htmlProperties, 
                   string ajaxJSONLocation, 
                   string selectedValue, 
                   int minLength) 
    { 
     return ComboBoxFor(htmlHelper, expression, htmlProperties, ajaxJSONLocation, selectedValue, minLength, false, string.Empty); 
    } 

    public static MvcHtmlString ComboBoxFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, 
                   Expression<Func<TModel, TProperty>> expression, 
                   object htmlProperties, 
                   string ajaxJSONLocation, 
                   string selectedValue, 
                   int minLength, 
                   bool hideId, 
                   string selectCallbackScript) 
    { 
     var textboxHTML = htmlHelper.TextBoxFor(expression, htmlProperties); 

     var scriptString = @"<script type=""text/javascript""> 
$(function() { 
    " + (string.IsNullOrEmpty(selectedValue) ? "$('#" + htmlHelper.IdFor(expression) + @"').val('')" : string.Empty) + @" 
    $.getJSON('" + ajaxJSONLocation + @"', function(result) { 

     $('#" + htmlHelper.IdFor(expression) + @"').autocomplete({ 
                    minLength: " + minLength.ToString() + @", 
                    source: function(request, response) { 
                       dataArray = new Array(); 
                       $.each(result, function(k, v) { 
                        if (v.value.toUpperCase().indexOf(request.term.toUpperCase()) != -1 || 
                         v.desc.toUpperCase().indexOf(request.term.toUpperCase()) != -1) { 
                         dataArray.push(v); 
                        } 
                       }); 
                       response(dataArray); 
                    }, 
                    focus: function(event, ui) {}, 
                    select: function(event, ui) { 
                    $('#" + htmlHelper.IdFor(expression) + @"').val(ui.item.value); 
                    " + selectCallbackScript + @" 
                    return false; } 
                  }) 
                .data(""autocomplete"")._renderItem = function (ul, item) { 
                 return $(""<li></li>"") 
                   .data(""item.autocomplete"", item) 
                   .append(""<a>"" + " + (hideId ? string.Empty : @"item.value + ""<br/>"" + ") + @"""<span>"" + item.desc + ""</span></a>"") 
                   .appendTo(ul); 
                }; 
    }); 
}); 
</script>"; 

     return MvcHtmlString.Create(textboxHTML.ToString() + scriptString); 
    } 
+0

'ComboBoxFor'확장 메소드를 보여 주시겠습니까? 또한 양식을 제출하려는 컨트롤러 조치의 서명. –

답변

1

이 모델 바인더 사용자 정의 암시 적 연산자를 호출하지 않을. 같은 이름의 공용 속성이 있거나 사용자 정의 모델 바인더를 작성해야합니다. 일반적으로 뷰 모델에서 암시적인 연산자를 사용할 필요가 없습니다.

+0

답변에 대한 해결책을 이해하지 못했습니다. 공공 재산 어디서 무엇과 같은 이름으로? 내 'EngNum' 유형에'EngineerNumber' 속성을 추가하려고 시도했지만 작동하지 않았습니다. –

+0

2 가지 가능성 :'CreateStockcheckJobModel' 클래스에서 여러분은 단순히 다음을 사용합니다 :'public string EngineerNumber {get; 세트; }'또는 복잡한 하위 모델을 사용하려는 경우 암시 적 연산자와 매개 변수를 사용하는 생성자를 제거하고 문자열 속성을 포함하는 클래스와 다른 이름으로 문자열 속성을 추가합니다. 이 경우 템플리트의 내부에서 <% = Html.ComboBoxFor (m => m.Number, new {@class = "EngineerNumber"}, Url.Action ("MasternautEngineers", "Data", new {area = (문자열) null}), Model.Number, 0) %>'. –

1

TypeConverterAttribute을 통해 클래스에 유형 변환기를 추가해야합니다. 이 형식 변환기는 ASP.NET MVC에서 문자열을 형식으로 변환하는 데 사용됩니다.

관련 문제