How to use the extension methods for HttpWebRequest? - c#

I'm struggling with something that should be pretty basic for the professionals.
I'm trying to use an extension wrapper for httpWebRequest. the extension class looks like this:
public static class WebRequestExtensions
{
public static Stream GetRequestStreamWithTimeout(
this WebRequest request,
int? millisecondsTimeout = null)
{
return AsyncToSyncWithTimeout(
request.BeginGetRequestStream,
request.EndGetRequestStream,
millisecondsTimeout ?? request.Timeout);
}
public static WebResponse GetResponseWithTimeout(
this HttpWebRequest request,
int? millisecondsTimeout = null)
{
return AsyncToSyncWithTimeout(
request.BeginGetResponse,
request.EndGetResponse,
millisecondsTimeout ?? request.Timeout);
}
private static T AsyncToSyncWithTimeout<T>(
Func<AsyncCallback, object, IAsyncResult> begin,
Func<IAsyncResult, T> end,
int millisecondsTimeout)
{
var iar = begin(null, null);
if (!iar.AsyncWaitHandle.WaitOne(millisecondsTimeout))
{
var ex = new TimeoutException();
throw new WebException(ex.Message, ex, WebExceptionStatus.Timeout, null);
}
return end(iar);
}
}
I'm trying to use the wrapper methods GetResponseWithTimeout and GetRequestStreamWithTimeout but I don't know how to do this. The working code should look like this:
var request = (HttpWebRequest)WebRequest.Create(url);
requestStream = request.GetRequestStreamWithTimeout();
How can I achieve this?
Edit
I've tried to derive the main class from the extension class which let's me use the wrapper methods but now I'm getting this error message:
Error 3 'chunkedUpload.UploadFile': cannot derive from static class 'chunkedUpload.WebRequestExtensions'

Related

Success/Failure return type for Generic Method

I have wrote Generic Methods for Get,Post and Put. An example of Get Generic Method is :
public async Task<object> GetAsync<T>(string uri, NamingStrategy namingStrategy)
{
using (var requestMessage = new HttpRequestMessage(HttpMethod.Get, uri))
{
return await ProcessAsync<T>(requestMessage, namingStrategy);
}
}
and ProcessAync is :
public async Task<object> ProcessAsync<T>(HttpRequestMessage request, NamingStrategy namingStrategy)
{
if (!string.IsNullOrEmpty(AuthToken))
{
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", AuthToken);
}
HttpResponseMessage response = await _client.SendAsync(request);
if (response.IsSuccessStatusCode)
{
_logger.LogInformation("Request Succeeded");
var dezerializerSettings = new JsonSerializerSettings
{
ContractResolver = new DefaultContractResolver
{
NamingStrategy = namingStrategy
}
};
T responseModel = JsonConvert.DeserializeObject<T>(await response.Content.ReadAsStringAsync(), dezerializerSettings);
return responseModel;
}
else
{
return await GetFailureResponseModel(response);
}
}
than i am calling this get method like that in my SingletonClass
public async Task<object> GetShops(string category)
{
_logger.LogInformation("ClubMatas outgoing request: {RequestName}", nameof(GetShops));
return await _client.GetAsync<ShopsResponseModel>($"v2/shops?category={WebUtility.UrlEncode(category)}");
}
And this method is called in my Controller like this
public async Task<ActionResult<object>> GetShops([FromQuery(Name = "category")]string category)
{
var response = await _httpClient.GetShops(category);
return ParseResponse<ShopsResponseModel>(response);
}
and ParseResponse is
protected ActionResult<object> ParseResponse<T>(object response)
{
if (response.GetType() == typeof(T))
{
return Ok(response);
}
else
{
return Error(response);
}
}
As the call chain shows, I am expecting other SuccessModel or FailureModel in my Api response and due to that I have to use object as return type. But I have feeling that I shouldn't be using object type for return. FYI above chain works fine. I am just looking for more refactoring or enhancement of my current flow. looking for more elegant solution to this problem. Please do suggest any other solution for my problem.
Update
I tried #ChrisPratt suggestion of using Interface, but that solution is not working or maybe i am doing it wrong. So i created this empty Interface
public interface IResult
{
}
And I extended Both my ShopResponseModel and FailureResponseModel from IResult Interface, and updated methods like this.
public async Task<IResult> GetShops(string category)
{
_logger.LogInformation("ClubMatas outgoing request: {RequestName}", nameof(GetShops));
return await _client.GetAsync<IResult>($"v2/shops?category={WebUtility.UrlEncode(category)}");
}
and
public async Task<T> GetAsync<T>(string uri, NamingStrategy namingStrategy)
{
using (var requestMessage = new HttpRequestMessage(HttpMethod.Get, uri))
{
return await ProcessAsync<T>(requestMessage, namingStrategy);
}
}
and I updated ProcessAsync return type from object to T. But getting errors.
But I have feeling that I shouldn't be using object type for return.
Yes. Don't use object for return values. It's virtually useless as a return type. What you should be doing is returning an interface. For example, you can do something like:
public interface IResponseStatusModel
{
bool Succeeded { get; }
int StatusCode { get; }
// etc.
}
Then:
public class SuccessModel : IResponseStatusModel
public class FailureModel : IResponseStatusModel
Then, you can return IResponseStatusModel, and based on the interface, you'll be able to interact with any property or method defined on the interface, regardless of which model you actually return.
However, you really shouldn't have separate classes for success/failure. Creating an interface that can generically allow you to interact with either one is going to lead to blurring the lines between the two, anyways. Instead, you should simply return a single model type, that has properties like the above and maybe a list property for errors and such. For example:
public class ProcessResult
{
public ProcessResult(int statusCode) : this(statusCode, null) {}
public ProcessResult(int statusCode, IEnumerable<string> errors)
{
Succeeded = statusCode < 300;
StatusCode = statusCode;
Errors = errors;
}
public bool Succeeded { get; private set; }
public int StatusCode { get; private set; }
public IEnumerable<string> Errors { get; private set; }
}
That's a very basic example. You might want to build it out more and provide a more robust solution for determining whether the task succeeded or not. The general idea is that you provide as much relevant information as possible concerning the result of the operation. Then, in your code, you can simply branch on Succeeded and then handle the situation accordingly:
if (result.Succeeded)
{
// do something on success
}
else
{
// do something on failure
}

Creating instance of return type in generic method

I am looking to create a generic helper method in java that mimics the functionality of the following C# method.
private T Execute<T>(Request request) where T : Response, new()
{
.... Code
}
The method above is called in the following cases
public AddLogicalDeviceResponse AddLogicalDevice(AddLogicalDeviceRequest request)
{
return Execute<AddLogicalDeviceResponse>(request);
}
public GetConfigurationResponse GetConfiguration(GetConfigurationRequest request)
{
return Execute<GetConfigurationResponse>(request);
}
public GetDeviceDefinitionsResponse GetDeviceDefinitions(GetDeviceDefinitionsRequest request)
{
return Execute<GetDeviceDefinitionsResponse>(request);
}
public RemoveLogicalDeviceResponse RemoveLogicalDevice(RemoveLogicalDeviceRequest request)
{
return Execute<RemoveLogicalDeviceResponse>(request);
}
public GetEPCListCommandResponse GetEPCListCommand(GetEPCListCommandRequest request)
{
return Execute<GetEPCListCommandResponse>(request);
}
public DeviceSpecificCommandResponse DeviceSpecificCommand(DeviceSpecificCommandRequest request)
{
return Execute<DeviceSpecificCommandResponse>(request);
}
public GetConfigValuesCommandResponse GetConfigValuesCommand(GetConfigValuesCommandRequest request)
{
return Execute<GetConfigValuesCommandResponse>(request);
}
public SetConfigValuesCommandResponse SetConfigValuesCommand(SetConfigValuesCommandRequest request)
{
return Execute<SetConfigValuesCommandResponse>(request);
}
public UpdateFirmwareCommandResponse UpdateFirmwareCommand(UpdateFirmwareCommandRequest request)
{
return Execute<UpdateFirmwareCommandResponse>(request);
}
Each of the above cases extends a class Response or Request in their respective situations.
I have attempted to create the same implementation as the above C# code using Java generics, but I have not had any success. Is it possible to implement the same functionality using only one helper method or am I forced to create a separate helper method for each individual type of call.
EDIT :
Here is my current Java implementation
private <T extends Response> execute(Request request)
{
String url = request.BuildUri(_baseUri, _accessKey);
Object[] response = Send(url, "");
if(((Integer)response[1] == 200))
{
T jsResponse = new T();
jsResponse.Body = (String)response[0];
jsResponse.Request = url;
return jsResponse;
}
else
{
throw new ResponseException(response[1], response[2], url, response[0]);
}
}
My current troubles stem from the function not being able to recognize the return as a valid object. Not being able to initialize the object T as a Response, and the T object not recognizing methods that are implemented in Response.
In Java, there's no way to create an instance of T class without sending Class<T> as parameter. Here's an example of using this for your current option:
interface Request {}
interface Response {
public String sayHi();
}
class DeviceRequest implements Request {}
class DeviceResponse implements Response{
public String sayHi() { return "DeviceResponse"; }
}
class WebRequest implements Request {}
class WebResponse implements Response{
public String sayHi() { return "WebResponse"; }
}
class Helper {
private <T extends Response> T execute(Request request, Class<T> clazz) throws InstantiationException, IllegalAccessException {
return clazz.newInstance();
}
public DeviceResponse foo(DeviceRequest request) throws InstantiationException, IllegalAccessException {
return execute(request, DeviceResponse.class);
}
public WebResponse bar(WebRequest request) throws InstantiationException, IllegalAccessException {
return execute(request, WebResponse.class);
}
}
class Consumer {
public void baz() throws InstantiationException, IllegalAccessException {
Helper helper = new Helper();
DeviceResponse dr = helper.foo(new DeviceRequest());
WebResponse wr = helper.bar(new WebRequest());
System.out.println(dr.sayHi());
System.out.println(wr.sayHi());
}
public static void main(String[] args) throws Exception {
new Consumer().baz();
}
}
Note that since this is just an example, I prefered to just throw the Exceptions without handling them. For real world app, you should handle the exceptions instead of just throwing them.
In Java you define the generic parameter before the other parts of the signature.
private <T extends Response> T execute(Request request)
{
.... Code
}

Avoid fxcop error CA1004 in this case

I have a case where it is returning objects of type T. My code looks like this.
public static T GetObjectsFromWebRequest<T>(string urlPath) where T : class
{
T modelObjects;
try
{
//SaveServiceDataIntoTextFile(urlPath);
WebRequest request = WebRequest.Create(urlPath);
WebResponse ws = request.GetResponse();
StreamReader responseStream = new StreamReader(ws.GetResponseStream());
//Get the response of the webrequest into a string
string response = responseStream.ReadToEnd();
modelObjects = XMLSerializeDeserialize.ConvertXMLToModel<T>(response);
}
catch (Exception)
{
throw;
}
return modelObjects;
}
In this case I don't have any option but add a default parameter like
public static T GetObjectsFromWebRequest<T>(string urlPath, T a = null) where T : class
Is there any other way I can resolve this violation?
As suggested here, you could use an out parameter to convey your result:
public static void GetObjectsFromWebRequest<T>(string urlPath, out T objects) ...

How to make a reference to a method name on an interface strongly typed

Sorry if this has been answered already, but I think I actually lack the formal education to ask this question properly, and hence also lack the correct criteria to search for it successfully.
I have an API that has several calls that do almost the same thing, but act on different input objects using a different method, but always form the same interface. I want to take the cut & paste aspect out of the API method call processes so that the common code gets done the same in all method invocations. I have managed to get a working solution using generics for the input and output objects and am making a reference to the method-name to be invoked from a string. I would like references to the the methods to be strongly typed instead of string based, so that a rename of the method name when re-factoring would not potentially leave the "magic" string of the method name waiting to explode at run-time.
Below is a very simplified version of what I am trying to achieve.
class ARequest { };
class AResponse { };
class BRequest { };
class BResponse { };
interface IWorker
{
AResponse DoA(ARequest aRequest);
BResponse DoB(BRequest bRequest);
}
class Worker : IWorker
{
public AResponse DoA(ARequest aRequest)
{
return new AResponse();
}
public BResponse DoB(BRequest bRequest)
{
return new BResponse();
}
}
class Program
{
static void Main(string[] args)
{
// current concrete copy & paste implementation
var a1 = API.DoA(new ARequest { });
var b1 = API.DoB(new BRequest { });
// new generic implementation
var a2 = API.DoA2(new ARequest { });
var b2 = API.DoB2(new BRequest { });
}
}
static class API
{
// current concrete copy & paste implementation
public static AResponse DoA(ARequest aRequest)
{
// lots of common code for logging & preperation
var worker = GetWorker();
return worker.DoA(aRequest);
}
public static BResponse DoB(BRequest bRequest)
{
// lots of common code for logging & preperation
var worker = GetWorker();
return worker.DoB(bRequest);
}
private static IWorker GetWorker()
{
return new Worker();
}
// new generic implementation Attempt
public static AResponse DoA2(ARequest aRequest)
{
return DoGen<ARequest, AResponse>(aRequest, "DoA"); // how to make references to DoA and DoB methods on the IWorker strongly typed?
}
public static BResponse DoB2(BRequest bRequest)
{
return DoGen<BRequest, BResponse>(bRequest, "DoB"); // how to make references to DoA and DoB methods on the IWorker strongly typed?
}
public static TResponse DoGen<TRequest, TResponse>(TRequest requestObj, string methodname)
where TRequest : class
where TResponse : class
{
// lots of common code for logging & preperation
var worker = GetWorker();
var mi = worker.GetType().GetMethod(methodname);
var result = mi.Invoke(worker, new Object[] { requestObj });
return result as TResponse;
}
}
"magic" string of the method name change to delegate on delegate
public static AResponse DoA2(ARequest aRequest)
{
return DoGen<ARequest, AResponse>(aRequest, worker => worker.DoA);
}
public static BResponse DoB2(BRequest bRequest)
{
return DoGen<BRequest, BResponse>(bRequest, worker => worker.DoB);
}
public static TResponse DoGen<TRequest, TResponse>(TRequest requestObj,
Func<IWorker, Func<TRequest, TResponse>> methodRef)
where TRequest : class
where TResponse : class
{
// lots of common code for logging & preparation
var worker = GetWorker();
var method = methodRef(worker);
return method(requestObj);
}
Func< xRequest, xResponse > might do what you are looking for:
var a1 = new Func<ARequest, AResponse>(API.DoA);
var b1 = new Func<BRequest, BResponse>(API.DoB);
var a2 = new Func<ARequest, AResponse>(API.DoA2);
var b2 = new Func<BRequest, BResponse>(API.DoB2);
a1.Invoke(new ARequest { });
b1.Invoke(new BRequest { });
a2.Invoke(new ARequest { });
b2.Invoke(new ARequest { }); // fails at compile time
Add a delegate for the mehods:
public delegate TResponse DoXDelegate<in TRequest, out TResponse>(TRequest request);
public static TResponse DoGen<TRequest, TResponse>(TRequest requestObj, DoXDelegate<TRequest, TResponse> method)
where TRequest : class
where TResponse : class
{
// lots of common code for logging & preperation
var worker = GetWorker();
/*var mi = worker.GetType().GetMethod(methodname);
var result = mi.Invoke(worker, new Object[] { requestObj });
return result as TResponse;*/
return method.Invoke(requestObj);
}
Use Func<TRequest, TResponse> like so:
Edit: That solution example is only usable if it doesn't matter where worker object comes from.
// new generic implementation Attempt
public static AResponse DoA2(ARequest aRequest)
{
return DoGen<ARequest, AResponse>(aRequest, DoA); // how to make refreces to DoA and DoB methods strongly typed?
}
public static BResponse DoB2(BRequest bRequest)
{
return DoGen<BRequest, BResponse>(bRequest, DoB); // how to make refreces to DoA and DoB methods strongly typed?
}
public static TResponse DoGen<TRequest, TResponse>(TRequest requestObj, Func<TRequest, TResponse> func)
where TRequest : class
where TResponse : class
{
// lots of common code for logging & preperation
var result = func(requestObj);
return result as TResponse;
}

Is there any way to inherit a class without constructors in .NET?

I'm currently trying to modify some HttpWebRequest functions, but I can't do it through inheritance because HttpWebRequest has no public constructors (besides the deserialization constructor). Is there a workaround to do this?
My objective is to code something like the example below, but this class objects must inherit the HttpWebRequest properties and methods:
using System;
using System.Net;
using System.Threading;
public class AsyncWebRequest:WebRequest
{
private readonly AsyncCallback getResponseCallback;
private readonly Uri uri;
private volatile int RetriesLeft = 3;
private volatile WebRequest request;
public AsyncWebRequest(string uri, AsyncCallback getResponseCallback)
:this(new Uri(uri), getResponseCallback)
{
}
public AsyncWebRequest(Uri uri, AsyncCallback getResponseCallback):base()
{
this.uri = uri;
this.getResponseCallback = getResponseCallback;
}
private IAsyncResult BeginGetResponse()
{
request = HttpWebRequest.CreateDefault(uri);
((HttpWebRequest)request).ReadWriteTimeout = Timeout;
var result = request.BeginGetResponse(GetResponseCallback, null);
ThreadPool.RegisterWaitForSingleObject(result.AsyncWaitHandle,
GetResponseTimeout, null, Timeout, true);
return result;
}
private void GetResponseTimeout(object state, bool timedOut)
{
if (timedOut)
{
Retry();
}
}
private void Retry()
{
request.Abort();
bool retry = false;
lock (request)
{
if (RetriesLeft > 0)
{
Interlocked.Decrement(ref RetriesLeft);
retry = true;
}
}
if (retry)
{
BeginGetResponse();
}
else
{
getResponseCallback(null);
}
}
private void GetResponseCallback(IAsyncResult AsyncResult)
{
try
{
getResponseCallback(AsyncResult);
}
catch(WebException webException)
{
Retry();
}
}
}
You can't through inheritance from HttpWebRequest (if you don't want to call the serialization constructor) , but you can through composition and delegation, and through inheritance from WebRequest (I'm not sure if that will do it for you, but functionally it is quite similar). WebRequest has a default constructor.
In this case you then can't have the class 'be' a HttpWebRequest (as in an is-a relationship), since you can't extend from it, but it wil 'be' a WebRequest, which should suffice.
You could write a class that inherits from WebRequest, that has an instance member of type WebRequest, create a HttpWebRequest and assign to instance member in the constructor of the new type and delegate all calls to that reference (sort of a decorator pattern):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
namespace ClassLibrary1
{
public class MyHttpWebRequest : WebRequest
{
private WebRequest request;
public MyHttpWebRequest(string uri)
{
request = HttpWebRequest.Create(uri);
}
public override WebResponse GetResponse()
{
// do your extras, or just delegate to get the original code, as long
// as you still keep to expected behavior etc.
return request.GetResponse();
}
}
}
Unless you can trick the serialization constructor to do your bidding, then no, there is no way.
The constructors of that class are internal, so you have no way of calling them.

Categories

Resources