0

モデルの文字列プロパティを、カスタム型との間で暗黙の演算子を持つクラスに変換しましたEngNum。これは、タイプが文字列のように動作して使用される必要がある場合でも、このタイプのすべてのオカレンスにカスタムエディターが含まれるようにするために行いました。

私の問題は、POSTのフォームに値が含まれていても、プロパティがモデルに正しくバインドされなくなったことです。

EngNum私のタイプについては、以下を参照してください。

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 };
    }
}

そして、これがビューに表示されます。

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

そして、これがそのエディターです:

<%@ 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) %>

ComboBoxForTextBoxForいくつかのjqueryと一緒にをレンダリングします。

このコードをビューから取り出してエディターに配置する前は、正常に機能していました。

ポストバックでプロパティを適切にバインドするには、何をする必要がありますか?


コントローラアクションのは、プロパティModelStateに関連付けられた次の例外があります。EngineerNumber

{System.InvalidOperationException:タイプ'System.String'からタイプ'ThreeSixtyScheduling.Models.EngNum'へのパラメーター変換は、タイプコンバーターがこれらのタイプ間で変換できないために失敗しました。System.Web.Mvc.ValueProviderResult.ConvertSimpleType(CultureInfoカルチャ、オブジェクト値、タイプdestinationType)at System.Web.Mvc.ValueProviderResult.UnwrapPossibleArrayType(CultureInfoカルチャ、オブジェクト値、タイプdestinationType)at System.Web.Mvc.ValueProviderResult.ConvertTo (タイプタイプ、CultureInfoカルチャ)at System.Web.Mvc.DefaultModelBinder.ConvertProviderResult(ModelStateDictionary modelState、String modelStateKey、ValueProviderResult valueProviderResult、Type 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);
    }
4

2 に答える 2

1

モデルバインダーは、カスタムの暗黙的な演算子を呼び出しません。同じ名前のパブリックプロパティを持っているか、カスタムモデルバインダーを作成する必要があります。通常、ビューモデルで暗黙的な演算子を使用する必要はありません。

于 2012-08-23T12:57:18.670 に答える
1

を介して型コンバーターをクラスに追加する必要がありますTypeConverterAttribute。このタイプコンバーターは、文字列をタイプに変換するためにASP.NETMVCによって使用されます。

于 2014-11-28T22:08:55.047 に答える