0

I am a newbie when it comes to C#, but I need to use it for a project at work. I am building a web page that is using jQuery to call a C# program. The C# program will connect to a SQL server, retrieve data for agencies and return it to the calling webpage as JSON.

I have all that working, I can get both a single agency and a collection of agencies and return it properly. Below is the code:

public class AgencyController : ApiController
{
    // GET: api/Agency
    public List<AgencyData> Get()
    {
        //var queryValues = Request.RequestUri.ParseQueryString();
        //string filter = queryValues.Get("filter").ToString();

        List<AgencyData> json;
        json = SQLAllAgencyData("");
        return json;
    }

    // GET: api/Agency/5
    public List<AgencyData> Get(string id)
    {
        List<AgencyData> json;
        json = SQLAgencyData(id);
        return json;
    }

What I want to do now is to be able to pass additional information to the C# program. Something like this: www.domain.com/api/Agency?state=TX&city=Dallas

I can not figure out how to do that. All the examples I found result in build errors. Here are a couple of links I tried:

http://forums.asp.net/t/1072321.aspx?How+to+get+parameter+in+url+by+C+for+net

Is there a way to get all the querystring name/value pairs into a collection?

You can also see the two commented out line in my code, they also don't work. I figure that Request is never set to anything, or defined/declared, but I haven't been able to find an example of how to do that.

Suggestions?

10
  • 1
    asp.net/web-api/overview/formats-and-model-binding/… Commented Mar 4, 2015 at 16:50
  • What are your build errors? You may just not be "using" Request.RequestUri. Commented Mar 4, 2015 at 16:50
  • Take a look at this question stackoverflow.com/questions/10656841/…. Commented Mar 4, 2015 at 16:51
  • Error is: The type or namespace name 'Request' could not be found (are you missing a using directive or assembly reference?) I get that on the "Request" even when I add using Request.RequestUri at the top of the code. Commented Mar 4, 2015 at 16:53
  • 1
    If you have access to HttpContext why can't you access the collection: Request.QueryString["id"];? If it is a Post then when it hits your controller, name the parameters identical to your query string and Model View Controller for instance, will automatically build and pass the data through to your Controller. Commented Mar 4, 2015 at 17:01

3 Answers 3

2

There is no need to read the query string, the WEB API model binder will bind any query string parameters to parameters of your action method... I have never known a scenario where I needed to manually parse the query string

With Attribute Routing:

Attribute routing allows you to specifiy nullable parameters, you will need to enable attribute routing which you can find hundreds of tutorials on.

[Route("Agency/{state?}/{city?}")
public List<AgencyData> Get(string state = null, string city = null)
{
    List<AgencyData> json;
    json = SQLAllAgencyData("");
    return json;
}

This would make the url look like this... http://xxxxxx.com/api/Agency/Texas/Dallas

I am however almost sure your query string syntax would work too however you will need to try that.

Without Attribute Routing:

If you do not want to add attribute routing to Web API you can also add overloaded action methods to the controller..

// /api/Agency
public List<AgencyData> Get()
{
    var json = SQLAllAgencyData("");
    return json;
}

// /api/Agency?state=texas&city=dallas
public List<AgencyData> Get(string state, string city)
{
    // Params will be equal to your values...
    var json = SQLAllAgencyData("");
    return json;
}

EDIT: Turns out there is no need to overload the action method... simply set the parameter defaults to null... (overload seems cleaner though)

// /Agency/ 
// /Agency?state=Texas&city=Dallas
public List<AgencyData> Get(string state = null, string city = null)
{
   // Check for null.. etc.
}

Edit: To make this work I have used the default routing config...

public static void Register(HttpConfiguration config)
        {
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }
Sign up to request clarification or add additional context in comments.

5 Comments

this is clearly the answer. I just skimmed the question and saw in the tags C# only, so I suggested the httpcontext object, but in this context your answer is obviously the way to go.
Thank you, I will test that. I am coming form a IBM Domino background, and what I am trying to do is similar to what I woudl do there. I would create a server program that I can then pass different arguments/parameters to in order to get different data back. Examples: /api/GetAgency?state=TX /api/GetAgency?maxamount=10000 /api/Agency?returnfields=prodcode,address1,address1,city,state,zip?state=TX
@BenjaminPaul For the non-attribute routing situation, shouldn't you show the route needed for the route?
@mason Not sure I understand? The default Web API routing config will ensure this works exactly the way I have explained? If you mean the URL that should be used for calling the action... that is commented above the action itself?
Ah, I didn't see the example URL, and thought you were going to pull it from segments like you did with the attribute routing example. A more equivalent way might be to define a new route /api/controller/{state}/{city} in the route config, which would allow you to use the same URL's you would use for the attribute routing, resulting in a cleaner URL.
0

if you want state and city as parameter of method than just add that to parameter of your method and parameters name should match with query string parameter names

   Get(String state, String city)

Comments

-2

You can directly accept the query parameters as method parameters and the query string values can be used in your method.

public List<AgencyData> Get(String state, String city)
{
    //var queryValues = Request.RequestUri.ParseQueryString();
    //string filter = queryValues.Get("filter").ToString();

    List<AgencyData> json;
    json = SQLAllAgencyData("");
    return json;
}

11 Comments

Code only answers are almost as useless as code only questions.
Will this work even with no arguments passed to the program? Suppose I only have one argument, how does the code differentiate it from /api/Agency/12345 (where the number is an agency ID)?
No, you will always need to pass the query keys. E.g. www.domain.com/api/Agency?state=&city= You can either leave the values blank or add a value that indicates none like state=null&city=null
OK. No cleaner way to do it?
You can make the values nullable and there will be no need to declare them.
|

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.