0

I'm working on a MVC web application. I need to download a file which I've stored as a byte[] stream in DB and its working fine. What I used to do on a button click I call a JS function and that calls a function in the C# backend and eventually download the file. Following is my JQuery code.

var DownloadDRR = function ()
{
    var InvoiceId = $(".invoiceid").text();
    location.href = location.origin + "/Invoicing/DownloadDRR?InvoiceId=" + InvoiceId;
}

And in the backend I normally get query string like this

Request.Querystring("InvoiceId");

But accidental I've discovered in my application if I write the following it still gets the InvoiceId without using Request.QueryString().

public FileResult DownloadDRR(int InvoiceId)
        {
            InvoicingService Invoices = new InvoicingService(Client);
            byte[] RawExcel = Invoices.GetExcelService(InvoiceId);

            MemoryStream stream = new MemoryStream(RawExcel);

            stream.Seek(0, SeekOrigin.Begin);
            return File(stream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "test.xlsx");
        }

Can anyone explain why please?

2
  • 4
    It is the automatic MVC Model Binding. This explains it with a lot of detail, answering both how and why: codeproject.com/Articles/710776/… .. and it is exactly how you should be doing things. even complex objects like Person person or List<myClass> myList. Proper MVC should not need Request.Querystring() nor FormCollection (except in especially dynamic parameters or logging) Commented Jun 18, 2014 at 13:49
  • 2
    @arserbin3 You should post that as an answer Commented Jun 18, 2014 at 13:53

1 Answer 1

1

MVC specifically automates a lot of that binding (model binding is the term used).

myurl.com/MyController/MyMethod?something=a&anotherthing=1234

//example 1
public ActionResult MyMethod(string something, string anotherthing)

//example2
public ActionResult MyMethod(string something, int anotherthing)

It works for both examples. Even though your querystring technically only contains string values, MVC will try to parse it to the desired type.

The only thing you need to pay attention to is that the querystring parameter names match the method's parameter names. The rest is done automagically :)

//example3
public ActionResult MyMethod(int something, int anotherthing)

In this example, something cannot be converted, as "a" cannot be put into an int. The method call will fail (expect an ASP.Net error page). However, there are ways around this:

  • If the type is nullable, the method will still be called, and null will be the value. int? something will be set as null if conversion fails, and this makes sure the method still gets called.
  • You can make it an optional parameter: MyMethod(int anotherthing, int something = 0). Notice the inversion of the parameters. Optional parameters must always be placed after normal (required) parameters! This will make sure that, when something either cannot be converted (or simply isn't part of the querystring), it will receive the default value you specified (in my example, 0)

Some remarks:

  • You can write custom modelbinders that go way deeper than just converting a value. However, this is not default MVC behavior. It's still good to know you can add it if you need it.
  • Not all parameters are always part of the querystring. If you make a POST request (as opposed to the more lax GET request), you won't see a querystring. The values are still passed, but not as part of the requested URL. This is a topic you can find tons of information on via Google.
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for giving me an insight. Really appreciate.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.