HttpPostedFileBase值在控制器方法中始终为null

时间:2013-08-20 19:09:18

标签: asp.net-mvc image razor upload

我希望能够使用视图上传图片。

到目前为止,这是我基于this blog here所做的事情:

我有一个包含以下项目的模型扩展名:

[FileSize(10240)]
[FileTypes("jpg,jpeg,png")]
public HttpPostedFileBase mCardImage { get; set; }

仅供参考:FileSizeFileTypes属性的形状如下:

public class FileSizeAttribute : ValidationAttribute
{
    private readonly int mMaxSize;

    public FileSizeAttribute(int _maxSize)
    {
        mMaxSize = _maxSize;
    }

    public override bool IsValid(object _value)
    {
        if (_value == null)
        {
            return true;
        }

        return mMaxSize > (_value as HttpPostedFile).ContentLength;
    }

    public override string FormatErrorMessage(string _name)
    {
        return string.Format("The file size shoud not exceed {0}", mMaxSize);
    }
}

public class FileTypesAttribute: ValidationAttribute
{
    private readonly List<string> mTypes;

    public FileTypesAttribute(string _types)
    {
        mTypes = _types.Split(',').ToList();
    }

    public override bool IsValid(object _value)
    {
        if (_value == null)
        {
            return true;
        }

        var fileExt = System.IO.Path.GetExtension((_value as HttpPostedFile).FileName).Substring(1);

        return mTypes.Contains(fileExt, StringComparer.OrdinalIgnoreCase);
    }

    public override string FormatErrorMessage(string _name)
    {
        return String.Format("Invalid file type. Only the following types: {0} are supported.",
                             String.Join(", ", mTypes));
    }
}

我的观点是这样的:

@model MyApp.Utilities.ModelExtensions.CardInfoExtension

<h2>Create new Card</h2>

@using (Html.BeginForm()) 
{
    @Html.ValidationSummary(true)

    <div class="formStyle">
        <div class="float-right baseMargin">
            @Html.Image(Model.mCardImageLink, Model.mCardName, null)<br/>
            @Html.TextBoxFor(_item => _item.mCardImage, new { @type = "file" } )
            @Html.ValidationMessageFor(_item => _item.mCardImage)
        </div>

        @Html.HiddenFor(_item => _item.mCardImageLink)

        <div class="baseFontSize">
            @Html.LabelFor(_item => _item.mCardName)
        </div>
        <div class="baseFontSize">
            @Html.EditorFor(_item => _item.mCardName)
            @Html.ValidationMessageFor(_item => _item.mCardName)
        </div>

        <div class="baseFontSize">
            @Html.LabelFor(_item => _item.mCardNumber)
        </div>
        <div class="baseFontSize">
            @Html.EditorFor(_item => _item.mCardNumber)
            @Html.ValidationMessageFor(_item => _item.mCardNumber)
        </div>

        <div class="baseFontSize">
            @Html.LabelFor(_item => _item.mCardColor)
        </div>
        <div>
            @Html.Image("~\\Images\\Functional\\blueColor.jpeg", "Blue", null) @Html.CheckBoxFor(_item => _item.mBlueColor, Model.mBlueColor)
            @Html.Image("~\\Images\\Functional\\redColor.jpeg", "Blue", null) @Html.CheckBoxFor(_item => _item.mRedColor, Model.mRedColor)
            @Html.Image("~\\Images\\Functional\\greenColor.jpeg", "Blue", null) @Html.CheckBoxFor(_item => _item.mGreenColor, Model.mGreenColor) <br/>
            @Html.Image("~\\Images\\Functional\\blackColor.jpeg", "Blue", null) @Html.CheckBoxFor(_item => _item.mBlackColor, Model.mBlackColor)
            @Html.Image("~\\Images\\Functional\\whiteColor.jpeg", "Blue", null) @Html.CheckBoxFor(_item => _item.mWhiteColor, Model.mWhiteColor)<br/>
        </div>

        <div class="baseFontSize">
            @Html.LabelFor(_item => _item.mCardManaCost)
        </div>
        <div class="baseFontSize">
            @Html.EditorFor(_item => _item.mCardManaCost)
            @Html.ValidationMessageFor(_item => _item.mCardManaCost)
        </div>

        <div class="baseFontSize">
            @Html.LabelFor(_item => _item.mCardManaConverted)
        </div>
        <div class="baseFontSize">
            @Html.EditorFor(_item => _item.mCardManaConverted)
            @Html.ValidationMessageFor(_item => _item.mCardManaConverted)
        </div>

        <div class="baseFontSize">
            @Html.LabelFor(_item => _item.mCardType)
        </div>
        <div class="baseFontSize">
            @Html.DropDownListFor(_item => _item.mCardType, Model.mCardTypeList, String.Empty) 
            @Html.ValidationMessageFor(_item => _item.mCardType)<br/>
            <span class="baseFontSize">Additional Type</span>
            @Html.TextBoxFor(_item => _item.mAdditionalCardType)
        </div>

        <div class="baseFontSize">
            @Html.LabelFor(_item => _item.mCardPower)
        </div>
        <div class="baseFontSize">
            @Html.DropDownListFor(_item => _item.mCardPower, Model.mCardPowerList, "--- Select a value---")
            @Html.ValidationMessageFor(_item => _item.mCardPower)
        </div>
        <div class="baseFontSize">
            @Html.LabelFor(_item => _item.mCardToughness)
        </div>
        <div class="baseFontSize">
            @Html.DropDownListFor(_item => _item.mCardToughness, Model.mCardToughnessList, "--- Select a value---")
            @Html.ValidationMessageFor(_item => _item.mCardToughness)
        </div>
        <div class="baseFontSize">
            @Html.LabelFor(_item => _item.mCardRarity)
        </div>
        <div class="baseFontSize">
            @Html.DropDownListFor(_item => _item.mCardRarity, Model.mCardRarityList, String.Empty)
            @Html.ValidationMessageFor(_item => _item.mCardRarity)
        </div>
        <div class="baseFontSize">
            @Html.LabelFor(_item => _item.mCardTextAbilities)
        </div>
        <div class="baseFontSize">
            @Html.TextAreaFor(_item => _item.mCardTextAbilities, new { @class = "textAreaWide" } )
            @Html.ValidationMessageFor(_item => _item.mCardTextAbilities)
        </div>
        <div class="baseFontSize">
            @Html.LabelFor(_item => _item.mCardTextFlavor)
        </div>
        <div class="baseFontSize">
            @Html.TextAreaFor(_item => _item.mCardTextFlavor, new { @class = "textAreaWide" } )
            @Html.ValidationMessageFor(_item => _item.mCardTextFlavor)
        </div>
        <div class="baseFontSize">
            @Html.LabelFor(_item => _item.mCardArtistName)
        </div>
        <div class="baseFontSize">
            @Html.EditorFor(_item => _item.mCardArtistName)
            @Html.ValidationMessageFor(_item => _item.mCardArtistName)
        </div>

        <div class="baseFontSize">
            @Html.LabelFor(_item => _item.mCardSet)
        </div>
        <div class="baseFontSize">
            @Html.DropDownListFor(_item => _item.mCardSetID, ViewBag.List as SelectList, "--- Select Card Set ---", new { @class = "CardSetInfo"} )
            @Html.ValidationMessageFor(_item => _item.mCardSet)
        </div>

        <div id="buttonField">
            <input type="submit" value="Create" onclick="needToConfirm = false"/>
        </div>
    </div>
}

最后,我的控制器操作会收到文件所在的模型:

[HttpPost]
public ActionResult CreateCard(CardInfoExtension _card)
{
    // Do some code here...
}

我的问题是:为什么mCardImage总是为空?我尝试使用输入手动上传整个内容:

<input type="file" name="_file">

但是,再一次,在我的控制器方法中,值为null。为什么?有人可以帮帮我吗?

2 个答案:

答案 0 :(得分:3)

我在视图中忽略了这一行:

@using (Html.BeginForm("CreateCard", "Card", FormMethod.Post, new { enctype = "multipart/form-data" })) 

默认情况下,如果没有此行,Html视图无法上传。添加此代替经典Html.BeginForm()解决了这个问题!

答案 1 :(得分:0)

您需要设置name的{​​{1}}以匹配您要绑定到的模型属性的名称。