Querying C# attribute - c#

i have tried to surf the internet but i could not get anything related to what i want.
This is in relation to ASP.Net. But could be any other instance as well.
Following is my attribute
class SomeAttribute :Attribute
{
string someparam;
string SomeParam
{
get{ return someparam;}
set { someparam = val;}
//the value generated for someparam is dynamically generated with respect to some attribute present in the request header.
}
}
it's similar to the [Authorize] attribute that .net uses in its asp .net memberships to validate if the user has logged in and it redirects him back to log in page if validation fails.
I have an attribute associated with a method like below:
[SomeAttribute]
public void someFunction
{
//i want to retrieve here the value of someparam jus generated before entering this method.
}
Note that i don't pass any value or used any named properties in this attribute. It is simply going to check a condition for me whenever the method is called and return true or false and accordingly the function is either called or not.
In my case, After validating, it generates a value and that value has to be shared with the function to which it is associated 'somefunction'.
i know reflections can help me get the attributes associated with a function and the value of its properties.
But here i dont want to fetch the value from some other function. And i dont want to just fetch the attribute either.
As i mentioned earlier when the function is called the attribute will work upon that. What the attribute does is fetches some data from request header and does some processing and generates a value. Now this value has to be passed on to the function just after that.

Well, what you want to accomplish is certainly possible, but it would not be an optimal use of the run-time or the MVC model.
In this particular case, think of an attribute as an annotation. It's something you use to mark a function, controller, etc. so that its execution behaves differently at run-time. The attribute itself should not be doing the bulk of the work, rather just signalling to other pieces in your design to behave differently.
It seems like you want to check some header values, and calculate something based off of that. You can use extension methods off of a Request class to accomplish this.
Now, let's say that inside your Controller's function, you want to guarantee that the header values exist. You can have an attribute called RequireHeaderValues that implements IActionFilter. The attribute would check the header for the required values and if they don't exist, it routes the response to another location or somehow indicates error. This way, when inside your function, you call the extension method off the Request object, you are guaranteed that the values will exist. The MVC run-time will automatically call your filter attribute for you. For more info, see this.

Related

How to validate all properties in a model at the same time?

I have a Blazor application. In this application I have several models with various ValidationAttributes.
To validate these models I use an EditForm from Microsoft.AspNetCore.Components.Forms. On this form there is a parameter Called EditContext where I call the Validate() method to validate my models.
The validation itself works fine. However the order of when validations are run seems to be based on the type, like this:
Required
Other(Like Range)
IValidatableObject
This results in Required validations being validated first and only after these are valid in the model the other validations are running.
What I want is for all validations to run at the same time.
Does anyone know how to achieve this in Blazor?
Thanks
What I want is for all validations to run at the same time.
Not sure what you mean? All registered validations are run when you call Validate. There's has to be a sequence. If you want to change the sequence then you need to write your own validator.
the order of when validations are run seems to be based on the type
Validate on the edit context looks like this. It simply invokes any delegates registered with the OnValidationRequested event.
public event EventHandler<ValidationRequestedEventArgs>? OnValidationRequested;
public bool Validate()
{
OnValidationRequested?.Invoke(this, ValidationRequestedEventArgs.Empty);
return !GetValidationMessages().Any();
}
DataAnnotationsValidator or whatever validator you use registers a handler on this event.
In your case the validator is finding fields to validate by searching through the properties in the Model (referenced in EditContext) for specifc attributes. The first attribute it looks for is Required, ....
I'm apparently not allowed to write comments - only answers - but you're right and what Shaun Curtis says is definitely wrong. For anybody doubting this there's a gist here.
When using <DataAnnotationsValidator /> the validation attributes on the model are processed first - only once all of the attribute validation rules pass will the IValidatableObject.Validate method be called.
The functionality is by design - IValidatableObject is to validate the entire object once all of its properties have been filled out. Why is IValidatableObject.Validate only called if property validation passes?
I think Required validation is checked first for a reason. All subsequent validations can and must be run only after the property has a value.
Otherwise, all the other validations would fail by default. It's the framework just reminding you that you forgot to type in a field. After you supply the value, then it goes on to validate its format and what not.
I hope that makes sense.

how to search other field than id

I'm following and implementing a side project from:
https://learn.microsoft.com/es-mx/aspnet/core/tutorials/first-web-api?view=aspnetcore-3.0&tabs=visual-studio
But in the part where [HttpGet("{id}")] is invoked, it works only with the id field, but I want to retrieve a JSON stored in the DBmemory, with other field instead of id; in this case I want to manage data by field TAG.
How can I accomplish this?
I've try to change all the id parts to TAG, which is the field I'm looking for, but when I do this, the post method breaks up.
// GET: api/Maquinas/5
[HttpGet("{id}")]
public async Task<ActionResult<Maquina>> GetMaquina(string id)
{
// HERE. i need to find data with the field of "TAG" not "id"
var maquina = await _context.Maquinas.FindAsync(id);
if (maquina == null)
{
return NotFound();
}
return maquina;
}
Don't get stuck on the fact that is called id. You could make use of this endpoint and instead of passing the value of id to pass the value of tag, api/Maquinas/tagvalue.
Later on you should use this value in the call you make to retrieve the entity you are looking for.
_context.Maquinas.FirstOrDefaultAsync(maquina => maquina.Tag == id);
I have assumed here that the property on which you want to filter is called Tag and it's type is string. It is quite probable, at least the name of the property to not be this one. So you have to change the above code correspondingly.
This will fix your problem, but you should not consider this a best practice. The semantics of your API would be broken. The very reason, I shared the above, is to show you that the name of the parameter id is irrelevant with that you pass. There isn't any check that would halt you for passing there "anything". The reason I wrote that the semantics of your API would be broken is that since this is going to be a REST api, someone would expect an endpoint like the following one:
api/Maquinas/1
for getting the entity with id 1.

Explicit vs. implicit null in ASP.NET Web API during partial updates

I have been experimenting with Web API 2 for the past couple of weeks and I'm trying to figure out the best way to handle a particular scenario during partial updates.
The API will allow the user to do partial updates via POST. By design, any properties that are not supplied in the request body are assumed to be unchanged and no changes will be made to those properties.
The challenge, however, is trying to determine when a user has explicitly set a property value to null. When the request body is pulled in via the controller, any absent properties are set as null automatically as the JSON request body is deserialized. As such, I lose my ability to determine if the property value is null explicitly (i.e. the user is trying to set the property value as null, in which case I want to update the property to null) or if the property value is null implicitly (i.e. the property value was set to null during deserilaization, in which case I want to ignore it).
I am looking for any ideas of how I might approach this situation.
I have played around with this a bit and I have come up with a way to work around this. Maybe there's another way to address the issue but this seems to be a reasonable approach:
In Web API, the request body can only be read once. Therefore, if you have the controller pull the object in for you, the object will be deserialized and you will lose access to the original request content and will not be able to determine if something was explicitly null or absent. This is demonstrated by something like this:
[Route("cars"), HttpPost]
public IHttpActionResult AddCar(Car car)
{
Car newCar = Car.Add(car);
return Created<Car>("/cars/" + newCar.car_id, newCar);
}
If you want to be able to examine exactly what was sent in, you don't have the controller pull in the object for you, instead, you pull the request body in manually, thus preserving your ability to see exactly what was sent in, like this:
[Route("cars"), HttpPost]
public IHttpActionResult AddCar()
{
HttpContent content = Request.Content;
string carJson = content.ReadAsStringAsync().Result;
// You now have the original JSON and can examine it before deserialization
}
It certainly adds a few more steps, but at least in my case where I needed to be able to see exactly what was POSTed, this provides a solution that seems to work.

How to differentiate between user specified null and default value in WCF data contract

I need to define a WCF API to enable user to update large object. While I can define few smaller methods and let the user update specific parts of the large object at a time. But for some reason I am not able to do that. The other way I tried is defined the data contract as collection of key-value (key is an enum and value is some string) and let the user add whatever he wants to update. This api very compact but it's not very intuitive and can be confusing for the user. Also since the value is of string type, so it's not very type safe.
So I now I have create one api, where the user can update the entire object.
for example:
public UpdateResult UpdateAPI(UpdateParam param){}
Now the UpdateParam class will several nullable fields.
Q: If there is a null value in one of the fields, how can differentiate at the server side,
the null value was specified by the user or it's default non-specified one? Is there something in the incoming soap message that can help differentiate?
Any help would be greatly appreciated.
Similar questions asked are
1. Data member default values, how to figure out whether something was really sent?
2.
no, as far as i know there is no way to tell the conditions apart if you only have a nullable field ...
however, you could provide an additional bool per property that could serve as a flag to indicate if the value was set by the user or is still on its default value
You can implement the setters of your properties to automatically set the corresponding bool when your properties are set

Requires a generic approach to validate control of ASP.Net form

I have a B2B we app having lots of forms taking input from registered users. So validation is mandatory there. I am using 3 tier architecture for my app. I am just ignoring server validation controls and client side validations. Instead i am thinking of Code Behind based validation, which i know will increase hit to my server, but too is most secure, if I am not wrong.
So what i am thinking is,
to enumerate all the controls of the page and check their validity. But this wayI can check only whether it is empty or not. Also I have to write it on each and every page.
Another approach, if i can set the maxlength , mandatory etc somewhere in my Model Layer where I have skeleton classes,and compare it while save button hit and tell what is missing and where.
Some common method that will take entire page controls as array of controls and check for validity...
Please guide me which one is possible or any other good solution.So that i can avoid code repetitions.
Model Layer means
public class Employee
{
public string Name {get;set;}
}
You can add a set of controls that inherit from ASP.NET controls, only with (a)additional type classification. For example: TextBox that accepts an attribute of DataType (enum) and values like: int, double, email etc. Another idea is for int type add a min/max values (i.e 15-32). And (b) a Validate function that returns true/false if the value matches the datatype.
Then, create a page base that inherits from Page and exposes a function called ValidateAllMyControls that iterates through all those special controls that are in use in the current form and calls the Validate function for each one. If one of them returns false - the form is not valid. :)

Categories