0

こんにちは、次のようなコントローラーがあります。

public class MyController : Controller
    {
        public MyController(Uow uow)
        {
            ;
        }

        public ActionResult Index()
        {
            return View();
        }

        [HttpPost]
        public ActionResult Index(HttpPostedFileBase file)
        {
            var validationResults = _uow.GetResults(file.FileName, file.InputStream);

            return View(new MyViewModel { Errors = validationResults.Errors, Data = validationResults.Data });
        }

        [HttpPost]
        public void Save(MyViewModel viewModel)
        {
            //Save the data
        }
    }

これには次のようなビューがあります。

@model MyViewModel 

<form action="" method="post" enctype="multipart/form-data">

    <label for="file" id="filelabel">Filename:</label>
    <input type="file" name="file" id="file" />

    <input type="submit" id="submitbtn" disabled="disabled" />
    <img class="loader" id="loader" style="display: none;" alt="Loading..." src="@Url.Content("~/Content/Images/ajax-loader.gif")" />

    @if (Model != null && Model.Errors.Any())
    {
        foreach (var error in Model.Errors)
        {
            <span class="error">@error</span>
        }    
    }

    <button id="savebtn" >Save</button>

</form>


<script type="text/javascript">

    $(document).ready(function () {

        $('#file').change(function () {
            alert("in here");
            $('#submitbtn').prop('disabled', false);

        });

        $('#submitbtn').click(function () {

            $('#loader').show();

        });

    });
</script>

ここで私がしようとしているのは、コントローラーにファイルをアップロードする手段です。私はこれを達成し、Index Post で受け取りました。次に、これを処理しますが、これは正常に機能します。次に、関連するデータを viewModel に入れ、フォームを再表示します。

私が望んでいるのは、[保存] ボタンが押されたときに、設定されたビューモデルで Save Post メソッドが呼び出されることです。ただし、ボタンを押すたびに、意味のある Index Post に投稿されます。

ファイルのアップロードと処理コードを保持し、後で [保存] ボタンを押すと、viewModel が [Post の保存] メソッドに送信されるようにする方法を教えてください。

4

1 に答える 1

0

これらのアクションを分離して現在のフォームを変更しないようにする必要がある場合は、非同期で投稿できるようにするか、他のアクションに投稿できないようにするために別のフォームが必要になります...つまり、JavaScriptを使用して別のフォームの非表示フィールドを更新するなどの厄介なことを行うことを意味します最初のフォームに変更が加えられるたびに...特定のjavascriptイベントを発生させずにフォームフィールドを変更できる多くの方法があるため、これは絶対確実ではありません。

保存ボタンがクリックされたときにjavascriptを使用してフォームアクションを変更する可能性もあります。しかし、正直なところ、それはすべて私にはあまりにも汚いようで、私はビューモデルを1アクションアプローチに使用します。

HttpPostedFileBaseビューモデルにを設定し、インデックスアクションでデータの検証と保存を処理することをお勧めします。

強く型付けされたフォームヘルパーとアノテーションについては、次の例を参照してください:asp.netmvc3でjqueryとdataannotationを使用して入力ファイルを検証する方法

が付いたHttpPostedFileBaseプロパティが表示DataAnnotationsされます。この方法で検証する必要がある場合は、UOWを呼び出すカスタムアノテーションを作成してみてください。理由はわかりません。

また、これにもModel.ValidationMessageFor()ヘルパーを使用することをお勧めします。

ビューモデルを受け取るアクションの一般的なパターンは次のとおりです。

[HttpPost]
public ActionResult Index(MyViewModel myViewModel)
{
    try
    {
        // Check your viewmodel is valid
        if (!ModelState.IsValid)
        {
            // not valid so return to the view with the view model as a param
            // The validation message helpers will display the relevant error messages
            return View(myViewModel);
        }

        // modelstate is valid so perform any work i.e. save to database
        // attach any additional information to the view modal to give feedback maybe?
        // or redirect the user to some other page
        return View(myViewModel);
    }
    catch
    {
        // any exceptions then go back to the view and hopefully the validation helpers will kick in
        return View(myViewModel);
    }
}

個人的には簡単なことのために私はこの種のことをします、しかしあなたは考えを得ることができます:

ビューモデルで

[DisplayName("Update your image")]
[Required]
public HttpPostedFileBase Image { get; set; }
public string ImageName { get; set; }

ビューで

@if (Model.ImageName != null) { 
    <img src="@Url.Content("~/uploads/" + Model.ImageName)" alt="" />
}

<div class="control-group">
    @Html.LabelFor(model => model.Image)
    <div class="controls">
        @Html.TextBoxFor(model => model.Image, new { @type = "file", @class = "input-file" })
        @Html.ValidationMessageFor(model => model.Image)
    </div>
</div>

コントローラのポストアクションで、チェックした後ModelState.IsValid

var fileName = "";
// check for a posted file and that it has a size to it before attempting to save the file
if (myViewModel.Image != null && myViewModel.Image.ContentLength > 0)
{
    var currentDate = DateTime.UtcNow.ToString("yyyymmddhhmmss");
    var fileType = Path.GetExtension(myViewModel.Image.FileName);
    Random random = new Random();
    fileName = Path.GetFileNameWithoutExtension(myViewModel.Image.FileName) + "-" + currentDate + random.Next(1, 10000) + fileType;

    // upload the file
    var path = Path.Combine(Server.MapPath("~/uploads"), fileName);
    myViewModel.Image.SaveAs(path);
}

// for saving to the database on an model entity
if (fileName != "")
{
    entity.ImageName = fileName;
}
于 2013-01-24T00:28:55.983 に答える