I want to use an out parameter with string variable - c#

I want to use an out parameter with string variable.
For Example:
string Url = "https://learn.microsoft.com/tr-tr/dotnet/csharp/language-reference/keywords/out-parameter-modifier"
string BaseUrl = this.DecompositionUrl(out Url).BaseUrl;
string ServiceUrl = this.DecompositioUrl(out Url).ServiceUrl;
I want to using a method like this.
public static string DecompositionUrl(out string Urlr)
{
// enter here :
BaseUrl = Urlr.Substring(0,40);
ServiceUrl = Urlr.Substring(40,Urlr.Length);
}
When returned my DecompositionUrl I want to set BaseUrl and ServiceUrl

You need to declare out parameters for the two values that you intend to return from your method: baseUrl and serviceUrl. The source url needs to be passed in through an ordinary parameter (not out).
public static void DecompositionUrl(string url, out string baseUrl, out string serviceUrl)
{
baseUrl = url.Substring(0, 40);
serviceUrl = url.Substring(40);
}
You would then call your method like so:
string url = "https://learn.microsoft.com/tr-tr/dotnet/csharp/language-reference/keywords/out-parameter-modifier"
DecompositionUrl(url, out var baseUrl, our var serviceUrl);
Console.WriteLine($"Base URL is {baseUrl} and service URL is {serviceUrl}.");

C# 7 allows you to return a 'tuple' as the result of a method like this
public static (string, string) DecompositionUrl(string url)
{
var baseUrl = ...;
var serviceUrl = ...;
return (baseUrl, serviceUrl);
}
You can then use it like this
(string baseUrl, string serviceUrl) = DecompositionUrl("https://learn.microsoft.com/tr-tr/dotnet/csharp/language-reference/keywords/out-parameter-modifier");
I think that's better than using the out keyword since it's clearer what's input and what's output.

Related

Async Method not Returning a String

I am trying to get some weather data from Open Weather Maps and l use HTTPClient and API ASP.NET in C#.
My code keeps returning:
System.Threading.Tasks.Task`1[System.String]
I've made my methods async and await but I still get the above returned. I thought making it await would return the value.
I am just trying to get the string from Open Weather Maps, I'll worry about parsing it to JSON once I have this working. Here is my code, "MY_APPID" is replaced with my API key, I just removed it here.
My main:
private async Task<string> GetLocationJson()
{
const string APPID = "(MY_APPID)";
const string LOCATIONID = "2172797";
string jsonAsString = "";
string callStringJson = "api.openweathermap.org/data/2.5/weather?id=" + LOCATIONID + "&appid=" + APPID;
ApiCalls weatherApi = new ApiCalls(callStringJson);
jsonAsString = await weatherApi.GetLocationJson();
return jsonAsString;
}
//ShowLocationJson is called on button click
protected void ShowLocationJson(object sender, EventArgs e)
{
litOutput.Text = GetLocationJson().ToString();
}
And my ApiCalls Class is:
public class ApiCalls
{
HttpClient client = new HttpClient();
Uri url;
public ApiCalls(string link)
{
url = new Uri("https://" + link);
}
public async Task<string> GetLocationJson()
{
string content = await client.GetStringAsync(url);
return content;
}
}
url variable is being passed the correct values so I know it's ok up to there.
Im using ASP.NET Framework 4.5 as well
As Steve and mason have already noticed you have to await all methods returning Task. You need to change your ShowLocationMethod to:
protected async void ShowLocationJson(object sender, EventArgs e)
{
litOutput.Text = await GetLocationJson();
}
You receive System.Threading.Tasks.Task1[System.String] because you call method ToString() of Task object. The default implementation of the ToString method returns the fully qualified name of the type of the object: Task<String>

Reading Axios Get params in Asp.Net MVC controller

I am using axios get method and passing params to asp.net mvc controller. I can read individual values. But I am trying to read all values together as one object. I do not have a view model and I am trying to read params as generic object. What will be axios params datatype to use in c# controller as parameter ? I created a seperate method for buildurl and validating each parameter but is there any option to validate all at once?
This works
React Code
export const GetRequestCall = () => {
const getUrl = 'baseurl';
return new Promise((resolve, reject) => {
axios.get(getUrl, {
params: {
param1: 'abc',
param2: 'efg'
}
})
.then(response => {
}).catch(error => reject(error));
});
};
C# controller code
//Read parameter as individual strings
[HttpGet("[action]")]
public async Task<string> GET(string param1, string param2)
{
try
{
var url = BuildUri( param1, param2);
}
}
This did not work
Controller code
//Read parameters as a single object to do some logic. Tried
//[FromBody]object, Object, String as parameters datatypes for data
[HttpGet("[action]")]
public async Task<string> GET(Array data)
{
try
{
var url = BuildUri( param1, param2);
}
}
private static string BuildUri(string BaseUrl, string param1, string param2)
{
var uriBuilder = new UriBuilder(BaseUrl);
var query = HttpUtility.ParseQueryString(uriBuilder.Query);
if (!string.IsNullOrEmpty(param1)) { query["param1"] = param1; }
if (!string.IsNullOrEmpty(param2)) { query["param2"] = param2; }
uriBuilder.Query = query.ToString();
var url = uriBuilder.ToString();
return url;
}
I found option to build query string with name value pairs in C# but not sure on how to pass axios params as name value pair object to c# controller.
Ref: https://codereview.stackexchange.com/questions/91783/constructing-a-query-string-using-stringbuilder
There are probably better ways to do it, but one way is to use an object[] parameter like this:
[HttpGet("[action]")]
public string GET(object[] objects)
{
string param1 = objects[0] as string;
string param2 = objects[1] as string;
try
{
var url = BuildUri(param1, param2);
}
}
Also you should not use try blocks without catch blocks. I hope this helps

Pass list of strings from client to web api

The client application accesses a web api controller to get a set of data , the controller has a list as parameter.
static void Main(string[] args)
{
Program p = new Program();
p.getdata().Wait();
}
public async Task getdata()
{
List<string> datelist = new List<string>();
datelist.Add("12/05/2017");
datelist.Add("14/05/2017");
datelist.Add("18/05/2017");
HttpClient host = new HttpClient();
host.BaseAddress = new Uri("http://localhost/widgetApi/");
host.DefaultRequestHeaders.Clear();
host.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
StringContent content = new StringContent(JsonConvert.SerializeObject(datelist), Encoding.UTF8, "application/json");
HttpResponseMessage response = await host.GetAsync("api/dataAccessApi?"+ datelist);
response.EnsureSuccessStatusCode();
if( response.IsSuccessStatusCode)
{
Console.Read();
}
}
The controller is
public HttpResponseMessage Get([FromBody] List<string> dates)
{
..... function going here
}
My question is how can I pass datelist to the web api ??
GET requests do not have a BODY, you can use query string values. ?dates='{UrlEncoded date}'&dates='{UrlEncoded date}'...
public HttpResponseMessage Get([FromUri] List<string> dates) {
//..... function going here
}
On the client side you would need to construct the query string and append it to the Uri
var dates = datelist.Select(d => string.Format("dates={0}", UrlEncode(d));
var query = string.Join("&", dates);
var uri = "api/dataAccessApi?" + query;
With UrlEncode looking like this
/// <summary>Escape RFC3986 String</summary>
static string UrlEncode(string stringToEscape) {
return stringToEscape != null ? Uri.EscapeDataString(stringToEscape)
.Replace("!", "%21")
.Replace("'", "%27")
.Replace("(", "%28")
.Replace(")", "%29")
.Replace("*", "%2A") : string.Empty;
}
For Asp.Net Core consider to use [FromQuery] instead of [FromUri]

Object null in WebApi method after PostAsJsonAsync

I am posting an object to a WebApi method. I'm using PostAsJsonAsync to do this.
public async Task<HttpResponseMessage> PostAsync(string token, ServiceCall call)
{
var client = new HttpClient();
client.SetBearerToken(token);
var response = await client.PostAsJsonAsync(Uri + "id/nestedcall", call);
return response;
}
The object call that I'm passing is not null when I post it.
[HttpPost]
[Route("id/nestedcall")]
public async Task<IHttpActionResult> NestedCall([FromBody]ServiceCall call)
{
// call is null here
}
However it is null in my API method. I can't seem to work out why as all of the examples I've followed use this format.
Why isn't the call object being picked up by the web api?
Edit
Here is the ServiceCall object. It is in a separate class library and a reference is included in both the web application and the API.
public class ServiceCall
{
public ServiceCall(Service service, string grantType)
{
ClientId = service.Id;
ClientSecret = service.Secret;
Uri = service.Uri;
Scope = service.Scope;
GrantType = grantType;
}
public ServiceCall(string clientid, string clientsecret, string uri, string scope, string grantType)
{
ClientId = clientid;
ClientSecret = clientsecret;
Uri = uri;
Scope = scope;
GrantType = grantType;
}
public string ClientId { get; set; }
public string ClientSecret { get; set; }
public string Uri { get; set; }
public string Scope { get; set; }
public string GrantType { get; set; }
}
I have seen Object null in WebApi method after PostAsJsonAsync due to serialization.
Better to use PostAsync like below :
var obj = new MyClass()
{
MyProperty = 11
};
using (var client = new HttpClient())
{
string inputJson = Newtonsoft.Json.JsonConvert.SerializeObject(obj);
HttpContent inputContent = new StringContent(inputJson, Encoding.UTF8, "application/json");
HttpResponseMessage response1 = client.PostAsync("http://localhost:60909/api/home/Test", inputContent).Result;
if (response1.IsSuccessStatusCode)
{
}
}
Using Prefix Stackify I was able to diagnose that the serialiser was throwing an exception:
Newtonsoft.Json.JsonSerializationException: Unable to find a constructor to use for type Core.Models.ServiceCall. A class should either have a default constructor, one constructor with arguments or a constructor marked with the JsonConstructor attribute. Path 'ClientId', line 1, position 12.
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateNewObject
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize
However, very helpfully, rather than tell me that an exception occurred the controller simply gave me a null object.
As hinted by the exception the solution is to add a default constructor (or at least one the serialiser can understand).
public ServiceCall()
{
}
looks like the JSON serialization may be failing. BTW, remove that [FromBody] and try without it like below. PostAsJsonAsync method serializes the ServiceCall object to JSON and then sends the JSON payload in a POST request.
public async Task<IHttpActionResult> NestedCall(ServiceCall call)
{
// your code
}
I run into exactly the same problem and had to do this to solve it:
using (var client = new HttpClient())
{
client.SetBearerToken(token);
var content = new StringContent(JsonConvert.SerializeObject(call), Encoding.UTF8, "application/json");
var response = await client.PostAsJsonAsync(Uri + "id/nestedcall", content);
return response;
}

How to get client domain name from a request

I have wcf-service host at kkk.com. When someone(other domain) request to my service I use this code to get client's domain name.
public static string GetClientDomian(HttpContext context)
{
string clientDomain = string.Empty;
clientDomain = context.Request.Url.Host;
return clientDomain;
}
But it's always return kkk.com not return the client's domain name. How to solve this? Thanks.
OK. This code is work. Change context.Request.Url.Host to context.Request.UrlReferrer.Host
Like this
public static string GetClientDomian(HttpContext context)
{
string clientDomain = string.Empty;
clientDomain = context.Request.UrlReferrer.Host;
return clientDomain;
}

Categories