4

次のようなコントローラーがあります。

[HttpPost]
[Authorize(Roles = "Admin")]
public ActionResult ProjectAdd(PortfolioViewModel model, int[] categories, HttpPostedFileBase thumbnail, HttpPostedFileBase image)
{
    model.ProjectImage = System.IO.Path.GetFileName(image.FileName);
    model.ProjectThubmnail = System.IO.Path.GetFileName(thumbnail.FileName);
    using (PortfolioManager pm = new PortfolioManager())
    {
        using (CategoryManager cm = new CategoryManager())
        {
            if (ModelState.IsValid)
            {
                bool status = pm.AddNewProject(model, categories);
            }
            ViewBag.Categories = cm.GetAllCategories();
            ViewBag.ProjectsList = pm.GetAllProjects();
        }
    }
    return View(model);
}

私の見解は;

@using (Html.BeginForm("projectAdd", "home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    @Html.ValidationSummary(true)

    <fieldset>
        <legend>Add New Project</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.ProjectHeading)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.ProjectHeading)
            @Html.ValidationMessageFor(model => model.ProjectHeading)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.ProjecctUrl)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.ProjecctUrl)
            @Html.ValidationMessageFor(model => model.ProjecctUrl)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.ProjectLongDescription)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.ProjectLongDescription)
            @Html.ValidationMessageFor(model => model.ProjectLongDescription)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.PromoFront)
        </div>
        @Html.EditorFor(model => model.PromoFront)
        @Html.ValidationMessageFor(model => model.PromoFront)

        <div class="editor-label">
            <label for="thumbnail">Thumbnail</label>
        </div>
        <div class="editor-field">
            <input type="file" name="thumbnail" id="thumbnail" /> 
        </div>
        <div class="editor-label">
            <label for="image">Image</label>
        </div>
        <div class="editor-field">
            <input type="file" name="image" id="image" /> 
        </div>
        <div class="editor-label">
            <label for="categories">Categories</label>
        </div>
        @foreach (var c in categories)
        {
            <input type="checkbox" name="categories" value="@c.CategoryId">
            @c.CategoryName
        }
        <p>
            <input type="submit" value="Create" class="submit" />
        </p>
    </fieldset>
}

このコードを試すと、ModeState.IsValidプロパティが false になります (デバッグで確認しました)。ただし、を削除するModeState.IsValidと、挿入が正常に行われ、すべてが希望どおりに機能します。
ビューを検証するには、ModeState.IsValid プロパティが必要です。
更新: 私のビューモデルは;

[Key]
public int ProjectId { get; set; }
[Required(ErrorMessage="Please enter project heading")]
public string ProjectHeading { get; set; }
[Required(ErrorMessage = "Please enter project Url")]
public string ProjecctUrl { get; set; }
[Required(ErrorMessage = "Please enter project description")]
public string ProjectLongDescription { get; set; }
public string ProjectShortDescription
{
    get
    {
        var text = ProjectLongDescription;
        if (text.Length > ApplicationConfiguration.ProjectShortDescriptionLength)
        {
            text = text.Remove(ApplicationConfiguration.ProjectShortDescriptionLength);
            text += "...";
        }
        return text;
    }
}
public bool PromoFront { get; set; }
[Required(ErrorMessage = "You must sepcify a thumbnail")]
public string ProjectThubmnail { get; set; }
[Required(ErrorMessage = "You must select an image")]
public string ProjectImage { get; set; }
public int CategoryId { get; set; }
public IEnumerable<Category> Categories { get; set; }

更新 2:エラーが見つかりました。問題は

{System.InvalidOperationException: The parameter conversion from type 'System.String' to type 'PortfolioMVC4.Models.Category' failed because no type converter can convert between these types.
   at System.Web.Mvc.ValueProviderResult.ConvertSimpleType(CultureInfo culture, Object value, Type destinationType)
   at System.Web.Mvc.ValueProviderResult.UnwrapPossibleArrayType(CultureInfo culture, Object value, Type destinationType)
   at System.Web.Mvc.ValueProviderResult.ConvertTo(Type type, CultureInfo culture)
   at System.Web.Mvc.DefaultModelBinder.ConvertProviderResult(ModelStateDictionary modelState, String modelStateKey, ValueProviderResult valueProviderResult, Type destinationType)}
4

2 に答える 2

12

デバッグ中はModelState、エラーがないかチェックしてください。これは、モデルを有効にするために必要なすべてのプロパティを含むキー/値ディクショナリです。-propertyを確認すると、 -list で空でないValues値を見つけ、エラーの内容を確認できます。Errors

ModelState エラーの例

または、アクション メソッドに次のコード行を追加して、モデルのすべてのエラーを取得します。

var errors = ModelState.Where(v => v.Value.Errors.Any());
于 2012-09-30T16:19:48.160 に答える
4

モデルには、完全に異なるタイプのプロパティが既にあり、モデル バインダーを混乱させるcategoriesため、アクション パラメータの名前を別の名前に変更する必要があります。PortfolioViewModelCategories

[HttpPost]
[Authorize(Roles = "Admin")]
public ActionResult ProjectAdd(
    PortfolioViewModel model, 
    int[] categoryIds, 
    HttpPostedFileBase thumbnail, 
    HttpPostedFileBase image
)
{
    ...
}

明らかに、チェックボックス名と一致するようにビューを更新する必要もあります。

これで問題が解決する可能性がありますが、ビュー モデルを使用し、ドメイン モデルをビューに渡すのをやめることを強くお勧めします。

于 2012-09-30T16:31:34.833 に答える