What does MVC3 do with C# Optional Parameters?

2019-05-23 08:07发布

问题:

Setup the following Controller

public class HomeController : Controller
{
    // GET: /Home/Read    
    public string Read(Sample sample = null)
    {
        if (sample != null)
            Console.WriteLine("Not null");
        else
            Console.WriteLine("null");

        return "";
    }

}
public class Sample
{

}

Sample is not null. Is this a bug or a feature?

回答1:

Optional parameters are implemented via call-site rewriting. Since the controller will be invoked using a full parameter list by the MVC engine, the optional parameter is simply not relevant.

For example, given the following function:

public void Foo(int bar = 1, int baz = 2)
{
}

Calling it like so:

Foo();

Causes the compiler to actually interpret it as:

Foo(1, 2);

There is no magic that occurs whereby the call remains as Foo(), and then the method itself subs in the parameters at run-time. The parameters are subbed in at compile-time, and nothing futher needs to be done.

Update: To indicate to MVC that a given route parameter is optional, you can set it to UrlParameter.Optional when defining your route. At that point, the default parameter value of the action method should kick in.



回答2:

Its a feature not a bug. The binder sees that method signature is the only one that makes sense (if you define one with no parameter I'd imagine that would be called instead or you would get the 'ambiguous call' error) and creates an empty instance since there are no query string parameters available. Since its the model binder doing the magic of creating your instance and not the compiler here, it's MVC's doing.