Get the Header Value In wcfWebapi Using Handler - wcf-web-api

How can i get the Header value in the WcfwebApi using the Handler before entering the Web-method .

You can use an OperationHandler<RequestMessage, RequestMessage>
It gets passed a RequestMessage in which you can access the the headers:
public class HeaderAccessRequestHandler : HttpOperationHandler<HttpRequestMessage, HttpRequestMessage> {
public HeaderAccessRequestHandler() : base("request") {
}
public override HttpRequestMessage OnHandle(HttpRequestMessage request) {
request.Headers.Remove("Accept"); // remove value and
request.Headers.Add("Accept","text/html"); // set it new = update
return request;
}
}

Related

Using Volley For Spoonacular Api

How to use Volley to fetch recipes from spoonacular API for an android application. I am new to APIs and would like some help in fetching recipes from the spoonacular api for a list of ingredients specified in an android app.
Step 1
dependencies {
...
implementation 'com.android.volley:volley:1.0.0'
}
Step 2
In AndroidManifest file add permission
<uses-permission android:name="android.permission.INTERNET"/>
Step 3 Add following in MyApplication class
private RequestQueue requestQueue;
public RequestQueue getRequestQueue() {
if (requestQueue == null)
requestQueue = Volley.newRequestQueue(getApplicationContext());
return requestQueue;
}
public void addToRequestQueue(Request request, String tag) {
request.setTag(tag);
getRequestQueue().add(request);
}
public void cancelAllRequests(String tag) {
getRequestQueue().cancelAll(tag);
}
Step 4 Final Step
//URL of the request we are sending
String url = "https://api.spoonacular.com/food/products/22347";
/*
JsonObjectRequest takes in five paramaters
Request Type - This specifies the type of the request eg: GET,
URL - This String param specifies the Request URL
JSONObject - This parameter takes in the POST parameters.null in case of
GET request
Listener -This parameter takes in a implementation of Response.Listener()
interface which is invoked if the request is successful
Listener -This parameter takes in a implemention of Error.Listener()
interface which is invoked if any error is encountered while processing
the request
*/
JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.GET,
url, null,
new Response.Listener() {
#Override
public void onResponse(JSONObject response) {
//Success Callback
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
//Failure Callback
}
});
// Adding the request to the queue along with a unique string tag
MyApplication.getInstance().addToRequestQueue(jsonObjectReq, "getRequest");
Something like that. Let's try. Thanks

How to get a custom ModelState error message in ASP.NET Core when a wrong enum value is passed in?

I'm passing a model to an API action with a property called eventType which is a nullable custom enum.
If I pass a random value for eventType, such as 'h', it fails to serialise which is correct.
However, the error I get from the ModelState is not something I would want a public caller to see. It includes the line number and position (see below).
I've tried a number of options including a custom data annotation with no success.
Does anyone know how I could define a nicer custom message?
"Error converting value \"h\" to type
'System.Nullable`1[Custom.EventTypes]'. Path 'eventType', line 1,
position 80."
Most times the first error is usually the most important error or rather one that describes the situation properly. You can use this way to manipulate to get the first error message from the first key or change it to whatever you want if you wish to get all the error messages.
public ActionResult GetMyMoney(MyModel myModel)
{
string nss = ModelState.First().Key;
ModelError[] ern = ModelState[nss].Errors.ToArray();
string ndd = ern.First().ErrorMessage;
}
public class CustomFilter: IAsyncActionFilter
{
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
if (!context.ModelState.IsValid)
{
// You can pass custom object to BadRequestObjectResult method
context.Result = new BadRequestObjectResult(customObject);
}
}
}
You can write a custom filter like above mentioned and pass a custom object with your message.
Ref: this
IF you just want the error messages you can simply create a custom class of response and then
var response = new ResponseApi{
StatusCode = HttpStatusCode.BadRequest,
Message = "Validation Error",
Response = ModelState.Values.SelectMany(x => x.Errors).Select(x =>
x.ErrorMessage)
};
then just return the response or create a validation filter to handle validations globally.
/// <summary>
/// Validatation filter to validate all the models.
/// </summary>
public class ValidationActionFilter : ActionFilterAttribute
{
/// <inheritdoc/>
public override void OnActionExecuting(HttpActionContext actionContext)
{
ModelStateDictionary modelState = actionContext.ModelState;
if (!modelState.IsValid)
{
actionContext.Response = SendResponse(new ResponseApi
{
StatusCode= 400,
Message = "Validation Error",
Response = modelState.Values.SelectMany(x =>
x.Errors).Select(x => x.ErrorMessage)
});
}
}
private HttpResponseMessage SendResponse(ResponseApiresponse)
{
var responseMessage = new HttpResponseMessage
{
StatusCode = (HttpStatusCode)response.StatusCode,
Content = new StringContent(JsonConvert.SerializeObject(response)),
};
responseMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
return responseMessage;
}
}

Pass Dynamic Values to ExchangeFilterFunction implementation in Spring WebClient

I would like to use ExchangeFilterFunction and use some dynamic values in it to add to the request header.
webClient = WebClient.builder()
.clientConnector(new ReactorClientHttpConnector(options -> {
options.option(ChannelOption.SO_TIMEOUT, DEFAULT_READ_TIMEOUT);
options.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, DEFAULT_CONNECTION_TIMEOUT);
})).filter(userCredentialDelegationFilter).build();
public class UserCredentialDelegationFilter implements ExchangeFilterFunction {
#Override
public Mono<ClientResponse> filter(ClientRequest request, ExchangeFunction next) {
String orgId = // ** I would like to pass in this org id when callling get on web client.
if (orgId != null) {
request = ClientRequest.from(request).header(ClientConstants.HEADER_ORG_ID, securityContext.getOrgId()).build();
}
return next.exchange(request);
}
}
How can I achieve this ?

Service Stack - Custom authentication on one route

In my current application, I am using Service Stack with JWT's for security. Security has been implemented and works perfectly. Trouble is, I would like to secure one route differently from the others. There is a document the logged in user retrieves, I want to make sure the document they are retrieving is theirs and not someone else's. It is very sensitive data. I would like to secure it differently because something like PostMan could be used with a valid token to retrieve any document, I want to prevent this. The users id is in the token, I would like to match it against the document that is being retrieved if possible. The current security is implemented like so:
public class AppHost: AppHostBase
{
public override void Configure(Funq.Container container)
{
Plugins.Add(new AuthFeature(() => new AuthUserSession(),
new IAuthProvider[] {
new JsonWebTokenAuthProvider("myKey", "myAudience"),
}));
}
}
JsonWebTokenAuthProvider is a custom class where security was implemented, this all works perfectly. Here is the code:
public override object Authenticate(IServiceBase authService, IAuthSession session, Authenticate request)
{
// first validate the token, then get roles from session
string header = request.oauth_token;
// if no auth header, 401
if (string.IsNullOrEmpty(header))
{
throw HttpError.Unauthorized(MissingAuthHeader);
}
string[] headerData = header.Split(' ');
// if header is missing bearer portion, 401
if (!string.Equals(headerData[0], "BEARER", StringComparison.OrdinalIgnoreCase))
{
throw HttpError.Unauthorized(InvalidAuthHeader);
}
// swap - and _ with their Base64 string equivalents
string secret = SymmetricKey.Replace('-', '+').Replace('_', '/');
string token = headerData[1].Replace("\"", "");
// set current principal to the validated token principal
Thread.CurrentPrincipal = JsonWebToken.ValidateToken(token, secret, Audience, true, Issuer);
string lanId = GetLanID(Thread.CurrentPrincipal.Identity.Name);
string proxyAsLanId = request.Meta.ContainsKey(META_PROXYID) ? request.Meta[META_PROXYID] : null;
if (HttpContext.Current != null)
{
// set the current request's user the the decoded principal
HttpContext.Current.User = Thread.CurrentPrincipal;
}
// set the session's username to the logged in user
session.UserName = Thread.CurrentPrincipal.Identity.Name;
session.Roles = GetApplicableRoles(lanId, proxyAsLanId);
authService.Request.SetItem("lanID", lanId);
authService.Request.SetItem("proxyAsLanId", proxyAsLanId);
return OnAuthenticated(authService, session, null, null);
}
I looked up RequestFilterAttribute found here, but I do not think that is what I want. Ideally, if the check fails I would like to return a 401 (unauthorized) if possible.
What is the best way to do this?
If you just want to handle one route differently than you can just add the validation in your single Service, e.g:
public object Any(MyRequest dto)
{
var lanId = base.Request.GetItem("lanId");
if (!MyIsValid(lanId))
throw HttpError.Unauthorized("Custom Auth Validation failed");
}
You could do the same in a RequestFilter, e.g:
public class CustomAuthValidationAttribute : RequestFilterAttribute
{
public override void Execute(IRequest req, IResponse res, object responseDto)
{
var lanId = req.GetItem("lanId");
if (!MyIsValid(lanId))
{
res.StatusCode = (int) HttpStatusCode.Unauthorized;
res.StatusDescription = "Custom Auth Validation failed";
res.EndRequest();
}
}
}
And apply it to a single Service:
[CustomAuthValidation]
public object Any(MyRequest dto)
{
//...
}
Or a collection of Services, e.g:
[CustomAuthValidation]
public class MyAuthServices : Service
{
public object Any(MyRequest1 dto)
{
//...
}
public object Any(MyRequest2 dto)
{
//...
}
}

How to request same parameter twice in query string?

I am trying to request the following query string url: api/item?name=storm&name=prest
I am using the following code below and I cannot get the code to work.
public class ItemController : ApiController
{
private cdwEntities db = new cdwEntities();
public HttpResponseMessage Get([FromUri] Query query)
{
var data = db.database_ICs.AsQueryable();
if (query.name != null)
{
**data = data.Where(c => c.Name.Split("&").Contains(query.name));**
}
if (query.id!= null)
{
data = data.Where(c => c.ID== query.id);
}
if (!data.Any())
{
var message = string.Format("No data was found");
return Request.CreateErrorResponse(HttpStatusCode.NotFound, message);
}
return Request.CreateResponse(HttpStatusCode.OK, data);
}
}
Any help would be very much appreciated.
You can use post Api and send array of [name].
name = [item1,item2....]
public void Post([FromBody] List<string> name) {
}
You can not pass same name key in Querystring. Browser/Code did not identified which is correct value, if you want multiple value then pass as a object.