モデルの文字列プロパティを、カスタム型との間で暗黙の演算子を持つクラスに変換しました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) %>
ComboBoxFor
TextBoxFor
いくつかの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);
}