7

I'm new in C# and espacially in ASP.NET MVC.

I have my HomeController, which contains this method:

public ActionResult Error(Error error)
{
    return View(error);
}

Now I have another Controller, which have the following line inside:

return RedirectToAction("Error","Home", new { Error = (new Error("ErrorName","ErrorDescription"))} );

As you might notice, I am trying to pass an Error object to the other controller, which then should pass it to the View.

The Error class I have written on my own, nothing spectacular:

public class Error
{
    public String name {  get; private set; }
    public String description {  get; private set; }
    public int number {  get; private set; }

    public Error(String name, String description)
    {
        this.name = name;
        this.description = description;
        number = 0;
    }
}

My problem ist that every time I try to access the error Variable in the HomeController, it is null. I have already googled an found some posts, but I don't understand, why my code isn't working. There are no errors, just this null value object.. I Appreciate any help! :)

Ba5t14n
  • 719
  • 2
  • 5
  • 20
  • Because you have `private set` on all your properties (the `DefaultModelBinder` cannot set the properties. And you also need to include a parameter-less constructor –  Jun 10 '15 at 11:50
  • Are you sure you can pass a [serialized object](http://stackoverflow.com/questions/7597863/passing-object-in-redirecttoaction) – lloyd Jun 10 '15 at 11:53

3 Answers3

6

The DefaultModelBinder cannot initialize an instance or your Error class based on the query string parameters because you have private set on all your properties.

Your model should be

public class Error
{
  public String name {  get; set; }
  public String description {  get; set; }
  public int number {  get; set; }

  public Error() // you must add a parameter-less constructor
  {
  }

  public Error(String name, String description)
  {
    this.name = name;
    this.description = description;
    // number = 0; // no need for this - the default is 0
  }
}

You can also use

return RedirectToAction("Error","Home", new { name = "ErrorName", description = "ErrorDescription"});

and delete both constructors

  • Thanks for you answer! I removed the `private` statements and added a parameterless constructor, but when I try to access the parameter in `HomeController`s `Error(Error error)` method, I still get an exception. I trird `String test = error.name;`... do you have any other ideas? Thanks until here :) – Ba5t14n Jun 10 '15 at 12:04
  • A `NullReferenceException` is thrown in the line, because the `error` variable is `null` – Ba5t14n Jun 10 '15 at 12:06
  • I have just tested this and it works fine. Have your tried `RedirectToAction()` as per my last snippet –  Jun 10 '15 at 12:08
  • Yes it works - thanks! But I now dont really understand, how the compiler knows, that he must create an Error Object - do you know what I mean? I just found out that is has no effect when I write `new Error {name="...",description="..."}` – Ba5t14n Jun 10 '15 at 12:12
  • When you do `RedirectToAction()` you not actually passing the model to the `Error()` method. The `RedirectToAction()` internally generates query string values (your url would be `/Home/Error?name=ErrorName&description=ErrorDescription`). Then in the `Error()` method, the `DefaultModelBinder` first initializes the method parameters (i.e. your `Error` class) - which is why you need a parameter-less constructor, then it sets the properties - which is why you need public setters. –  Jun 10 '15 at 12:17
  • Okay, now there ist not that much "magic" on this than before :) – Ba5t14n Jun 10 '15 at 12:20
0

Try using "error" in lower case when you name the anonymous parameter.

return RedirectToAction("Error","Home", new { error = (new Error("ErrorName","ErrorDescription"))} );

I believe the parameters are passed by name, and now he can't link "Error" to parameter name of your method.

Timon
  • 1,003
  • 1
  • 9
  • 38
  • Te `DefaultModelBinder` is NOT case sensitive - this make no difference at all –  Jun 10 '15 at 11:58
0

You cannot pass complex objects in an url like that. You will have to send its constituent parts:

public ActionResult YourAction()
{

   // Here user object with updated data

   return RedirectToAction("Error","Home", new { 
        name = "ErrorName", 
        description = "ErrorDescription", 
        number = 0
   });
}
Abbas Galiyakotwala
  • 2,949
  • 4
  • 19
  • 34
  • Of course you can pass complex objects (just so long as their properties are value types - which OP's are) –  Jun 10 '15 at 12:04
  • This works fine - thank you! But now I don't understand how the compiler knows that he has to create an Error object - does he "look" in the HomeControllers method? – Ba5t14n Jun 10 '15 at 12:09