簡體   English   中英

為什么模型在 ASP.NET MVC 中回發后為空

[英]Why model is null after postback in ASP.NET MVC

我正在使用最新的 .NET Framework 和 VS 2019 開發 ASP.NET MVC 應用程序。

在我的頁面中,我有一個簡單的文本框和一個搜索按鈕。 當我單擊搜索按鈕並回發表單時,在控制器中,我得到model.Code為 NULL

這是我的代碼 - 我的視圖模型:

public class UserManagementViewModel
{
    public string Code { get; set; }
    // some other properties including simple and complex types
}

在視圖中:

<td style="min-width: 300px">
    @Html.TextBoxFor(m => m.Code)
</td>

在控制器中:

[HttpPost]
public ActionResult UpdateUserPermissions(UserManagementViewModel model)
{
    // model.Code is null here!!
    return RedirectToAction("UserManagement");
}

經過數小時的研究,我嘗試了以下操作:

我查看了 html 源代碼,發現

<input id="Code" name="Code">

使用 Chrome 開發工具,我將輸入的名稱更改為"Model.Code"

<input id="Code" name="Model.Code">

這一次,我在回發后在文本框中獲得了輸入的值。

我不知道為什么會發生這種情況以及為什么沒有正確生成元素名稱!

我能做什么?

編輯:

我還有一些其他控件,如復選框和單選按鈕,我使用純 HTMl 代碼並以“模型”開頭命名它們。 像下面這樣而不是使用@HTML helper。

它工作正常,我得到了 Action 的價值。

解決方法:

我在這里找到了一個解決方法: ASP.NET MVC 4 覆蓋發出的 html 名稱和 ID,因此我將代碼更改為:

@Html.TextBoxFor(m => m.Code, new { @Name = "Model.Code" })

但是這段代碼幫助我解決了我的問題,我仍然不知道為什么 Razor 引擎生成的名稱不起作用。

輔助方法@Html.TextBoxFor工作完全正確。 基本上,您幾乎在所有情況下都需要使用此方法(除了某些需要使用非標准行為的情況)。

關於您的情況,我認為您在使用HtmlFieldPrefix 時遇到了問題

此屬性用於生成 HTML 輸入名稱。 我們可以在 GitHub 中查看 MVC 源代碼...

MVC 使用以下代碼片段生成 HTML 輸入(GitHub 鏈接):

private static MvcHtmlString InputHelper(HtmlHelper htmlHelper, InputType inputType, ModelMetadata metadata, string name, object value, bool useViewData, bool isChecked, bool setId, bool isExplicitValue, string format, IDictionary<string, object> htmlAttributes)
{
    string fullName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);
    if (String.IsNullOrEmpty(fullName))
    {
        throw new ArgumentException(MvcResources.Common_NullOrEmpty, "name");
    }

    TagBuilder tagBuilder = new TagBuilder("input");
    tagBuilder.MergeAttributes(htmlAttributes);
    tagBuilder.MergeAttribute("type", HtmlHelper.GetInputTypeString(inputType));
    tagBuilder.MergeAttribute("name", fullName, true);

    string valueParameter = htmlHelper.FormatValue(value, format);
    bool usedModelState = false;

    ...

    return tagBuilder.ToMvcHtmlString(TagRenderMode.SelfClosing);
}

正如我們所見, name屬性由方法GetFullHtmlFieldName計算。

這個方法我們也可以在 GitHub 上查看( 鏈接):

public string GetFullHtmlFieldName(string partialFieldName)
{
    if (partialFieldName != null && partialFieldName.StartsWith("[", StringComparison.Ordinal))
    {
        // See Codeplex #544 - the partialFieldName might represent an indexer access, in which case combining
        // with a 'dot' would be invalid.
        return HtmlFieldPrefix + partialFieldName;
    }
    else
    {
        // This uses "combine and trim" because either or both of these values might be empty
        return (HtmlFieldPrefix + "." + (partialFieldName ?? String.Empty)).Trim('.');
    }
}

此方法使用HtmlFieldPrefix屬性計算名稱。 因此,如果更改此屬性,則可以修改生成的名稱。

我認為您使用部分Views並且需要帶有一些前綴的渲染屬性才能正確綁定。

請查看帶有示例和可能解決方案的下一個鏈接:

另一方面,要返回模型,您必須使用表單標簽。 MVC 有時將名稱視為模型屬性,但最好明確地這樣做。 這段代碼已經過測試,文本框的兩種變體都可以正常工作。

@model UserManagementViewModel 

<form  asp-action="UpdateUserPermissions" method="post">

     @Html.TextBoxFor(m => m.Code)

    // or

    <div class="form-group">
        <label asp-for="Code" class="control-label"></label>
        <input asp-for="Code" class="form-control" />
    </div>
    
    <div>
        <button  type="submit"> submit </button>
    </div>

</form>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM