0

I know how to retrieve with one string in webapi. But I dont know how to use hashtable with my webapi. Because in hashtable i have different condition for each form but calling same api.

I am using .net3.5

Example:

System.Collections.Hashtable _condition = new System.Collections.Hashtable();
            if (TPX.StringHelper.NVL(cbxStatus.EditValue, "-Please Select-") != "-Please Select-")
                _condition.Add("Status", cbxStatus.EditValue.ToString());
            if (TPX.StringHelper.NVL(cbxCenter.EditValue, "-Please Select-") != "-Please Select-")            
                _condition.Add("Center", cbxCenter.EditValue.ToString());
            if (chkHideDone.Checked)
                _condition.Add("IsDone", Convert.ToInt32(!chkHideDone.Checked));

        _condition.Add("StartDate", dtpBegin.DateTime.ToString("yyyyMMdd"));
        _condition.Add("EndDate", dtpEnd.DateTime.ToString("yyyyMMdd"));

        string itemJson = Newtonsoft.Json.JsonConvert.SerializeObject(_condition);

        string navURL = GlobalParameters.Host + "api/Order/RetrieveOrderList?conditions="+itemJson;

        using (System.Net.WebClient webClient = new System.Net.WebClient())
        {
            webClient.Headers["Content-Type"] = "application/json";
            webClient.Encoding = Encoding.UTF8;                

            string sJson = webClient.DownloadString(navURL);  List<Models.OrderList> myDeserializedObjList = (List<Models.OrderList>)Newtonsoft.Json.JsonConvert.DeserializeObject(sJson, typeof(List<Models.OrderList>));
            grdOrder.DataSource = myDeserializedObjList;
        }

It is giving error while downloading string (webclient.downloadstring(navURL)). Note: I have copied same logic to create one more and filtered by one field instead of hashtable i have no issues. I really need hashtbale, because I use same logic in different places on my project, only the supplied condition is different.

I really appreciate for any valuable input. Thanks.

Mdyahiya
  • 167
  • 3
  • 15

1 Answers1

1

When you serialize Hashtbale to JSON, resulting string contains quotation marks (and possibly other special characters), that are not valid characters in URL querystring. These characters must be encoded using percent encoding. To do that, you can use Uri.EscapeDataString static method.

string navURL = GlobalParameters.Host + "api/Order/RetrieveOrderList?conditions=" + Uri.EscapeDataString(itemJson);


EDIT:
You might find some examples how to pass Dictionary to WebAPI in

but this works for me:

// Declare binder that will convert parameters to Hashtable
public class HashtableBinder : IModelBinder
{
    public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
    {
        var json = bindingContext?.ValueProvider?.GetValue(bindingContext.ModelName)?.AttemptedValue as string;
        if (json != null)
        {
            //Deserialize using Microsoft's JSON serializer
            var serializer = new JavaScriptSerializer();
            bindingContext.Model = serializer.Deserialize<Hashtable>(json);
            //or deserialize using Newtonsoft JSON convertor
            //bindingContext.Model = JsonConvert.DeserializeObject<Hashtable>(json);
            return true;
        }
        return false;
    }
}


// In your controller, decorate parameter
// with FromUri attribute and specify HashtableBinder
// as BinderType
[HttpGet]
[Route("api/Order/RetrieveOrderList")]
public void RetrieveOrderList([FromUri(BinderType = typeof(HashtableBinder), Name = "conditions")]Hashtable conditions)
{
    // access hashtable in conditions parameter, e.g. var status = conditions["Status"]
}
Ňuf
  • 6,027
  • 2
  • 23
  • 26
  • I tried as you suggest. But still returned same error(Error 500, Internal Server Error). Before applying the changes my api link is like this http://localhost:8989/api/Order/RetrieveOrderList?conditions={"StartDate":"20170923","Status":"100","EndDate":"20170930"} and now http://localhost:8989/api/Order/RetrieveOrderList?conditions=%7B%22StartDate%22%3A%2220170923%22%2C%22Status%22%3A%22100%22%2C%22EndDate%22%3A%2220170930%22%7D – Mdyahiya Sep 30 '17 at 02:13
  • Although cannot be 100% sure without more details, Error 500 usually happens when method processing WebAPI request on the server throws an unhandled exception. So problem is now not with the WebClient, but on the server. You should debug your server code and see, why exception is thrown. – Ňuf Sep 30 '17 at 22:44
  • @Nuf, I am using same logic and my data model works without any exception in other project. When I am calling throw webapi its giving error. So I feel something wrong with my api calling method. I am using HTTPGET. I am not sure HTTP Post will work for retrieving data. I tried that too. If some example for retrieving with hashtable condition in webapi will be great. Thanks – Mdyahiya Oct 03 '17 at 03:50