35

I have an mvc form (made from a model) which when submitted, I want to get a parameter I have the code to set the form and get the parameter

using (@Html.BeginForm("myMethod", "Home", FormMethod.Get, new { id = @item.JobId })){
}

and inside my home controller I have

    [HttpPost]
    public FileStreamResult myMethod(string id)
    {
         sting str = id;

    }

However, I always get the error

The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.

When I omit the [HttpPost], the code executes file but the variables str and id are null. How can I fix this please?

EDIT

Can this be caused because myMethod in the controller is not an ActionResult? I realized that when I have a method of type Actionresult where the method is bound to a view, everything works well. But the type FileStreamresult cannot be bound to a View. How can I pass data to such methods?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
jpo
  • 3,959
  • 20
  • 59
  • 102
  • You are specifying a GET on the form declaration, but expecting it to call your POST method? – Forty-Two Jan 02 '13 at 15:22
  • I tried omitting the HttpPost as well but my variables str and id are always null. and I tried changing the formmethod to post but no difference. – jpo Jan 02 '13 at 15:28
  • Is your view strongly typed? – Forty-Two Jan 02 '13 at 15:30
  • I am not returning a View but a FileStreamResult. So, I do not have the option of adding a view to myMethod in the controller – jpo Jan 02 '13 at 15:34
  • But you can still strongly type the view containing the form and pass the data using mvc's built in conventions and model binding. This will not affect the fact that you are returning a fileStreamResult – Forty-Two Jan 02 '13 at 15:40
  • my bad. I used @Html.displayfor on the paramaters I wanted to pass – jpo Jan 03 '13 at 19:56

4 Answers4

54

When in doubt, follow MVC conventions.

Create a viewModel if you haven't already that contains a property for JobID

public class Model
{
     public string JobId {get; set;}
     public IEnumerable<MyCurrentModel> myCurrentModel { get; set; }
     //...any other properties you may need
}

Strongly type your view

@model Fully.Qualified.Path.To.Model

Add a hidden field for JobId to the form

using (@Html.BeginForm("myMethod", "Home", FormMethod.Post))
{   
    //...    
    @Html.HiddenFor(m => m.JobId)
}

And accept the model as the parameter in your controller action:

[HttpPost]
public FileStreamResult myMethod(Model model)
{
    sting str = model.JobId;
}
Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
Forty-Two
  • 7,535
  • 2
  • 37
  • 54
  • @jpo in Response to your edit: what you are returning from the POST method has absolutely no effect on model binding. As far as your model being an IEnumerable, just add it to the view model (see edit). If you follow the pattern I've outlined here, you should not have any problems. – Forty-Two Jan 02 '13 at 16:36
  • Will try that. Say JobId is an element of myCurrentModel, how do I initialize the string str? I tried sting str = model.single().JobId but i get the error "Sequence contains more than one element" – jpo Jan 02 '13 at 16:48
  • 1
    Use `First()` or `FirstOrDefault()` or specify a condition for `Single()` – Forty-Two Jan 02 '13 at 16:54
14

This is because you have specified the form method as GET

Change code in the view to this:

using (@Html.BeginForm("myMethod", "Home", FormMethod.Post, new { id = @item.JobId })){
}
CoffeeCode
  • 4,296
  • 9
  • 40
  • 55
3

You seem to be specifying the form to use a HTTP 'GET' request using FormMethod.Get. This will not work unless you tell it to do a post as that is what you seem to want the ActionResult to do. This will probably work by changing FormMethod.Get to FormMethod.Post.

As well as this you may also want to think about how Get and Post requests work and how these interact with the Model.

Alex
  • 94
  • 3
3

here the problem is model binding if you specify a class then the model binding can understand it during the post if it an integer or string then you have to specify the [FromBody] to bind it properly.

make the following changes in FormMethod

using (@Html.BeginForm("myMethod", "Home", FormMethod.Post, new { id = @item.JobId })){

}

and inside your home controller for binding the string you should specify [FromBody]

using System.Web.Http;
[HttpPost]
public FileStreamResult myMethod([FromBody]string id)
{
     // Set a local variable with the incoming data
     string str = id;

}

FromBody is available in System.Web.Http. make sure you have the reference to that class and added it in the cs file.

Community
  • 1
  • 1
Anto Subash
  • 3,140
  • 2
  • 22
  • 30