0

私が取り組んでいるMVCアプリのドロップダウンリストをRazorで作成しました。

@Html.DropDownList("BillId", "")

ただし、ユーザーは私のプログラムのロジックに従って何も選択する必要はありません(リストには私のコントローラーの「Bill」オブジェクトが表示されます)。彼らが何も選択しない場合、私はエラーを受け取ります

The ViewData item that has the key 'BillId' is of type 'System.Int32' but must be of type 'IEnumerable<SelectListItem>'.

何も選択されていない場合にBillId0を返すステートメントをRazorで作成するにはどうすればよいですか?

私はストレートJavaとVBのバックグラウンドを持っているので、構文はわかりませんが、

 If DropdownBox.SelectedIndex = 0
 Else 
 BillId = DropdownBox.SelectedIndex
 End

次のようにコントローラー:

Function Create(id As Integer) As ViewResult
        ViewBag.id = id
        Dim job As Job = New Job
        job.CustomerId = id
        job.JobAmount = 0
        job.JobDate = Date.Now()
        job.JobStatus = "Active"

        Dim BillList = New List(Of Bill)()

        Dim BillQuery = From s In db.Bills
                        Select s

        BillList.AddRange(BillQuery)

        ViewBag.BillIdList = New SelectList(BillList, "BillId", "BillDate")

        ViewBag.BillId = New SelectList(BillList, "BillId", "BillDate")

        Return View(job)
    End Function

createのPOST関数は次のとおりです。

    <HttpPost()>
    Function Create(job As Job) As ActionResult
        If ModelState.IsValid Then
            db.Jobs.Add(job)
            db.SaveChanges()

            Dim customer As Customer = db.Customers.Find(job.CustomerId)
            Dim customerNumber As String = customer.CustCellphone.ToString()
            Dim messageSender As SendMessage = New SendMessage
            Dim smsMessage As String = "LAUNDRY: Job Number " & job.JobId & " has been booked in. You will be notified when individual services within it are ready for collection."
            messageSender.SendMessage(smsMessage, customerNumber)

            Dim url As String = "/RequestedService/AddService/" + job.JobId.ToString()
            Return Redirect(url)
        End If
        Return View(job)
    End Function

編集

POSTのように、これがどのように返されるのか疑問に思っていました。「null」をチェックできる可能性がありますか?ただし、送信ボタンを押した瞬間に問題があるのではないかと思います

4

1 に答える 1

1

POSTコントローラーのアクションで、ビューを返す前にViewCrap(おっと、私はViewBagを意味します)にデータを入力するのを忘れました。

<HttpPost()>
Function Create(job As Job) As ActionResult
    If ModelState.IsValid Then
        ...
    End If

    ' Here you must populate the ViewCrap before returning the view the same 
    ' way you did in your GET action because your view depend on it
    Dim BillQuery = From s In db.Bills
                    Select s
    ViewBag.BillId = New SelectList(BillQuery.ToList(), "BillId", "BillDate")

    Return View(job)
End Function

ただし、ビューモデルを使用して、......(発音したくない単語)の存在を忘れることを強くお勧めします。


アップデート:

次に、これを実装する正しい方法を見てみましょう(ビューモデルを使用する方法です)。ビューモデルは、ビューごとに定義する必要があるクラスであり、その特定の要件を表します。したがって、コメントセクションでの発言から私の回答まで、ユーザーがドロップダウンから請求書を選択する必要があり、必要なドロップダウンリストをビューに表示する必要があります。

それでは、ビューモデルをロールしてみましょう。

public class JobViewModel
{
    [Required(ErrorMessage = "Please select a bill")]
    [Display(Name = "Bill")]
    public int? SelectedBillId { get; set; }
    public IEnumerable<SelectListItem> Bills 
    { 
        get 
        {
            return db.Bills.ToList().Select(x => new SelectListItem
            {
                Value = x.BillId.ToString(),
                Text = x.BillDate.ToString()
            });
        } 
    }

    public int CustomerId { get; set; }

    ... here you could put any other properties that you want 
        to display on the view, things like JobId, ...
}

次に、2つのアクションでコントローラーを定義します。

public ActionResult Create(int id)
{
    var model = new JobViewModel
    {
        CustomerId = id
    };
    return View(model);
}

[HttpPost]
public ActionResult Create(JobViewModel model)
{
    if (ModelState.IsValid)
    {
        // Using AutoMapper here to map between the domain model
        // and the view model (http://automapper.org/)
        var job = Mapper.Map<JobViewModel, Job>(model);

        // Now call your service layer to do the necessary processings
        // on this job domain model including saving the job and sending 
        // messages and stuff. This avoids polluting your controller with
        // business logic code which belongs to your service layer
        ServiceLayer.ProcessJob(job);

        return RedirectToAction("AddService", "RequestedService", new { id = job.JobId });
    } 

    return View(model);
}

そして最後に、ビューモデルに強く型付けされる対応するビューがあります。

@model JobViewModel

@using (Html.BeginForm())
{
    <div>
        @Html.LabelFor(x => x.SelectedBillId)
        @Html.DropDownListFor(x => x.SelectedBillId, Model.Bills, "-- select --")
        @Html.ValidationMessageFor(x => x.SelectedBillId)
    </div>

    ... some other input fields

    <p><button type="submit">OK</button></p>
}

そして今、コメントセクションで約束されているように、これを解決するために絶対ポルノアプローチと呼んだものを示しましょう。アプリケーションに実装した場合は、もう戻ってASP.NETMVC関連の質問をしないように依頼する必要があります。 StackOverflowで:-)

ポルノのアプローチは、id =0およびtext=空の文字列のアイテムをリストの先頭に手動で挿入し、次にコントローラー内で、モデルが有効かどうかを確認するために、選択したIDが0に等しいかどうかを確認することで構成されました。

したがって、GETアクションでは:

Function Create(id As Integer) As ViewResult
    ViewBag.id = id
    Dim job As Job = New Job
    job.CustomerId = id
    job.JobAmount = 0
    job.JobDate = Date.Now()
    job.JobStatus = "Active"

    Dim Bills = db.Bills.ToList().Select(Function(s) New SelectListItem With { .Value = s.BillId.ToString(), .Text = s.BillDate.ToString() })
    Bills.Insert(0, New SelectListItem With { .Value = "0", .Text = "" })
    ViewBag.BillId = Bills

    Return View(job)
End Function

<HttpPost()>
Function Create(job As Job, BillId as Integer) As ActionResult
    If BillId > 0 Then
        db.Jobs.Add(job)
        db.SaveChanges()

        Dim customer As Customer = db.Customers.Find(job.CustomerId)
        Dim customerNumber As String = customer.CustCellphone.ToString()
        Dim messageSender As SendMessage = New SendMessage
        Dim smsMessage As String = "LAUNDRY: Job Number " & job.JobId & " has been booked in. You will be notified when individual services within it are ready for collection."
        messageSender.SendMessage(smsMessage, customerNumber)

        Dim url As String = "/RequestedService/AddService/" + job.JobId.ToString()
        Return Redirect(url)
    End If
    ModelState.AddModelError("BillId", "Please select a bill")
    Return View(job)
End Function

ビュー内:

@Html.DropDownList("BillId")
于 2012-08-21T20:00:18.353 に答える