Modifying Error message at Client side. Custom Validation ASP .NET MVC - asp.net-mvc-4

I am trying implement custom client side validation.It is a cross coupled validation. I have followed all steps and its working fine. But my requirement requires me to modify the ErrorMessage which is will be part of metadata(HTML 5 Data Attribute). The example is as follows
IClientValidatable implementation:
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
ModelClientValidationRule rule = new ModelClientValidationRule();
rule.ValidationType = "salaryandloanconstraint";
rule.ValidationParameters.Add("loanconstraintvalue", _loanEligibleMultiplicity);
rule.ErrorMessage = "Salary Insufficient to sanction a loan amount of";
return new ModelClientValidationRule[] { rule };
}
The message which i have initilized to rule.ErrorMessage is incomplete. I want to append text which is taken from input field for LoanAmount property to the error message when the user enters.
In Summary is there any way which i can manipulate the error message(HTML5 DATA ATTRIBUTES) at the client side using JQuery?

check this url, may be this solve your issue:
$(".field-validation-error span", $("#form"))
.clone()
.appendTo("#error-summary")
.wrap("<li>");

Related

How to return a status code from an endpoint that can then be handled by app.UseStatusCodePages() middleware?

If I return StatusCode(403) or any other error code from an endpoint, any configuration of app.UseStatusCodePages<whatever> will be ignored.
I believe this is because the StatusCode(<whatever>) will automatically create a result object, and UseStatusCodePages only kicks in if there is an error status code and no content.
So how do I set a status code result in an IActionResult type endpoint and then return without setting any content so that UseStatusCodePages will handle the job of providing a suitable resonse?
As far as I know, the UseStatusCodePages will just be fired when the action result is the StatusCodeResult.
If you put some value inside the status codes, it will return the object result which will not trigger the UseStatusCodePages.
So I suggest you could directly use StatusCodeResult(403), then if you want to put some value to the StatusCodeResult, I suggest you could put it inside the httpcontext's item.
More details, you could refer to below codes:
public IActionResult OnGet()
{
HttpContext.Items.Add("test","1");
return StatusCode(403);
}
Program.cs:
app.UseStatusCodePages(async statusCodeContext =>
{
var status = statusCodeContext.HttpContext.Items["test"];
// using static System.Net.Mime.MediaTypeNames;
statusCodeContext.HttpContext.Response.ContentType = Text.Plain;
await statusCodeContext.HttpContext.Response.WriteAsync(
$"Status Code Page: {statusCodeContext.HttpContext.Response.StatusCode}");
});
Result:
The issue was that I have the ApiController attribute on the endpoint controller. One of the things this attribute does is to automatically create a ProblemDetails response body for any failed requests, and it is this that prevents UseStatusCodePages from having any effect.
The solution is to either remove the ApiController attribute if you do not require any of its features, or alternatively its behaviour of automatically creating ProblemDetails responses can be disabled using the following configuration in Program.cs (or Startup.cs in old style projects).
builder.Services.AddControllers().ConfigureApiBehaviorOptions(options =>
{
options.SuppressMapClientErrors = true;
});

Acumatica API get all attachments

I have a problem while trying to get attachment from ACUMATICA through API service.
As the example in http://acumaticaopenuniversity.com/pdf/T210_Acumatica_Web_Services.pdf page 36
Example code here
But I don't know how many files here and what are their names? How can I get all attachment of this entity?
Thank in advance.
The contract based web service API has a straightforward GetFiles interface for getting all files of an entity. When you don't have special requirements that forces you to use the screen based web-service API, I'd recommend you use the contract based one.
Interface:
File[] GetFiles(Entity entity)
Usage pseudo-code:
using (DefaultSoapClient soapClient = new DefaultSoapClient())
{
soapClient.Login("username", "password", "CompanyLoginName", null, null);
File[] files = soapClient.GetFiles((Entity)soapClient.Get(new Entity { EntityIntField = new IntSearch { Value = 1 } }));
}
Contract based web service API reference:
http://acumaticaopenuniversity.com/courses/i210-contract-based-web-services/

ServiceStack: Can we Pass Data through a RequestFilterAttribute to the calling service

Maybe I'm thinking about this wrong, but I'm trying to create a custom attribute for our CMS to handle auth checks.
https://gist.github.com/sitefinitysteve/62ab761256a64a84d8a6#file-sitefinityjwt-cs-L39
So if this service is called from within the CMS from a logged in user, user data is all there for the service method already.
But in the context of being called from an app, the user is technically Anonymous, however I can decode the token and get the user just fine... but not sure how to like pass that over to the service.
Am I just maybe looking at this wrong, and the proper thing to do is to call a CMS API method to just log that person in (seems slow if I already have the persons user object from line 33, and the service context expires instantly.
Use Request.Items Dictionary
You would use the IRequest.Items dictionary for any data you want to pass throughout ServiceStack's Request Pipeline:
//RequestFilter:
req.Items["info"] = new MyRequestInfo { ... };
In Service:
var info = (MyRequestInfo)base.Request.Items["info"];
Have DTO's share common interface
Another option for adding extra info to your Service is to have Request DTO's implement an interfaces, e.g:
public interface IHasInfo
{
MyRequestInfo Info { get; set; }
}
Which you could then populate in your Request Filter, e.g:
((MyRequestInfo)dto).Info = new MyRequestInfo { ... };
Access in Service like any other DTO property, e.g:
public object Any(Request request)
{
var info = request.Info;
}

Specifyng a default message for Html.ValidationMessageFor in ASP.NET MVC4

I want to display an asterisk (*) next to a text box in my form when initially displayed (GET)
Also I want to use the same view for GET/POST when errors are present) so For the GET request
I pass in an empty model such as
return View(new Person());
Later, when the form is submitted (POST), I use the data annotations, check the model state and
display the errors if any
Html.ValidationMessageFor(v => v.FirstName)
For GET request, the model state is valid and no messages, so no asterisk gets displayed.
I am trying to workaround this by checking the request type and just print asterisk.
#(HttpContext.Current.Request.HttpMethod == "GET"? "*" : Html.ValidationMessageFor(v=> v.FirstName).ToString())
The problem is that Html.ValidationMessageFor(v=> v.FirstName).ToString() is already encoded
and I want to get the raw html from Html.ValidationMessageFor(v=> v.FirstName)
Or may be there is a better way here.
1. How do you display default helpful messages (next to form fields) - such as "Please enter IP address in the nnn.nnn.nnn.nnn format) for GET requests and then display the errors if any for the post?
2. What is the best way from a razor perspective to check an if condition and write a string or the MvcHtmlString
Further to my last comment, here is how I would create that helper to be used:
public static class HtmlValidationExtensions
{
public static MvcHtmlString ValidationMessageForCustom<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression, string customString)
{
var returnedString = HttpContext.Current.Request.HttpMethod == "GET" ? customString : helper.ValidationMessageFor(expression).ToString();
return MvcHtmlString.Create(returnedString);
}
}
And it would be used like this #Html.ValidationMessageForCustom(v=> v.FirstName, "Please enter IP address in the nnn.nnn.nnn.nnn format")

Varying WCF Security Roles/Claims by Method Parameter

I have a class that implements IAuthorizationPolicy. I set up a custom Principal object based on the logged in user which has all of my base level roles (I have also done this using claims). Now I would like to change the roles that a particular principal has depending on a key value passed in as a message parameter.
The problem I am having is that the request message cannot be read in the authorization policy class because I don't have access to write the message back to the request context. I can copy and read the message in a ServiceAuthorizationManager derived class using an override of the CheckAccess method. However, I have to ensure that the GetAuthorizationPolicies method has already been called prior to doing that.
I am looking for suggestions on how I can vary the roles on a principal, based on whether or not the message contains a particular parameter. Basically, when the Evaluate method id called on the policy I want to do something like this:
string myObjectId = null;
if (!messageCopy.IsEmpty)
{
System.Xml.XmlDictionaryReader xdr = messageCopy.GetReaderAtBodyContents();
xdr.ReadToDecendant("objectId");
if (xdr.Read())
{
myObjectId = xdr.ReadContentAsString();
}
xdr.Close();
}
messageCopy.Close();
ClaimSet claims = (myObjectId != null) ?
MapClaims(identity, myObjectId) : MapClaims(identity);
DefaultPrincipal principal = new DefaultPrincipal(identity, claims);
After an entire day of attempted failures, I gave up on trying to read the message body and used an easier method, adding a SOAP message header. When calling the service I now perform the following:
using (new OperationContextScope((IContextChannel)myService)) {
OperationContext.Current.OutgoingMessageHeaders.Add(
MessageHeader.CreateHeader("objectId", "http://tempuri.org/", "object value"));
myService.BeginMyOperation(parm, callback, state);
}
Then in my service authorization policy's Evaluate method I do this:
int index = OperationContext.Current.IncomingMessageHeaders.FindHeader(
"objectId", "http://tempuri.org/");
string myObjectId = (index < 0) ? null :
OperationContext.Current.IncomingMessageHeaders.GetHeader<string>(index);
ClaimSet claims = (myObjectId != null) ?
MapClaims(identity, myObjectId) : MapClaims(identity);
DefaultPrincipal principal = new DefaultPrincipal(identity, claims);
I run into the same situation while developing WebAPI security and I choosen the next approach:
Method that recieves argument creates AuthorizationContext where it passes the argument as Resource claim
My custom ClaimsAuthorizationManager then can get argument from AuthorizationContext.Resource and use it from authorization.