We have a number of forms on our site that are shown with jquery .dialog and we submit them using an ajax post request.
I've done a fair bit of research and from what I can tell there isn't any definite patterns on how to return validation errors from the server side as a result of an ajax request.
Pretty much the only pattern I could find was to post the form and then do validation server side and in either case return a json object that encapsulated a result and if the result was incorrect the form html
ie.
{result: true}
{success: false, html = "<form>....</form>"}
So in the case the result was false you would need to rewire up any events attached to items on the form as you would be replacing the old form with the new form that has the validation errors.
This seems like an ok approach but you also end up potentially returning a lot more data to the client that you need to when they only really need to validation messages and you are also forced to rewire the form up which is a bit annoying.
I did find one other mention of somehow getting the validation errors and returning them in a json object from the action and somehow telling the client to display them against the correct fields.
Is there any frameworks out there that make this easier or should I write my own or just stick to returning the entire partial for the form and rewiring it when validation is incorrect?
I don't know of any frameworks that handle this particular case–and I don't know that there's a clear best practice–but it's easy enough to serialize validation errors and return them as a JSON object. You could try this extension method on ModelStateDictionary:
public static IEnumerable<ValidationResult> GetValidationResults(this ModelStateDictionary dictionary)
{
foreach (var key in dictionary.Keys)
foreach (var error in dictionary[key].Errors)
if (error != null)
yield return new ValidationResult(error.ErrorMessage, new string[] { key });
}
And in the controller:
if (!ModelState.IsValid)
{
return new JsonResult(ModelState.GetValidationResults());
}
But you're right, you would then have to loop through the object and append the errors to the correct fields. If you have ClientValidationEnabled and UnobtrusiveJavaScriptEnabled set to true, the loop would look something like this:
$.each(errors, function(i, item) {
$('span[data-valmsg-for=' + item.MemberNames[0] + ']').html(item.ErrorMessage);
})
If not, it wouldn't be that difficult to match up the error messages to their respective fields as the object contains the field name. This would definitely save you some data across the wire, but it moves a larger share of the validation responsibility into Javascript. Like I said, I don't know that there's a clear best practice, but I have used this method in the past with success.
Related
I'm trying to use react-validation for simple form validation in React. I understood how to validate the fields according to my needs, but what i do not understand, is how to get the "status" of the form, when the user tries to submit the it.
The documentation says that the Form component provides 4 public methods:
validate(name), validateAll(), showError(component [,error]), hideError(component)
From what i understand, these methods are accessible by a ref to the Form component:
<Form ref={c => { this.form = c }} onSubmit={this.handleSubmit.bind(this)}>
When i console log this.form in my submit handler, i do get an object with the above mentioned methods, but when i call one of them, like validateAll(), it returns undefined. I do not understand why.
Can someone help me with this specific plugin, or perhaps recommend a different simple alternative? I need to perform very basic validation(but can't use HTML built in one), and do not need something fancy like react-form or redux-form(i do not even use Redux in this project)
I have checked it in sandbox, please review it,
and I can tall you that it DOES work in this way. When you call this.form.validateAll() it returns undefined BUT it executes all validation functions and appends to form error messages defined in that functions. So may be it is even unnecessary validateAll to return smth
The solution I have found to provide state.isValid. Set isValid = true on form change
handleChange() {
this.setState({ isValid: true });
}
and in each validator set state.isValid = false if validation is not pass
I'm creating a new Web API and I'm having a doubt regarding the Update operation (it's a basic CRUD). Should I return a DTO with the updated entity data? I want my API to be RESTful.
have a read here
https://www.rfc-editor.org/rfc/rfc7231
it says and I quote:
For a state-changing request like PUT (Section 4.3.4) or POST
(Section 4.3.3), it implies that the server's response contains the
new representation of that resource, thereby distinguishing it from
representations that might only report about the action (e.g., "It
worked!"). This allows authoring applications to update their
local copies without the need for a subsequent GET request.
However, you do not need to be too fixed on this, return a 201 for example when you create something is perfectly OK as well and you probably want to add the the unique identifier of the created resource.
For updates, a 200 would be ok as well. 204 can be acceptable as well as already mentioned.
The bottom line is ... return only the data you need, if you need to see the whole updated object then return it. If you don't then don't do it. Keep in mind that some objects can be quite big and have a whole object graph below them, there's no point sending too much data down the wire.
I guess the most important thing is to choose one way of doing things and then be consistent and use the same thing everywhere
First of all, returning a DTO has nothing to do with RESTful.
It's true that DTO is a pattern created with the purpose of transferring data to remote interfaces (and web services can be a good fit for this pattern).
However using DTOs won't make your application more or less RESTful. Your application can use DTOs to have more control over the data exposed in the REST API. Just that.
If your update operation relies on the PUT HTTP method (which is designed to replace the state of a resource with a new representation), you may want to return 200 or 204 status code to indicate that the operation has succeeded.
If you go for 200, you can return a representation of the new state of the recently updated resource. If you go for 204, no representation must be returned.
By representation I mean a JSON document, a XML document or any other content that can be used to represent the state of a given resource.
We normally return NoContentResult after update is successful. For example,
[HttpPut("{id}", Name = "UpdateUser")]
public IActionResult UpdateUser(Guid id, [FromBody] UserUpdateDto user)
{
if (user == null)
{
return BadRequest();
}
if (!_repository.UserExists(id))
{
return NotFound();
}
var entity = _repository.GetUser(id);
Mapper.Map(user, entity);
_repository.UpdateUser(entity);
return NoContent();
}
NoContent basically returns status code 204. The following is the source code of NoContentResult.
public class NoContentResult : StatusCodeResult
{
public NoContentResult()
: base(204)
{
}
}
Returning data from a PUT operation is optional, though not necessary. If theres anything you wanted to calculate in the model which will be useful for the client then return them, but otherwise a 204.
Lets say I have a form with method=POST on my page.
Now this form has some basic form elements like textbox, checkbox, etc
It has action URL as http://example.com/someAction.do?param=value
I do understand that this is actually a contradictory thing to do, but my question is will it work in practice.
So my questions are;
Since the form method is POST and I have a querystring as well in my URL (?param=value)
Will it work correctly? i.e. will I be able to retrieve param=value on my receiving page (someAction.do)
Lets say I use Java/JSP to access the values on server side. So what is the way to get the values on server side ? Is the syntax same to access value of param=value as well as for the form elements like textbox/radio button/checkbox, etc ?
1) YES, you will have access to POST and GET variables since your request will contain both. So you can use $_GET["param_name"] and $_POST["param_name"] accordingly.
2) Using JSP you can use the following code for both:
<%= request.getParameter("param_name") %>
If you're using EL (JSP Expression Language), you can also get them in the following way:
${param.param_name}
EDIT: if the param_name is present in both the request QueryString and POST data, both of them will be returned as an array of values, the first one being the QueryString.
In such scenarios, getParameter("param_name) would return the first one of them (as explained here), however both of them can be read using the getParameterValues("param_name") method in the following way:
String[] values = request.getParameterValues("param_name");
For further info, read here.
Yes. You can retrieve these parameters in your action class.
Just you have to make property of same name (param in your case) with there getters and setters.
Sample Code
private String param;
{... getters and setters ...}
when you will do this, the parameters value (passed via URL) will get saved into the getters of that particular property. and through this, you can do whatever you want with that value.
The POST method just hide the submitted form data from the user. He/she can't see what data has been sent to the server, unless a special tool is used.
The GET method allows anybody to see what data it has. You can easily see the data from the URL (ex. By seeing the key-value pairs in the query string).
In other words it is up to you to show the (maybe unimportant) data to the user by using query string in the form action. For example in a data table filter. To keep the current pagination state, you can use domain.com/path.do?page=3 as an action. And you can hide the other data within the form components, like input, textarea, etc.
Both methods can be catched in the server with the same way. For example in Java, by using request.getParameter("page").
I am developing a website using zend framework.
i have a search form with get method. when the user clicks submit button the query string appears in the url after ? mark. but i want it to be zend like url.
is it possible?
As well as the JS approach you can do a redirect back to the preferred URL you want. I.e. let the form submit via GET, then redirect to the ZF routing style.
This is, however, overkill unless you have a really good reason to want to create neat URLs for your search queries. Generally speaking a search form should send a GET query that can be bookmarked. And there's nothing wrong with ?param=val style parameters in a URL :-)
ZF URLs are a little odd in that they force URL parameters to be part of the main URL. I.e. domain.com/controller/action/param/val/param2/val rather than domain.com/controller/action?param=val¶m2=val
This isn't always what you want, but seems to be the way frameworks are going with URL parameters
There is no obvious solution. The form generated by zf will be a standard html one. When submitted from the browser using GET it will result in a request like
/action/specified/in/form?var1=val1&var2=var2
Only solution to get a "zendlike url" (one with / instead of ? or &), would be to hack the form submission using javascript. For example you can listen for onSubmit, abort the submission and instead redirect browser to a translated url. I personally don't believe this solution is worth the added complexity, but it should perform what you're looking for.
After raging against this for a day-and-a-half, and doing my best to figure out the right way to do this fairly simple this, I gave up and did the following. I still can't believe there's not a better way.
The use case that necessitates this is a simple record listing, with a form up top for adding some filters (via GET), maybe some column sorting, and Zend_Paginate thrown in for good measure. I ran into issues using the Url view helper in my pagination partial, but I suspect with even just sorting and a filter-form, Zend_View_Helper_Url would still fall down.
But I digress. My solution was to add a method to my base controller class that merges any raw query-string parameters with the existing zend-style slashy-params, and redirects (but only if necessary). The method can be called in any action that doesn't have to handle POSTs.
Hopefully someone will find this useful. Or even better, find a better way:
/**
* Translate standard URL parameters (?foo=bar&baz=bork) to zend-style
* param (foo/bar/baz/bork). Query-string style
* values override existing route-params.
*/
public function mergeQueryString(){
if ($this->getRequest()->isPost()){
throw new Exception("mergeQueryString only works on GET requests.");
}
$q = $this->getRequest()->getQuery();
$p = $this->getRequest()->getParams();
if (empty($q)) {
//there's nothing to do.
return;
}
$action = $p['action'];
$controller = $p['controller'];
$module = $p['module'];
unset($p['action'],$p['controller'],$p['module']);
$params = array_merge($p,$q);
$this->_helper->getHelper('Redirector')
->setCode(301)
->gotoSimple(
$action,
$controller,
$module,
$params);
}
I have an ASP.NET MVC 2 application which in part allows a user to filter data and view that data in a JQGrid.
Currently this consists of a controller which initialises my filter model and configures how I wish my grid to be displayed. This information is used by a view and a partial view to display the filter and the grid shell. I use an editor template to display my filter. The JQGrid makes use of a JsonResult controller action (GET) to retrieve the results of the filter (with the addition of the paging offered by the grid - only a single page of data is returned by the GET request. The Uri used by the grid to request data contains the filter model as a RouteValue - and currently contains a string representation of the current state of the filter. A custom IModelBinder is used to convert this representation back into an instance of the filter model class.
The user can change the filter and press a submit button to get different results - this is then picked up by an (HttpPost) ViewResult action which takes the filter model - reconstituted by a further model binder and causes the grid shell to be updated.
So I have:
FilterModel
Represents the user's desired filtering characteristics
FilterModelEditorTemplateSubmissionBinder : DefaultModelBinder - used to convert the request information supplied from a user changing their filtering characteristics into the appropriate FilterModel instance.
FilterModelStringRepresentationBinder : IModelBinder - used to convert the encoded filter from the JQGrid GET request for data so the correct request is made of the service which is ultimately performing the query and returning the relevant data.
ViewResult Index() - constructs a default filter, configures the grid specification and returns the view to render the filter's editor template, and the grid shell.
[HttpPost]ViewResult Filter(FilterModel filter) - takes the new filter characteristics and returns the same view as Index(). Uses FilterModelEditorTemplateSubmissionBinder to bind the filter model.
JsonResult GetData(FilterModel filter, string sidx, string sord, int page, int rows) - called from the JQGrid in order to retrieve the data. Uses FilterModelStringRepresentationBinder to bind the filter model.
As a complication, my filter model contains a option to select a single value from a collection of items. This collection is retrieved from a service request and I don't want to keep querying for this data everytime I show the filter, currently I get it if the property is null, and then include the options hidden in the editor template and encoding in the string representation. These options are then reconstituted by the relevant model binder.
Although this approach works I can't help but feel that I am having to basically reinvent viewstate in order to maintain my filter and the included options. As I am new to ASP.NET MVC but am very happy with classic ASP and ASP.NET Web Forms I thought I'd throw this out there for comment and guidance as to find a way which more closely fits with the MVC pattern.
It seems to me that the best way in to divide some actions which provide pure data for the jqGrid from other controller action. Such jqGrid-oriented actions can have prototype like:
JsonResult GetData(string filter, string sidx, string sord, int page, int rows)
I personally prefer to implement this part as WCF service and to have this WCF service as a part of the same ASP.NET site. In general it's much more the matter of taste and depends on your other project requirements.
This part of you ASP.NET site could implement users authentication which you need and can be tested with unit tests exactly like other actions of your controllers.
The views of the ASP.NET MVC site can have empty data for jqGrids, and have only correct URLs and probably generate the HTML code depends on the users permission in the site. Every page will fill the data of jqGrids with respect of the corresponds requests to the server (request to the corresponding GetData action).
You can use HTTP GET for the data for the best data caching. The caching of data is the subject of a separate discussion. If you do this, you should use prmNames: { nd:null } in the definition of jqGrid to remove unique nd parameter with the timestamp added per default to every GET request. To have full control of the data caching on the server side you can for example add in HTTP headers of the server responses both "Cache-Control" set to "max-age=0" and "ETag" header with the value calculated based of the data returned in the response. You should test whether the request from the client has "If-None-Match" HTTP header with the value of "ETag" coresponds the data cached on the client. Then you should verify whether the current data on the server (in the database) are changed and, if there are not changed, generate a response with an empty body (set SuppressEntityBody to true) and return "304 Not Modified" status code (HttpStatusCode.NotModified) instead of default "200 OK". A more detail explanation is much more longer.
If you don't want optimize you site for caching of HTTP GET data for jqGrids you can either use HTTP POST or don't use prmNames: { nd:null } parameter.
The code inside of JsonResult GetData(string filter, string sidx, string sord, int page, int rows) is not very short of cause. You should deserialise JSON data from the filter string and then construct the request to the data model depends on the method of the data access which you use (LINQ to SQL, Entity Model or SqlCommand with SqlDataReader). Because you have this part already implemented it has no sense to discuss this part.
Probably the main part of my suggestion is the usage of clear separation of controller actions which provide the data for all your jqGrids and the usage of MVC views with empty data (having only <table id="list"></table><div id="pager"></div>). You should also has no doubt with having a relative long code for analyzing of filters which come from the Advance Searching feature of the jqGrid and generating or the corresponding requests to your data model. Just implement it one time. In my implementation the code in also relatively complex, but it is already written one time, it works and it can be used for all new jqGrids.
I made this once, very simple.
pseudo code:
Controller
[HttpGet]
public ActionResult getList(int? id){
return PartialView("Index", new ListViewModel(id??0))
}
ViewModel
public class ListViewModel{
//ObjectAmountPerPage is the amount of object you want per page, you can modify this as //parameter so the user
//can choose the amount
public int ObjectAmountPerPage = 20 //you can make this into a variable of any sort, db/configfile/parameter
public List<YourObjectName> ObjectList;
public int CurrentPage;
public ListViewModel(id){
Currentpage = id;
using (MyDataContext db = new MyDataContext()){
ObjectList = db.YourObjectName.OrderBy(object=>object.somefield).getListFromStartIndexToEndIndex(id*ObjectAmountPerPage ,(id*ObjectAmountPerPage) +20).toList();
}
}
}
Now Create A RenderPartial:
PartialView
<#page inherit="IEnumerable<ListViewMode>">
<%foreach(YourObjectName object in Model.ObjectList){%>
Create a table with your fields
<%}%>
And create a view that implements your Jquery, other components+your partialView
View
<javascript>
$(function(){
$("#nextpage").click(function(){
(/controller/getlist/$("#nextpage").val(),function(data){$("#yourlist").html = data});
});
});
</javascript>
<div id="yourlist">
<%=Html.RenderPartial("YourPartialView", new ListViewModel())%>
</div>
<something id="nextpage" value"<%=Model.CurentPage+1%>">next page</something>
I hope this helps, this is according to the MVC- mv-mv-c principle ;)
Model-View -(modelview) - control