I've setup a site using http://razor.servicestack.net/.
I've created several views and matching services with an example as follows:
Service Example:
using ServiceStack.ServiceHost;
using ServiceStack.ServiceInterface;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace website
{
[DefaultView("AboutUs")]
public class AboutUsService : Service
{
public object Get(AboutUsRequest request)
{
return new AboutUsResponse
{
//any properties that need to be set on the response object can be done inline here
};
}
}
[Route("/About-Us")]
public class AboutUsRequest
{
//any request parameters we need can be provided here. They should be auto parsed from the request
}
public class AboutUsResponse
{
//any response properties we want to use in the view can be defined here
}
}
View Example (located at /Views/AboutUs.cshtml)
#inherits ServiceStack.Razor.ViewPage<website.AboutUsResponse>
<html><body><h1>About Us</h1></body></html>
This loads fine on windows, but fails to load on Mono/NginxFastCGI, and instead just shows the default API snapshot page:
Snapshot of AboutUsRequest generated by ServiceStack on 11/17/2012 02:30:14
view json datasource from original url: http://dev.mydomain.com:80/About-Us? in other formats: json xml csv jsv
Is there some specific change that I need to configure for this to work on the Mono/Linux side? By the way, i have IOMAP=all already turned on.
Any ideas on how to get this working would be greatly appreciated!
Unfortunately you left out the most important part: the name and location of the Razor view.
The Snaphot page is a fallback for when ServiceStack can't find the view it's looking for, in this case since you've specified [DefaultView("AboutUs")], ServiceStack will look for a view named "AboutUs.cshtml" in the /Views/ directory, is that what you have?
Related
I have a .net core 2.1 solution comprising a web app, an API and a bunch of libraries.
I am trying to post JSON into a controller in the web project and it is not working - it appears that the properties that I am setting in the JSON are just being set to their default values.
I have tried with and without the [FromBody] attribute and had no luck either way.
This is what I have in the controller
[HttpPost]
public async Task<JsonResult> Search([FromBody] int test)
{
Json(new
{
IThinkYouPassed=test,
});
}
Nothing out of the ordinary there.
I am posting to this using PostMan with the following body :
{
"test":"234"
}
If i put a breakpoint in the action and hit it and I can see that the value of test is 0.
I don't have this issue with the actions in the API project so there must be something missing from the web project - some setup that needs to be done in order for this to work?
I get the same result when using jquery to post the data so Im fairly sure that the issue is with the web app rather than something I am missing in postman.
I thought that maybe the InputFormatter might not be specified but Im told that should happen automatically as part of the UseMVC extension?
Any help with this appreciated.
Your json is an object that contains the test field. You should change
public async Task<JsonResult> Search([FromBody] int test)
to
public async Task<JsonResult> Search([FromBody] TestDto testDto)
where TestDto.cs contains the test field
public class TestDto {
public int Test { get; set; }
}
I'm getting some json data using Flurl (function below). My problem is that this returns the expected fields but not the actual data:
The json is at: https://jsonplaceholder.typicode.com/users
The exact same function worked fine in a separate standalone test app that did not use Microsoft.AspNetCore.Mvc.
Any ideas why it would return the fields but not the data? Thanks.
using System;
using Test.API.Constants;
using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;
using Flurl.Http;
namespace Test.API.Controllers
{
public class TestController
{
[Route(ApiControllerRoutes.Test.test)]
[HttpGet]
public async Task<dynamic> GetAsync()
{
try
{
string url = "https://jsonplaceholder.typicode.com/users";
return await url.GetJsonListAsync();
}
catch (Exception e)
{
}
}
}
}
GetJsonListAsync (without a generic argument) returns Task<IList<dynamic>>, so the easiest fix is to use the same return type from your controller, instead of Task<dynamic>.
If you want this to be a bit more robust and type-safe, I would skip dynamics altogether and create a User class, then use GetJsonListAsync<User>() and return Task<IList<User>> in your controller. I see there's nested objects involved so you'd actually need several classes to represent the whole structure. json2csharp is a great tool to assist with this. Just paste in JSON represention of a single user (not the whole list) and it'll generate everything for you.
I am currently using Spring and AngularJS.
So far no problem displaying my index.html using Spring like so
#RequestMapping(value="/")
public String index() {
return "/app/index.html";
}
Is there any way I can get my context path in my .html? Or should I render my index as index.jsp?
As you said, you should render it as a JSP in order to access the contextpath:
${pageContext.request.contextPath}
If you wanna stick to pure HTML maybe you could extract it from the URL with Javascript:
function getContextPath() {
return window.location.pathname.substring(0, window.location.pathname.indexOf("/",2));
}
console.log(getContextPath());
I'm trying out building a web API with MVC 6. But when one of my controller methods throws an error, the content of the response is a really nicely formatted HTML page that would be very informative were this an MVC app. But since this is an API, I'd rather have some JSON returned instead.
Note: My setup is super basic right now, just setting:
app.UseStaticFiles();
app.UseIdentity();
// Add MVC to the request pipeline.
app.UseMvc();
I want to set this up universally. Is there a "right/best" way to set this up in MVC 6 for an API?
Thanks...
One way to achieve your scenario is to write an ExceptionFilter and in that capture the necessary details and set the Result to be a JsonResult.
// Here I am creating an attribute so that you can use it on specific controllers/actions if you want to.
public class CustomExceptionFilterAttribute : ExceptionFilterAttribute
{
public override void OnException(ExceptionContext context)
{
var exception = context.Exception;
context.Result = new JsonResult(/*Your POCO type having necessary details*/)
{
StatusCode = (int)HttpStatusCode.InternalServerError
};
}
}
You can add this exception filter to be applicable to all controllers.
Example:
app.UseServices(services =>
{
services.AddMvc();
services.Configure<MvcOptions>(options =>
{
options.Filters.Add(new CustomExceptionFilterAttribute());
});
.....
}
Note that this solution does not cover all scenarios...for example, when an exception is thrown while writing the response by a formatter.
I have data in my apicontroller in following way-
public class OutletPOCController : ApiController
{
OutletPOCContext db = new OutletPOCContext();
[System.Web.Http.ActionName("GetTabText")]
public TabTextModel GetTabText(int bizId)
{
var outlet = db.Info.Where(t => t.BizId == bizId).SingleOrDefault();
return new TabTextModel
{
HomeTab = outlet.BizHomeTabText,
AboutTab = outlet.BizAboutTabText,
TimingsTab = outlet.BizTimingsTabText,
};
}
And now i want to retrieve this data into my view. How shall i create view for this controller and pass the above data? What will be my action method? I am new to webapi and json. Any help is appreciable! Thanks in advance!
The API controller dosent really have views in the sense that you create a cshtml page that takes care of how you display your data. The purpose of the ApiController is simply to return data in the format that you want to consume it.
Basically the API exposes raw data to the web, you consume it in some way, and then display it..
I use something similar to this to load data dynamically into a web page.
Just a simple web api that returns data to the client.
public class APIController : ApiController
{
[HttpGet]
[HttpPost] // allow both post and get requests
public IEnumerable<String> GetData()
{
return new List<string>() { "test1", "test2" };
}
}
When you browse to the API method above it returns this xml data
<ArrayOfstring xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<string>test1</string>
<string>test2</string>
</ArrayOfstring>
Which I get using Jquery and do what I please with (http://api.jquery.com/jQuery.get/):
$.get("/api/GetData", function(data) {
alert("Data Loaded: " + data);
});
Examples of XML parsing with JS/Jquery:
http://tech.pro/tutorial/877/xml-parsing-with-jquery
http://www.kawa.net/works/js/jkl/parsexml-e.html
If you are simply looking to get data into a regular view and work with it there without going through javascript I wouldent use a webapi, but instead get the data in the controller and send it to the view for displaying (ASP MVC4 - Pass List to view via view model).
You can also check out the ViewBag container for passing random odd data to the view http://goo.gl/03JTR
On the off chance you really do want to render your data in a view, check this out: Web API - Rendering Razor view by default?