简体   繁体   中英

Generating a list of RadioButtons with the same name in a for-loop in an ASP.NET MVC3 view

I'm working on an ASP.NET MVC3 project, and I have a problem with RadioButtons name generated by a for loop in a PartialView.
First, here is my code, I'll explain the exact problem just after :

Model FileUploadModel

public class FileUploadModel
{
    public HttpPostedFileBase File { get; set; }

    public bool IsMainFile { get; set; }
}


Model MyModel

public class MyModel
{
    // Some properties

    public List<FileUploadModel> Files { get; set; }
}


How the PartialView _UploadFiles is called

@Html.Partial("_UploadFiles", Model) // Model is a MyModel model


PartialView _UploadFiles - HERE IS THE PROBLEM

@model MyModel

@{
    var nbFiles = (Model.Files != null ? Model.Files.Count : 0);
    const int NB_DEFAULT_UPLOAD_FIELDS = 3;
}

@for (int i = 0; i < NB_DEFAULT_UPLOAD_FIELDS; i++)
{
    @Html.TextBoxFor(m => m.Files[nbFiles].File, new { type = "file", name = "Files", id = "Files" })
    @Html.RadioButtonFor(m => m.Files[nbFiles].IsMainFile, "Main ?", new { id = "rb" + i + "_File_IsMain" })
}

So this is the last snippet the problem. I'd like to create 3 upload fields with an associated RadioButton indicating if the file is the "main file". However, with the above snippet, the displayed view is OK, but when I validate my form, my posted model only have the first picture uploaded (and the corresponding boolean IsMainFile , the others are just ignored). That means the List Files contains only the first TextBox and first RadioButton data

So I tried with @Html.RadioButtonFor(m => m.Files[i].IsMainFile , but the RadioButtons have a different name so user can check all RadioButtons, which is NOT the desired behavior. MVC doesn't authorize me to override the name of the RadioButtons, so I can't give them my own name.

How can I generate these fields is order to only ONE Radiobutton can be checked AND my MyModel.Files property contains all chosen files ?

Thank you

I think your best bet here is to use editor templates .

First, you create a view named FileUploadModel , and place it a folder named EditorTemplates which should exist under your controller's Views folder. Note that the name of the view must match the name of your view model's class.

Its contents would look something like:

@model FileUploadModel

@Html.TextBoxFor(m => m.File, new { type = "file" })
@Html.RadioButtonFor(m => m.IsMainFile, true)

Then, back in your "_UploadFiles" view, your markup for the input field and radio button would change to:

@model MyModel

using (Html.BeginForm(...

    @Html.EditorFor(m => m.Files)

...

Note that this will automatically iterate through and apply that editor template for each FileUploadModel object, and automatically name them as required. This of course assumes that the Files property in your model is populated.

Your action that accepts the post should accept type MyModel as its sole parameter, and everything should bind up automatically at post.

There are ways to avoid editor templates and build and name those fields programmatically , but this is really the preferred way, and much cleaner.

More specific to your issue... (In other words, I forgot that the code above won't group radio buttons.)

For the grouping of radio buttons to work, you should set the attribute name as follows:

@Html.RadioButtonFor(m => m.IsMainFile, true, new { Name = "IsMainFile" })

Case matters here. Note that Name must be capitalized for this to work. I'm not sure why this is the case.

The problem is that once you change that attribute, this field will no longer automatically bind in the post. This is unfortunate but understandably is as designed since, if you look at the request, I believe you will see that only the selected radio button value has been posted.

So, you could change the value of the radio button to something recognizable since just that one instance of IsMainFile will show up in the request, if I'm correct.

Perhaps you can use this specific knowledge to tweak your existing code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM