2

ユーザー名(テキストボックス)、電子メール(テキストボックス)、部門(SelectList)を表示する登録フォームがあります。名前と電子メールは事前に入力されています (私は Windows 認証、イントラネット アプリを使用しています)。SelectedValue を DropDown からコントローラーに Int32 として送信したいのですが、SelectList 全体を送信したくありません。このリストは現在は小さいですが、かなりのサイズになるでしょう。

という名前のクラスRegistrationViewModelで、これらのフィールドのパブリック プロパティが含まれています。ただし、SelectListDivisionList に使用すると、次のエラーが表示されますNo parameterless constructor defined for this object.

Type を変更しても問題ありませんが、Division は null または 0 です。SelectedValue を DropDown から Controller Action メソッドに Int32 として渡す方法はありますか?

編集1:

自分が何をしているのかよくわかりませんが、MVC を約 48 時間使用し、PDF、TechEd、および TechDays のビデオを見てきました。

申し訳ありませんが、これが私のコントローラーコードです:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Register(RegistrationViewModel rvm)
{
    IApplicationContext context = ContextRegistry.GetContext();
    IValidationErrors errors = new ValidationErrors();

    IValidator validator = (IValidator)context.GetObject("RegistrationValidator");
    bool valid = validator.Validate(rvm, errors);

    if (valid)
        repo.SaveRegistration();
    else
        ViewData["DivisionList"] = repo.GetDivisions();

    return View(rvm);
}

RegistrationViewModelクラス

public class RegistrationViewModel
{
    public string Name { get; set; }
    public string Email { get; set; }
    //public SelectList DivisionList { get; private set; }
    public int Division { get; set; }    
}

これがビューです

<%@ Page Language="C#" 
MasterPageFile="~/Views/Shared/Site.Master" 
Inherits="System.Web.Mvc.ViewPage<RegistrationViewModel>" %>

<%@ Import Namespace="Project1.Entities"%>
<%@ Import Namespace="Project1.Models"%>

<asp:Content ID="registerTitle" ContentPlaceHolderID="TitleContent" runat="server">
    Register
</asp:Content>

<asp:Content ID="registerContent" ContentPlaceHolderID="MainContent" runat="server">
...
    <% using (Html.BeginForm())
       { %>
        <div>
            <fieldset>
                <legend>Account Information</legend>
                <p>
                    <label for="name">Name:</label>
                    <%= Html.TextBox("Name", User.Identity.Name.GetDisplayName()) %>
                    <%= Html.ValidationMessage("username") %>
                </p>
                <p>
                    <label for="email">Email:</label>
                    <%= Html.TextBox("email", User.Identity.Name.GetEmailFromLogin()) %>
                    <%= Html.ValidationMessage("email") %>
                </p>              
                <p>
                    <label for="division">Division:</label>
                    <%= Html.DropDownList("DivisionList", ViewData["DivisionList"] as SelectList)%>
                    <%= Html.ValidationMessage("confirmPassword") %>
                </p>
                <p>                
                    <input type="submit" value="Register" />
                </p>
            </fieldset>
        </div>
    <% } %>
</asp:Content>

編集2:

Eilon: これも私が変更したものです。

コントローラ:

public ActionResult Register()
{
  ViewData["DivisionList"] = repo.GetDivisions();
  return View();
}

意見:

<%= Html.DropDownList("DivisionValue", ViewData["DivisionList"] as SelectList)%>

私はこの例外を受け取ります: タイプ「IEnumerable」のキー「DivisionValue」を持つ ViewData アイテムはありません。

ビューをこれに更新したとき:

<%= Html.DropDownList("DivisionList", ViewData["DivisionList"] as SelectList)%>

それはうまく機能します!すべての「ディビジョン」アイテムが同じ名前の場合にのみ機能するようです。名前を変更すると、View がクラッシュするか、ViewModel の "Division" プロパティが 0 として送信されます。

何故ですか?

4

2 に答える 2

5

RegistrationViewModel型には、次のような単純型のプロパティが含まれている必要があります。

public string DivisionValue { get; set; }

または、タイプを int、DateTime、または適切なタイプに変更します。

HTML と HTTP では、ドロップダウン リストに返される唯一のものは、フィールドの名前と選択された値です。

すべてを一致させるには、ビューを変更して、ドロップダウン リストの別の入力名をレンダリングする必要もあります。

<%= Html.DropDownList("DivisionValue", ViewData["DivisionList"] as SelectList)%>

"DivisionValue" をリストの値として使用し、 DivisionListを使用可能なすべてのアイテムのリストとして使用していることに注意してください。

于 2009-05-31T00:57:45.640 に答える
0

私はSelectListタイプをより明確にするだけです。SelectListコントローラーアクションで作成し、ビューでキャストすることを忘れることをお勧めします。私のコードは次のように機能します(CRUD編集ページ):

..アクションで:

            ViewData["WorkType.ID"] = new SelectList(this._vacancySvc.GetVacancyWorkTypes(),
            "ID", "Name", ViewData["WorkType.ID"] ?? vacancy.WorkType.ID);

..そしてビューで:

<p><% =Html.Encode("Work Type:") %><br />
            <% =Html.DropDownList("Worktype.ID")%><span class="smallgrey">(required)</span><br />

.. [null 合体演算子][1] (??) を使用することで、最初の選択 (DB から) が保持されているか、ポストバックからの ViewData (フォームが検証に失敗した場合など) が保持されていることがわかります。

さらに、このコードをリファクタリングした場合、あなたのように ViewModel オブジェクトを使用したいと思います。SelectList唯一のことは、(1)ビュー coz でViewModel プロパティを参照する必要がないことHtml.DropDownList()です。MVC はオーバーロードによってこれを自動バインドします.. (2) とにかくアクションで ViewData を参照する必要があります失敗した検証ポストバックから選択された値を取得するには、実際には何がポイントですか??

于 2009-06-01T05:41:56.257 に答える