You are not logged in.
how can I make a function that I can spend an array parameter as it comes with named parameter. but I have dynamic parameters. each time I call the function with a different number of parameters, do not even know how to do on Delphi or in html.
example:
not
function Login(const LogonName,PlainPassword: RawUTF8): TMVCAction;
yes
function Login(const params: array of RawUTF8): TMVCAction;
not
function CadastroSalvar(const p1, p2, p3, p4: RawUTF8): TMVCAction;
yes
function CadastroSalvar(const p: TObjectList): TMVCAction;
Thanks
Offline
don't
only first param:
function TnWebMVCMenu.CadastroSalvar3(const p: variant): TMVCAction;
begin
GotoView(result,'Cadastro',
['pp1',p])
end;
{"ClassName":"EMVCException","Address":"0B91DB80","Message":"TMVCRendererFromViews.CommandRunMethod: InWebMVCMenu.CadastroSalvar2() execution error","context":"TMVCRendererFromViews.ExecuteCommand"}
function TnWebMVCMenu.CadastroSalvar2(const p: TRawUtf8DynArray): TMVCAction;
begin
GotoView(result,'Cadastro',
['pp1',p[0]])
end;
General
Remote Address:[::1]:8080
Request URL:http://localhost:8080/npmnGem/CadastroSalvar2
Request Method:POST
Status Code:500 Internal Server Error
Response Headers
view source
Accept-Encoding:synlz,gzip
Access-Control-Allow-Origin:
Content-Encoding:gzip
Content-Length:1372
Content-Type:text/html; charset=UTF-8
Date:Tue, 30 Jun 2015 01:15:45 GMT
Server:mORMot/1.18.1563 (Windows) Microsoft-HTTPAPI/2.0
Server-InternalState:0
X-Powered-By:Synopse mORMot 1.18.1563 http://synopse.info
Request Headers
view source
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding:gzip, deflate
Accept-Language:pt-BR,pt;q=0.8,en-US;q=0.6,en;q=0.4
Cache-Control:max-age=0
Connection:keep-alive
Content-Length:20
Content-Type:application/x-www-form-urlencoded
Host:localhost:8080
Origin:http://localhost:8080
Referer:http://localhost:8080/npmnGem/Cadastro?Scope={%22Class%22:%22TnGemDMUsuarioGrupoUsu%22}
User-Agent:Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.130 Safari/537.36
Form Data
view source
view URL encoded
p:1
p:teste 1
p:10.5
Offline
But like putting a json array as value?
<form class="form-horizontal" action="CadastroSalvar2" method="post">
<div class="form-group">
<label for="input1" class="col-sm-2 control-label">ID</label>
<div class="col-sm-3">
<input type="number" class="form-control" id="input1" name="p[1]" placeholder="ID" value="1">
</div>
<div class="col-sm-1">
<input class="btn btn-default" type="button" value="...">
</div>
<div class="col-sm-6">
<input type="number" class="form-control" id="input1" placeholder="ID" value="1">
</div>
</div>
<div class="form-group">
<label for="input2" class="col-sm-2 control-label">Descricao</label>
<div class="col-sm-3">
<input type="text" class="form-control" id="input2" name="p[2]" placeholder="Descricao" value="teste 1">
</div>
<div class="col-sm-1">
<input class="btn btn-default" type="button" value="...">
</div>
<div class="col-sm-6">
<input type="text" class="form-control" id="input2" placeholder="Descricao" value="teste 1">
</div>
</div>
<div class="form-group">
<label for="input3" class="col-sm-2 control-label">Preco</label>
<div class="col-sm-3">
<input type="number" class="form-control" id="input3" name="p[3]" placeholder="Preco" value="10.5">
</div>
<div class="col-sm-1">
<input class="btn btn-default" type="button" value="...">
</div>
<div class="col-sm-6">
<input type="number" class="form-control" id="input3" placeholder="Preco" value="10.5">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-default">Salvar</button>
</div>
</div>
</form>
For
function TnWebMVCMenu.CadastroSalvar2(const p: TRawUtf8DynArray): TMVCAction;
begin
GotoView(result,'Cadastro',
['pp1',p[0],
'pp2',p[0]])
end;
But don´t go
I tried so well.
...
name="p.a1"
...
name="p.a2"
...
name="p.a3"
...
For
function TnWebMVCMenu.CadastroSalvar3(const p: variant): TMVCAction;
begin
GotoView(result,'Cadastro',
['pp1',p.a1,
'pp2',p.a2])
end;
Neither.
Request Payload
p={"a1":1,"a2":"dfasdfa"}
Thus it works for CadastroSalvar3, but I do not know how to do post the form to do so.
Offline
I suppose you may use a JavaScript function?
The onclick event of the button would let JavaScript compute the JSON, then send it at URI, or as POST body to the server.
I did not test it yet, but it should work.
Offline
source original
function TSQLRestServerURIContext.GetInputAsTDocVariant: variant;
var i: integer;
v: variant;
MultiPart: TMultiPartDynArray;
begin
VarClear(result);
FillInput;
if fInput<>nil then begin
with TDocVariantData(result) do begin
InitFast;
for i := 0 to (length(fInput) shr 1)-1 do begin
GetVariantFromJSON(pointer(fInput[i*2+1]),false,v,@JSON_OPTIONS[true]);
AddValue(fInput[i*2],v);
end;
end;
end else
if InputAsMultiPart(MultiPart) then
with TDocVariantData(result) do begin
InitFast;
for i := 0 to high(MultiPart) do
with MultiPart[i] do
if ContentType=TEXT_CONTENT_TYPE then begin
RawUTF8ToVariant(Content,v);
AddValue(Name,v); // append as regular "Name":"TextValue" field
end else // append binary file as an object, with Base64-encoded data
AddValue(Name,_ObjFast(['data',BinToBase64(Content),
'filename',FileName,'contenttype',ContentType]));
end;
end;
changer source
function TSQLRestServerURIContext.GetInputAsTDocVariant: variant;
var i,
APos: integer;
v,
vresult: variant;
MultiPart: TMultiPartDynArray;
AObjectName,
AParName: RawUTF8;
AFoundObject: Boolean;
begin
AObjectName := '';
VarClear(vresult);
FillInput;
if fInput<>nil then begin
AFoundObject := False;
APos := pos('.', fInput[0]);
if (APos > 0) then begin
AObjectName := Copy(fInput[0], 1, APos - 1);
for i := 0 to (length(fInput) shr 1)-1 do begin
AParName := fInput[i*2];
APos := pos('.', AParName);
if (APos > 0) and (AObjectName = Copy(AParName, 1, APos - 1)) then begin
AFoundObject := True;
end else begin
AFoundObject := False;
continue;
end;
end;
end;
with TDocVariantData(vresult) do begin
InitFast;
for i := 0 to (length(fInput) shr 1)-1 do begin
GetVariantFromJSON(pointer(fInput[i*2+1]),false,v,@JSON_OPTIONS[true]);
AParName := fInput[i*2];
if AFoundObject then
AParName := Copy(AParName, APos + 1, MaxInt);
AddValue(AParName,v);
end;
end;
end else
if InputAsMultiPart(MultiPart) then
with TDocVariantData(vresult) do begin
InitFast;
for i := 0 to high(MultiPart) do
with MultiPart[i] do
if ContentType=TEXT_CONTENT_TYPE then begin
RawUTF8ToVariant(Content,v);
AddValue(Name,v); // append as regular "Name":"TextValue" field
end else // append binary file as an object, with Base64-encoded data
AddValue(Name,_ObjFast(['data',BinToBase64(Content),
'filename',FileName,'contenttype',ContentType]));
end;
if AFoundObject then begin
VarClear(result);
with TDocVariantData(result) do begin
InitFast;
AddValue(AObjectName,vresult);
end;
end else
result := vresult;
end;
input
p.a1=5&p.a2=dfasdfa
before change
{"p.a1":5,"p.a2":"dfasdfa"}
after change
{"p":{"a1":5,"a2":"dfasdfa"}}
sorry the few sources thought, but I'm in a hurry.
it can be better and integer, or change to a different concept, provided it is nome.property
this works with this sources
function TnWebMVCMenu.CadastroSalvar3(const p: variant): TMVCAction;
begin
GotoView(result,'Cadastro',
['pp1',p.a1,
'pp2',p.a2])
end;
Offline
I've implement this feature, which sound in fact handy.
See http://synopse.info/fossil/info/c6dad25635
It follows another pattern, dedicated to MVC (I did not want to change the default TSQLRestServerURIContext behavior).
The associated updated documentation:
If you want to support a variable number of named parameters, you can define a variant input parameter, and provide the input as a JSON document, using a TDocVariant storage. But marshalling the context as JSON would involve using some JavaScript in the HTML page, which may not be very convenient.
If you want to handle a non-fixed set of regular URI or POST value, you can prefix all the incoming parameter names with the dotted name of a single defined variant.
For instance, if you have the following controller method:
function TnWebMVCMenu.CadastroSalvar3(const p: variant): TMVCAction;
Then you can supply as parameter at URI level:
p.a1=5&p.a2=dfasdfa
And you would be able to handle them in the controller body:
function TnWebMVCMenu.CadastroSalvar3(const p: variant): TMVCAction;
begin
GotoView(result,'Cadastro',
['pp1',p.a1,
'pp2',p.a2])
end;
You are now free to specify some versatile HTML forms in your views, and provide the controller with any kind of input parameters.
Of course, it may sound safer and easier to explicitly define and name each one of the input parameters, with simple types like integer or RawUTF8. But this convention may help you work with any kind of HTML views.
Thanks for the feedback!
Offline
Thank you, it was show.
Offline