How to pass value to a [FormBody] variable from RestAssured? - content-type

I have a web api method as given below
// POST api/values
public void Post([FromBody] string value)
{
names = names.Concat( new string[] { value } ).ToArray();
}
I would like to pass value to a "value" variable from RestAssured, I tried with the following RestAssured code and it did not work ( value is not getting passed)
request.contentType(ContentType.JSON);
JSONObject jsonobj = new JSONObject();
jsonobj.put("value",new String("test45#test.com"));
request.body(jsonobj.toString());
// Get Response and verify the status code
Response response = restAssuredManager.getAPIResponse(request, "Api/Values",RequestPostType.Post);
It is observed that the value "test45#test.com" is not getting binded with the "value" variable in Post method. however I could send the value from Postmain tool ( selected content-type as json and provided "rajkumar" as value in "raw" tab)
I was expecting the value to be passed from RestAssured code.

Related

Query string parameter vs regular parameter ASP.Net MVC 5

I have been working on desktop applications mostly and thought to learn web development using ASP.Net MVC5 and thus going through the book by Jon Galloway. So I was reading about how you can pass the parameters to action methods using query string like
/Store/Browse?genre=Disco
or directly embed them in the url like
/Store/Details/5
Now the controller code that I wrote (taken from book) is below :
namespace MvcMusicStore.Controllers
{
public class StoreController : Controller
{
// GET: Store
public string Index()
{
return "Hello from Store.Index()";
}
public string Browse(string genre)
{
string message = HttpUtility.HtmlEncode("Store.Browser, Genre = " + genre);
return message;
}
public string Details(int id)
{
string message = "Store.Details, ID = " + id;
return message;
}
}
}
The url opens fine and the actions return the message as expected. But just to try I tried to pass the genre value by embedding it in the url like
/Store/Browse/Rap
but that doesn't work like it did for the Details() action. I thought it may have to do something with the datatype of genre, so I tried changing the data type of id in Details() to string as below :
public string Details(string id)
{
string message = "Store.Details, ID = " + id;
return message;
}
}
and opened the url
/Store/Details/5
and the Details() action returns message with id value 5, but when i do the same for Browse() action
/Store/Browse/Rap
the action doesn't return the message with genre value "Rap". I tried to pass the genre value and removed the html encoding to see if that had anything to do with it, but it didn't.
I looked at the post here but that didn't help either. Any comments appreciated.
Your using the Default route which is defined as
url: "{controller}/{action}/{id}",
and expects a value for id. When you use /Store/Browse/Rap, then the value of the 3rd segment ("Rap") will be bound to a paramater named id, but your Browse() method does not contain one (its named genre).
Either change the name of the parameter so its
public string Browse(string id)
and the value of id will be "Rap",
Or create a specific route definition and place it before the Default route (and keep the Browse() method as is)
routes.MapRoute(
name: "Browse",
url: "Store/Browse/{genre}",
defaults: new { controller = "Store", action = "Browse", genre = UrlParameter.Optional }
);
... // default route here
Side note: You do not need to change the type of the parameter in the Details method if your always passing a value that is a valid int

Send object as parameter in client.PutAsync

I am facing a problem in using PutAsync. PutAsync update an object. Below is my code. (Mongodb database)
Controller Code:
stringData = JsonConvert.SerializeObject(businessUnit); //businessUnit is updated object
var contentData = new StringContent(stringData, System.Text.Encoding.UTF8, "application/json");
response = client.PutAsync(baseAddress + "/api/BusinessUnit/" + businessUnit.Id, contentData).Result;
API Controller Code :
[HttpPut("{id}")]
public async Task<string> Put(string id, BusinessUnit businessUnit)
{
if (string.IsNullOrEmpty(id)) return "Invalid id !!!";
return await _businessUnitRepository.Update(id, businessUnit);
}
Given code works good but my problem is in API controller businessUnit parameter's all fields become null instead of id.
My Confusion is, if businessUnit parameter's all fields are null then why its primary key "id" is not null ??
I want to get all fields as parameter in businessUnit object from controller to api controller. How can I do it?
Thanks in advance.
Add the [FromBody] attribute to the 'businessUnit' parameter:
public async Task<string> Put(string id, [FromBody] BusinessUnit businessUnit)
This is called an Model Binding and allows to map data from HTTP requests to action method parameters:
[FromBody]: Use the configured formatters to bind data from the request body. The formatter is selected based on content type of the request.

How to Store A Json Array or Json Object in mysql using Spring And Mybatis

Controller.java
#RequestMapping(value = { ControllerUriConstant.add }, method = RequestMethod.POST)
#ActivityMapping(activity = ActivityEnum.ADD)
public String addActivities(#ModelAttribute("activityForm") ActivityForm activityForm, BindingResult bindingResult, Model model,
HttpServletRequest request) throws Exception {
new ActivityFormValidator().validate(activityForm, bindingResult, request.getLocale(), getMessageSource(), null, activityService);
if (bindingResult.hasErrors()) {
model.addAttribute(Constants.ACTIVITY_FORM,activityForm );
model.addAttribute(Constants.HAS_ERROR, Boolean.TRUE);
model.addAttribute("add", true);
model.addAttribute(Constants.ERROR_MESSAGE, getMessageSource().getMessage("ulearn.messages.add.failed", activityForm.getName()));
return "activityform";
} else {
model.addAttribute(Constants.SUCCESS_MESSAGE, getMessageSource().getMessage("ulearn.messages.add.success", activityForm.getName()));
JSONArray address =new JSONArray();
JSONObject jo = new JSONObject();
jo.put("id", "1");
jo.put("name","Test");
JSONObject jo1= new JSONObject();
jo1.put("id", "1");
jo1.put("name", "Test2");
JSONObject jo2= new JSONObject();
jo2.put("id", "1");
jo2.put("name", "Test3");
address.add(jo);
address.add(jo1);
address.add(jo2);
activityForm.setInsertJsonMysql(address);
activityService.add(activityForm);
}
return getActivities( model, request);
}
Service.java
public void add(ActivityForm activityForm) throws TechnoShineException {
try {
Activity activity = new Activity();
activity.setName(activityForm.getName());
activity.setActive(activityForm.getActive());
activity.setInsertJsonMysql(activityForm.getInsertJsonMysql());
activityDAO.getMapper().insert(activity);
logAudit(getAuditableList(activity, null), getMessageSource().getMessage("ulearn.messages.add.success", activity.getName()), 0, ActivityEnum.ADD);
} catch (Exception e) {
throw new TechnoShineException(e, ActivityService.class);
}
}
Mapper.xml
<insert id="insert" parameterType="com.technoshinelabs.ulearn.persistance.bean.controlpanel.Activity">
INSERT INTO activity (activity_name,is_active,json_array)
VALUES (#{name},#{active},#{insertJsonMysql})
</insert>
// Finally got this error error Caused by: java.lang.IllegalStateException: Type handler was null on parameter mapping for property 'insertJsonMysql'. It was either not specified and/or could not be found for the javaType / jdbcType combination specified.
[1]: https://i.stack.imgur.com/OeZeR.png
I suppose what you want to store is the actual JSON and the MySQL table column json_array is of type VARCHAR or TEXT.
JSONArray is actually but an utility class used to build the JSON.
Then you shall change the type of property insertJsonMysql of class Activity to String and set it to the String representation of the JSONArray.
activity.setInsertJsonMysql(activityForm.getInsertJsonMysql().toString());
EDIT: about inserting into enum column.
According to MySQL 5.7 Reference Manual, I would say you insert into enum typed column the same way you insert any String, the DB will check provided value against list of values declared in CREATE TABLE.
But according to the code sample you provide, the value for insertJsonMysql will be:
[{"id":"1","name":"Test1"},{"id":"1","name":"Test2"},{"id":"1","name":"Test3"}]
that means one of the enum values would have to be this exact string.
However, I feel like that's not what you expect. Maybe using a SET typed column is a closer answer.

Unable to call web api PUT method

[System.Web.Http.Route("{id}")]
[System.Web.Http.HttpPut]
public async Task<ComplaintVM> Put(int id,int? employeeId)
{
var obj = _resolver.GetService<Complaint>();
obj.FranchiseId = 1;
obj.Id = id;
await obj.GetDetailAsyc();
obj.EmployeeId = employeeId;
await obj.AllocateAndManageCallAsyc();
return obj.EntityToVM();
}
This is put method with [System.Web.Http.RoutePrefix("api/app/complaint")]
so when i call my method with a PUT request i get the following error "message: "The requested resource does not support http method 'PUT'.".
but when i make the same call when the method does not have int? employeeId parameter. The call happens fine.
I am passing the employeeId as a json formatted request. I am using fiddler to test the code
The issue with Put(int id,int? employeeId) is the variable int? employeeId, since it was not part of the URL the model binder was not able to bind the attribute and hence was not able call the method with 2 parameters.
Using the [FormBody] did not work, the value returned was null, this is because the input was in form of a json.
The issue was solved by using a parameter of type Employee which had a property of EmployeeId so the value was mapped to the EmployeeId of the employee object, the method signature is Put(int id,Employee employee),
if there is no model class to bind, a parameter of type JObject can used as a input parameter and later the value can be extracted from JObject.

modify HTTP request URI and HTTP request method with a CXF interceptor

I want to modify HTTP request URI and HTTP request method using a CXF interceptor in a HTTP client.
I have developed something like this:
public class MyInterceptor extends AbstractPhaseInterceptor<Message> {
public MyInterceptor() {
super(Phase.PRE_PROTOCOL);
}
public void handleMessage(Message message) {
// this returns me correct path and method
// String path = (String) message.getExchange().getOutMessage().get(Message.REQUEST_URI);
// String method = (String) message.getExchange().getOutMessage().get(Message.HTTP_REQUEST_METHOD);
// this does not work as expected
String path = (String) message.get(Message.REQUEST_URI);
String method = (String) message.get(Message.HTTP_REQUEST_METHOD);
// do things here
}
}
Why do need I to use exchange/OutMessage to obtain data about current message and I can not use message directly?
How can I edit both values? I tried using message.put(<key>, <value>) and the same with exchange/OutMessage, but nothing is modified.
Coming to the path, you'd always get that value as null, I believe.
You can try following code, to get the actual value of your uri:
String requestURI = (String) message.get(Message.class.getName() + ".REQUEST_URI");

Resources