In a Nancy .Net REST web-service I need to be able to specify a custom xmlns:xsd for the root element of the xml-tree that is produced when I use the code below - is this possible?:
public class RequestModule : NancyModule
{
Get["/books"] = parameters =>
{
return Response.AsXml(List<Book>);
};
}
Calling /books using the code above produces output similar to...
<ArrayOfBook
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Book>
...
</Book>
...
</ArrayOfBook>
Does Nancy provide the possibilty of changing the values of xmlns:xsd to some custom schema url? So I would get something like...
<ArrayOfBook
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://myschemaurl.com/2007/MyCustomXMLSchema">
<Book>
...
</Book>
...
</ArrayOfBook>
If the above is not possible with Nancy out of the box, could someone point me to the location in the Nancy framework source code where I could change code to achieve my goal?
Response.AsXml is just a fancy helper to return XML. You can return a Response object on your own and set the ContentType and Content to what ever content you want. Use what ever serializer you want and just stick it in a response and off you go
If you want to use Response.AsXml then you should look at implementing an ISerializer and registering it in the Bootstrapper -> InternalConfiguration => Serializers. Response.AsXml will use the first ISerializer that say it can handle the xml media type
Related
I am using Laravel 5.4. I want to use query string like below:
tempsite.com/lessons?id=23
For getting this how routes are to be modified. It is possible to give route in the following way.
Route::get('lessons/id={id}', ['as' => 'lessons.index', 'uses' => 'Lessons\LessonController#index']);
But adding '?' is not getting for me. Please help us to provide a solution as early as possible.
If you are using resourceful controllers, your routes are all handled for you so you would simply put
Route::resource('lessons', 'Lessons\LessonController');
You can then use route model binding to bind the model instance which matches that particular ID.
Route::model('lesson', Lesson::class);
This would be done in your RouteServiceProvider.
I would also suggest having a good read of the following documentation on the laravel website https://laravel.com/docs/5.4/routing. It provides really good insight in to how routes work and how they should be structured.
Instead of tempsite.com/lessons?id=23
Pass it like this tempsite.com/lessons/23
and in the route
Route::get('lessons/{id}', ['as' => 'lessons.index', 'uses' => 'Lessons\LessonController#index']);
to get the id in your controller, write your function like this
public function index($id)
{
//do anything with $id from here
}
There is no need to define query string parameters in your routes. You can return query string parameters in your controller like so:
URL example: tempsite.com/lessons?id=23
public function lessons(Request $request)
{
$request->get('id'); // Using injection
Request::get('id'); // Using the request facade
request()->get('id'); // Using the helper function
}
You could even validate the parameter:
public function lessons(Request $request)
{
$this->validate($request, ['id' => 'required|integer']);
}
Note: If you want to make the URL not accessible if the ID is omitted, see #DarkseidNG answer.
I was able to inform laravel to accept query stringed requests on my route by affixing the url with a forward slash, like so
// web.php
Route::get('/path/', "Controller#action");
With the above, mysite/path?foo=bar&name=john does not throw 404 errors.
How can I call a ASP .NET web service and pass parameters using the URL?
For example, the URL for the service is like,
http://[localhost]:31856/MySystem/MyAPI.asmx?op=getHeight
I need to pass two parameters a and b, I tried
http://[localhost]:31856/MySystem/MyAPI.asmx?op=getHeight?a=254&b=1
But failed.
Please advice.
Many Thanks,
If you need to pass more than one parameter, use this format param1=value1¶m2=value2 and so on.So your link should be:
http://[localhost]:31856/MySystem/MyAPI.asmx/AnyMethodName?op=getHeight&a=254&b=1
You need a method like this.This method returns a list of strings,its just for demonstration.
[WebMethod]
public List<string> AnyMethodName(string op, string a, string b)
{
//Do whatever you want, get answer
return (ans.ToList());
}
I had the same problem and I needed to add the following in my webconfig inside the system.web -tag:
<webServices>
<protocols>
<add name="HttpGet" />
</protocols>
</webServices>
The rest was pretty much like already mentioned (using the example from Ashwin's answer, just removed the op-parameter)
[WebMethod]
public List<string> AnyMethodName(string a, string b)
{
//Do whatever you want, get answer
return (ans.ToList());
}
After that I was able to call the webservice with the following (removed the op-parameter again):
http://localhost/MySystem/MyAPI.asmx/AnyMethodName?a=254&b=1
Change the second ? to &. If you look at the page rendered by http://[localhost]:31856/MySystem/MyAPI.asmx, it will show you how to call it as an HTTP GET.
It's not like that.
You have to declare the parameters in function.
For example here is a little example:
[WebMethod]
public string[] getVariables(string sop, string sgsm)
{ // do what you want ... }
Then when you call it
WebReference.Service1 service = new WebReference.Service1();
service.getVariables("foo", "blabla");
Follow Below Steps
Step 1: Click on Add Service Reference and add reference of service .
It creates reference in a partial class to the service and all the methods which you need to call the service under the project namespace.
Step 2: Add the same class in using ..
Step 3: Browse the class file generated under the service reference and get the name of it .
Step 4: Create a client like new Service1SoapClient("Service1Soap"); and then use the service as Method . You can pass the parameter (if requires) like the way you pass while calling one method from another .
I've got a two classes (pupil, class) in a Roo-project and their scaffolded views.
pupil and class have a 1:1 relationship
In the list.jspx of pupil I'd like to display a column for a property of class.
I don't know the correct attributes to give to the table:column-tag.
This following example gives the error:
SpelEvaluationException: EL1027Epos 4): Indexing into type 'com.pupil' is not supported
<table:table data="${pupil}" duplicate="true" id="l_com_pupil" path="/admin/pupil" z="user-managed">
<table:column id="c_com_pupil_pupilName" property="pupilName" z="user-managed"/>
<!-- I'd like to display the attribute teacher_name of the class 'class' here but it doesn't work -->
<table:column id="c_com_pupil_class_teacherName" property="teacherName" z="user-managed"/>
</table:table>
Instead of messing around with the jspx files, you can simply do this by implementing a converter for the Teacher entity within the ApplicationServiceFactoryBean.java.
See the below conversion method for an example.
static class com.mycompany.test.controllers.ApplicationConversionServiceFactoryBean.TeacherConverter implements org.springframework.core.convert.converter.Converter<com.mycompany.test.domain.master.Teacher, java.lang.String> {
public String convert(Teacher teacher) {
return new StringBuilder().append(teacher.getName()).toString();
}
}
By default, Roo generates these converters and they are stored within the ApplicationConversionServiceFactoryBean_Roo_ConversionService.aj file.
You can push in refactor the related method for the Teacher entity from this aspectJ file into the
ApplicationServiceFactoryBean.java file and then implement your own conversion which will be used to show the Teacher name across the application as in the above example.
Cheers and all the best with Roo!
This is how I did it, not for listing, but rather for showing the name of the teacher when you view the pupil entity:
Edit the controller and specifically the method show (in the java file, not in the aj file, of course).
Add an attribute to your UI Model, for instance "teacherName" (use Model.addAttribute), where you populate the teacherName with the desired name.
Add in the show.jspx file something like:
<div><label for="_pupilTeacher">Teacher Name:</label><div class="box">${teacherName}</div></div><br/>
(alternatively, you could create a new tagx file with your own parameters)
Hope it helped.
Radu
I want an asmx webservice with a method GetPeople() that returns the following XML (NOT a SOAP response):
<People>
<Person>
<FirstName>Sara</FirstName>
<LastName>Smith</LastName>
</Person>
<Person>
<FirstName>Bill</FirstName>
<LastName>Wilson</LastName>
</Person>
</People>
How can I do this?
Look at using the [ScriptMethod] attribute.
If you don't want the Response to be in a SOAP envelope, are you also not bothered about calling the web service using SOAP. e.g. you are not creating proxy classes web references etc and just using http post or get to call the web service?
If so rather than writing a web service, write a ASHX handler file. You can then simply set the Response.ContentType to text/xml and do Response.Write(XmlDocument.ToString()). That will return pure unadulaterated XML plus the relevent http headers.
I see I can set the return type of the method to XmlDocument. This seems to work.
[WebMethod]
public XmlDocument ReturnXml()
{
XmlDocument dom = new XmlDocument();
XmlElement people = dom.CreateElement("People");
dom.AppendChild(people);
XmlElement person = dom.CreateElement("Person");
people.AppendChild(person);
XmlElement firstName = dom.CreateElement("FirstName");
person.AppendChild(firstName);
XmlText text = dom.CreateTextNode("Bob");
firstName.AppendChild(text);
// load some XML ...
return dom;
}
You may use Soap Extensions to create / customize for your needs.
Does anyone have any suggestions (or a regular expression) for parsing the HTTP Accept header?
I am trying to do some content-type negotiation in ASP.NET MVC. There doesn't seem to be a built in way (which is fine, because there are a lot of schools of thought here), but the parsing is not entirely trivial and I would rather not re-invent the wheel if someone has already done it well and is willing to share.
Have you seen this article? It gives a pretty comprehensive implementation for parsing the Accept header and subsequently doing something useful with it.
As of .NET 4.5 (I thinkâMicrosoft have made info on framework versions < 4.5 rather obscure these days), you can use one of the the built in parsers from System.Net.Http.Headers:
public IOrderedEnumerable<MediaTypeWithQualityHeaderValue> GetMediaTypes(string headerValue) =>
headerValue?.Split(',')
.Select(MediaTypeWithQualityHeaderValue.Parse)
.OrderByDescending(mt => mt.Quality.GetValueOrDefault(1));
Then you can do something like this:
var headerValue = "application/json, text/javascript, */*; q=0.01";
var mediaTypes = GetMediaTypes(headerValue);
Giving you a nice list of all the media types, where the preferred option is the first item. Here's a LINQPad Dump of the mediaTypes result from the example:
Hat tip to this answer, for getting me on the right track.
I've written a parser in PHP. It's not complex, but it will give you an array of mime types in order of preference.
Found another implementation in php here
After reading the xml.com article I decided to not write a function for the Accept header myself ;)
Fortunately the article points to a good library: https://code.google.com/p/mimeparse/ - in my case I need it as a Node.js module: https://github.com/kriskowal/mimeparse
Building on https://stackoverflow.com/a/49011308/275501 from https://stackoverflow.com/users/43140/mark-bell above:
public class MyController : Controller
{
[HttpGet]
[Route("/test")]
public ActionResult Index() {
// does this request accept HTML?
var acceptsHTML = IsAcceptable("text/html");
var model = FetchViewModel();
return acceptsHTML ? (ActionResult) View(model) : Ok(model);
}
private bool IsAcceptable(string mediaType) =>
Request.Headers["Accept"].Any(headerValue =>
!string.IsNullOrWhiteSpace(headerValue) &&
headerValue.Split(",").Any(segment => MediaTypeHeaderValue.Parse(segment).MediaType == mediaType));
private object FetchViewModel() {
return new { Description = "To be completed" };
}
}
The RFC is quite complex. If the regex where to follow these rules to the letter, it would become several lines long.
If you already have the Accept-header, and ignore the quotes and the parameters, you could do something like this to match each pair:
/([^()<>#,;:\\"\/[\]?={} \t]+)\/([^()<>#,;:\\"\/[\]?={} \t]+)/
* is included in the character class, so it does not need any special case in the regex.