user6096770
user6096770

Reputation:

How to fix conflicting 'Index()' ActionResults

In my View (Index.cshtml) I have a checkbox list and a file input form, both cant work together because both use Index() and you cant have multiple Index() in a controller, so then what do I do? create another view? I don't want to create another view because I want both my checkbox and file input on the same view, so what do I do?

CheckBox:

[HttpGet]
public ActionResult Index() //Index being used
{
    var list = new List<Album>
    {
        new Album { Id = 1, Name = "Aquafina", Checked = false },
        new Album { Id = 2, Name = "Mulshi Springs", Checked = false },
        new Album { Id = 3, Name = "Alfa Blue", Checked = false },
        new Album { Id = 4, Name = "Atlas Premium", Checked = false },
        new Album { Id = 5, Name = "Bailley", Checked = false },
        new Album { Id = 6, Name = "Bisleri", Checked = false },
        new Album { Id = 7, Name = "Himalayan", Checked = false },
        new Album { Id = 8, Name = "Cool Valley", Checked = false },
        new Album { Id = 9, Name = "Dew Drops", Checked = false },
        new Album { Id = 10, Name = "Dislaren", Checked = false },
    };
    return View("Index", list);
}

[HttpPost]
public ActionResult Index(List<Album> list) //2nd Index being used, so far so good
{
    var selected = list.Where(x => x.Checked).Select(x => x.Name);
    //ViewBag.Values = String.Join(", ", list);
    ViewBag.Values = selected;

    return this.View("Index", list);
}

File input form:

public ActionResult Index() //Wait, got an exception, cannot use more than one 'Index()'
{
    bindCombo();

    return this.View();
}

[HttpPost]
public ActionResult Index(HttpPostedFileBase file) //Same problem, how do i fix?
{
    ModelVariables mv = new ModelVariables();

    if (file != null && file.ContentLength > 0)
    {
        mv.fileSubmit = Path.GetFileName(file.FileName);
        var fileName = Path.GetFileName(file.FileName);
        var path = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName);
        file.SaveAs(path);
    }

    return RedirectToAction("Index", mv);
}

Upvotes: 0

Views: 96

Answers (4)

Sebastian Busek
Sebastian Busek

Reputation: 1032

In view define form action to file upload, and name of this action is up to you.

Index.cshtml

@Html.BeginForm("UploadFile", "Controller", new { type = "form/multipart" })
{
    <input type="file" name="file" />
    <button type="submit" value="Upload" />
}

@Html.BeginForm("Index", "Controller")
{
    <input type="checkbox" name="Album" value="No. Dolls!" />
    <input type="checkbox" name="Album" value="O.B.I." />
    <button type="submit" value="Upload" />
}

And Controller.cs

[HttpPost]
public ActionResult UploadFile(HttpPostedFileBase file) 
{ 
    // here you are working with uploaded file
    return View("Index"); 
}

[HttpPost]
public ActionResult Index(List<Album> list)
{
    // here you are working with checkbox list items
    return View();
}

Few off topic notes: Use interface class instate concrete implementation List<Album> => IList<Album>; IList enables to add Albums, does it makes sense to add Albums to uploaded collection?

If not, I'm recommending to use IEnumerable<Album>, but with IEnumerable is issue: you can modify elements and some part of your code doesn't expect changes (for example setting null value) and it can lead to Null reference exception. If you are ok with this, use it.

If not, my recommendation is to use IReadOnlyCollection

Upvotes: 2

Thijs
Thijs

Reputation: 3055

Like Ton Plooij suggest, use ActionName and use different methodnames for you controller functions.

[HttpGet, ActionName("Index")]
public ActionResult GetIndex()
{
    ...
}

[HttpPost, ActionName("Index")]
public ActionResult PostIndex()
{
    ...
}

Upvotes: 0

Denys Wessels
Denys Wessels

Reputation: 17049

  1. 1st Index works because it's [HttpGet]
  2. 2nd Index works because it's [HttpPost]

You cannot define another action in that controller called Index for HttpGet or HttpPost because when you call that action how will MVC know which Index to call?

Just give the other two actions unique names:

public ActionResult BindCombobox()
{

}

[HttpPost]
public ActionResult UploadFiles(HttpPostedFileBase file)
{

}

Upvotes: 0

Ton Plooij
Ton Plooij

Reputation: 2641

You can use the ActionName attribute to set up an Index alias for the second Index method which you then rename.

Upvotes: 1

Related Questions