We're happy to announce that after months of intense development, v4-beta of ServiceStack has finally been released to NuGet!
As announced in August to ensure it's continued development, ServiceStack has moved to a self-sustaining commercial model for commercial usage of ServiceStack from v4+ onwards. It's the first time we've been able to commit full-time resources to the project and is what has ensured continued investment and enabled v4 to be possible, with even more exciting features in the pipeline and roadmap for 2014.
Free Usage for Small and OSS Projects​
We're also happy to announce that v4 includes free quotas allowing the free usage of all of ServiceStack for small projects and evaluation purposes. Whilst OSS projects are able to use the source code on GitHub under the AGPL/FOSS License Exception, and the older v3 of ServiceStack continues to be available under the BSD license.
Upgrading from v3​
Whilst we recommend starting with v4 for greenfield projects, v4 has seen significant changes since v3 that will require some development effort to upgrade. During the upgrade we recommend using a tool like ReSharper to be able to easily find and update reference of any types that have moved.
What's new in v4​
The major version upgrade of ServiceStack to v4 has provided us a long sought breaking window opportunity allowing us to re-factor, simplify, clean-up and fix all the warts and cruft that has been lingering in the ServiceStack code-base since its beginning - that due to backwards compatibility we were reluctant to remove. Whilst v4 has seen significant changes to the code-base, all existing tests are passing again with additional tests added for new functionality.
We managed to retain a lot of the user-facing API's (E.g New API, AppHost, Config) which were already considered ideal so ideally upgrading shouldn't be too disruptive in the normal use-cases.
v4 provides us a great foundation to build on that will be further improved during the beta by focusing on stability and fixing any reported issues as well as updating existing documentation to match v4's implementation and publish new examples showcasing v4's new features.
The big refactor of v4​
This was the biggest re-factor in ServiceStack's history which at the end resulted in a much leaner, simplified, consistent and internal logically-structured code-base that's much easier to reason about, where even before adding any features the main ServiceStack repository saw:
1,192 changed files with 18,325 additions and 29,505 deletions.
The number of deletions is indicative of how much legacy code was able to be removed, with much of the internals having been heavily restructured. Some of the highlights during the re-factor include:
- All projects have been upgraded to .NET 4.0, except ServiceStack.Razor which is .NET 4.5 to use the latest version of Razor
- All obsolete/unused/shims/duplicate functionality and built-up cruft has now been removed (inc. the Old Api).
- State and configuration are now cohesively organized where now all AppHost's share the same
ServiceStackHost
base class which now maintains all state in ServiceStack, inc. the emptyBasicAppHost
that's used for unit testing which now shares much of the same state/context as Integration tests. - Many namespaces and some concepts have been collapsed (e.g 'Endpoint'), resulting in ServiceStack projects requiring fewer namespaces
- All DTO's and extension methods and common user-facing classes have been moved to the base
ServiceStack
namespace - allowing them to be much easier to find. - Re-organization of projects, NuGet packages now map 1:1 with ServiceStack projects for finer-grained control of dependencies:
- ServiceStack.Interfaces NuGet project created and ServiceInterface has been merged into ServiceStack
- ServiceStack NuGet package now only depends ServiceStack.Common and ServiceStack.Client
- A new ServiceStack.Server project exists for functionality requiring dependencies on OrmLite or Redis, inc. RedisMqServer and OrmLiteAuthRepository.
- ServiceStack.Client contains all the HTTP, SOAP and MQ Service Clients that have been split from ServiceStack.Common and only depends on ServiceStack.Interfaces and ServiceStack.Text (making it easier to maintain custom builds in future).
- EndpointHostConfig is now
HostConfig
and is limited to just Configuration, e.g. handlers likeCustomErrorHttpHandlers
,RawHttpHandlers
,GlobalHtmlErrorHttpHandler
have been moved to ServiceStackHost. - EndpointHost is gone and replaced by the static
HostContext
class which doesn't contain any state itself, it's just a static convenience wrapper aroundServiceStackHost.Instance
(where all state is maintained). - Removed all 'where T:' constraints where possible
- Removed
ConfigurationResourceManager
, useAppSettings
instead - The
ServiceStack.WebHost.Endpoints.ServiceStackHttpHandlerFactory
used in Web.config's handler mapping has been renamed to justServiceStack.HttpHandlerFactory
Config.ServiceStackHandlerFactoryPath
has been renamed toConfig.HandlerFactoryPath
.- Predefined routes have been renamed from
/syncreply
,/asynconeway
to just/reply
,/oneway
- ServiceManager has been merged into
ServiceController
. - The ServiceStack.Logging and ServiceStack.Contrib v4 projects have been merged into the major ServiceStack repo.
- The dynamic session
base.Session
has been renamed tobase.SessionBag
to better reflect its semantics. - The Auto Mapping Utils extension methods were renamed from
TFrom.TranslateTo<T>()
toTFrom.ConvertTo<T>()
. - The
RequestFilters
andResponseFilters
were renamed toGlobalRequestFilters
andGlobalResponseFilters
which matches naming in the clientServiceClientBase.GlobalRequestFilter
. - New
GlobalMessageRequestFilters
andGlobalMessageResponseFilters
have been added which are instead used by non-HTTP endpoints use, e.g. MQ. CustomHttpHandlers
has been renamed toCustomErrorHttpHandlers
- The LocalHttpWebRequestFilter and LocalHttpWebResponseFilter in the Service Clients were renamed to just
RequestFilter
andResponseFilter
- The Global HttpWebRequestFilter and HttpWebResponseFilter filters were also renamed to
GlobalRequestFilter
andGlobalResponseFilter
respectively.
RequestContext now merged into new IRequest / IResponse classes:​
An annoyance remaining in the ServiceStack code-base was RequestContext and its relationship with its IHttpRequest and IHttpResponse classes. This was originally modeled after ASP.NET's relationship with HttpContext and its child HttpRequest/HttpResponse classes. Pragmatically speaking this model isn't ideal, as there was functionality spread across all 3 classes, many times duplicated. It was also not obvious how to retrieve IHttpRequest/IHttpResponse classes from a RequestContext and creating a RequestContext from outside of ServiceStack required more knowledge and effort than it should have.
The new model adopts a flattened structure similar to Dart's server HttpRequest (http://bit.ly/19WUxLJ) which sees the IRequestContext
eliminated in favour of a single IRequest
class that also makes available direct access to the Response.
This now becomes much easier to create a Request from outside of ServiceStack with an ASP.NET or HttpListener HttpContext e.g:
var service = new MyService {
Request = HttpContext.Current.ToRequest()
}
var service = new MyService {
Request = httpListenerContext.ToRequest()
}
There's also direct access to the Response from a Request with:
IResponse response = Request.Response;
ASP.NET wrappers now only depends on HttpContextBase​
Also the ASP.NET IHttpRequest
wrappers bind to the newer and mockable HttpContextBase / HttpRequestBase / HttpResponseBase classes which now makes it easier to call services from newer web frameworks like MVC with:
var service = new MyService {
Request = base.HttpContext.ToRequest()
}
The biggest user-facing change was renaming the IHttpRequest/IHttpResponse classes to IRequest/IResponse which is more indicative to what they represent, i.e. the Request and Response classes for all endpoints including MQ and future TCP endpoints. Now only HTTP Requests implement IHttpRequest/IHttpResponse which lets you add logic targeting only HTTP Services with a simple type check:
var httpReq = request as IHttpRequest;
if (httpReq != null) {
//Add logic for HTTP Requests...
}
Accessing the IHttpResponse works the same way, e.g:
var httpRes = Request.Response as IHttpResponse;
if (httpRes != null) {
//...
}
We're still going to add extension methods on IRequest/IResponse to make it easier to discover new functionality, but for HTTP functionality on non-HTTP requests these would just be a NO-OP rather than throw an exception.
Community v4 migration notes​
New Features in v4​
Server-side Async Support​
The most requested feature, Server-side async support has now been implemented! This was surprisingly easy to do where now all HttpHandlers in ServiceStack inherit from a common HttpAsyncTaskHandler
base class that now implements IHttpAsyncHandler
. This lets you return an async Task from your Service in any number of ways as shown in http://bit.ly/1cOJ3hR
E.g. Services can now have either an object, Task or async Task return types that can return a started or non-started task (which we'll start ourselves). This transition went as smooth as it could where all existing services continuing to work as before and all tests passing.
ServiceStack Client Task-based Async​
In matching the new server-side async story and now that all projects have been upgraded to .NET 4.0, all Service Clients have been changed to return .NET 4.0 Task's for all async operations so they can be used in C#'s async/await methods. Some examples of Async in action: http://bit.ly/17ps94C
The Async API's also provide a OnDownloadProgress callback which you can tap into to provide a progress indicator in your UI, E.g: http://bit.ly/19ALXUW
Use any Request DTO in Client API's​
ServiceClient API's that used to only accept Request DTO's with a IReturn
marker, now have object
overloads so they can be used for unmarked Request DTO's as well.
Custom Silverlight and Android builds​
We've added custom Silverlight and Android automated builds for ServiceStack.Client allowing the client libraries to be available in even more environments - with more to follow.
Signed NuGet Packages​
The following Signed NuGet packages are available for core ServiceStack projects in separate NuGet packages using the .Signed suffix:
- ServiceStack.Client.Signed
- ServiceStack.Text.Signed
- ServiceStack.Redis.Signed
- ServiceStack.OrmLite.Signed
- ServiceStack.OrmLite.SqlServer.Signed
- ServiceStack.ServiceStack.Signed
- ServiceStack.ServiceStack.Razor.Signed
- ServiceStack.ServiceStack.Server.Signed
- ServiceStack.Common.Signed
ServiceStack.Interfaces is now strong-named​
In order to be able to have signed clients sharing types with non-signed ServiceStack instances, the DTO models and ServiceStack.Interfaces need to be signed. It was added in the most defensive way possible where ServiceStack.Interfaces.dll is the only dll that's strong-named by default. This should cause minimal friction as it is an impl-free assembly that rarely sees any changes. We're also keeping the AssemblyVersion which makes up the strong-name at a constant 4.0
whilst the benign AssemblyFileVersion will report the true version number.
Add Code-first Attributes at runtime, de-coupled from POCO's​
Inspection of all Metadata attributes in ServiceStack now uses ServiceStack.Text's attribute reflection API's which support adding of type and property metadata attributes dynamically. This now lets you add the same behavior normally only available via attributes, dynamically at StartUp. Some benefits of this include: being able to keep unattributed data model POCOs in OrmLite or to extend built-in and external Request DTOs and Services with enhanced functionality that was previously only available using attributes.
Fluent route configuration available in Reverse Routing​
Leveraging the dynamic attribute support, we now include fluent Route definitions when retrieving relative or absolute urls in Reverse Routing, which can be used in Services when returning urls in responses and is also used in Service Clients to determine which routes to use. Note: as Fluent Routes are defined in the AppHost, they aren't registered and therefore not available in disconnected .NET client applications - so using [Route]
attributes on Request DTO's remains the best way to share route definitions on both client and server.
Priority was added to [Route]
attributes so auto-generated routes are given less precedence than explicit user-defined custom routes when selecting the best matching route to use.
The Virtual FileSystem​
The Virtual FileSystem is now fully integrated into the rest of ServiceStack, this enables a few interesting things:
- The
Config.WebHostPhysicalPath
sets where you want physical files in ServiceStack to be served from - You can now access static files when ServiceStack is mounted at a custom path, e.g. /api/default.html will serve the static file at ~/default.html
- By Default, ServiceStack falls back (i.e when no physical file exists) to looking for Embedded Resource Files inside dlls.
- You can specify the number and precedence of which Assemblies it looks at with
Config.EmbeddedResourceSources
which by default looks at:- The assembly that contains your AppHost
- ServiceStack.dll
The VFS now elegantly lets you replace built-in ServiceStack templates with your own by simply copying the metadata or HtmlFormat Template files you want to customize and placing them in your folder at:
/Templates/HtmlFormat.html // The auto HtmlFormat template
/Templates/IndexOperations.html // The /metadata template
/Templates/OperationControl.html // Individual operation template
This works because the ServiceStack.dll is the last assembly in Config.EmbeddedResourceSources
.
API-first development​
We're starting to optimize ServiceStack's HTML story around an API-first style of web development (particularly well suited to ServiceStack) in which services are developed so they naturally support both web and native clients from the start. Effectively this means that the HTML views are just another client that escapes C# earlier and leverages JS+Ajax to provide its dynamic functionality, and any HTML-specific functionality is encouraged to be kept in Razor views rather than using post backs to generate different server-side HTML representations.
Having developed the new servicestack.net website in this way, we've found it to be a lot more productive and responsive than standard server-side MVC development that we we're accustomed to in .NET as JavaScript ends up being more mallable and flexible language with a smaller and reflective surface type area making it better suited in string manipulation, generating HTML views, consuming ajax services, event handling, DOM binding and manipulation, etc.
We've begun taking advantage of the Virtual FileSystem to ship embedded resources enhancing ServiceStack's JS integration with client-side libraries like ss-utils.js that we maintain and update alongside the rest of ServiceStack's dlls. Whilst we intend to create more examples in the near future showcasing this functionality, here's an overview of what's been added:
- ss-utils.js available in your local ServiceStack webhost at
/js/ss-utils.js
- Inspired by AngularJS we've added declarative support over jQuery, letting you declaratively register and trigger events, bind values to HTML elements, register document handlers, etc, saving a lot of boilerplate than normal jQuery (more on this soon)
- Enhanced HTML forms with integration with ServiceStack validation, adds responsive UX/behavior, follows soft redirects
- Server-side responses can be decorated with Soft redirects with
HttpResult.SoftRedirect
or client events withHttpResult.TriggerEvent
- Use
("a").setActiveLinks()
to automatically set the active link and containing menu items for the current page - Use
$("input").change($.ss.clearAdjacentError)
to clear highlighted errors as users correct their inputs - Use
T.AsRawJson()
extension method to serialize C# models into JSON literals that are natively accessible in JS - Use
T.ToGetUrl()
,T.ToPostUrl()
to resolve service urls from typed Request DTOs (no code-gen required)
Improved Razor Support​
Improved Server-side validation​
The server-side validation story has also been improved with MVC's HTML INPUT and Validation Helpers rewritten to look at ServiceStack error responses (earlier lost in the upgrade to Razor 2.0) and making use of the same bootstrap conventional classes that the client-side Ajax validation uses letting you maintain a single style of error feedback for both validation styles. It also now looks at state contained in the POST'ed data when rendering the HTML INPUT controls.
Fallback Routes​
The default Razor views are now also processed by the FallbackRoute
if one exists, enhancing the story for Single Page Apps who want requests to un-specified routes to be handled by client-side routing instead of returning 404's.
Pre-Request filters​
Direct (i.e. No Controller) Razor views and static file handlers now have pre-request filters applied to them, so they can be used for adding global behavior across all ServiceStack service and page requests.
Precompilation option for Razor Views​
New options have been added to RazorFormat PrecompilePages
and WaitForPrecompilationOnStartup
that allow you to precompile razor views on startup and specify whether or not you want to wait for compilation to complete are now options available when registering the RazorFormat
. As these can slow down dev iteration times they are not done when Config.DebugMode
(aka development mode), but are otherwise enabled by default for production.
Other Razor Improvements​
- More functionality was added to Razor Views matching the same API's available in ServiceStack's base
Service
class - RenderSection/IsSectionDefined now looks in all connected views.
GetAbsoluteUrl
,IsPostBack
,GetErrorStatus()
,GetErrorMessage()
convience methods added
CORS Feature​
CorsFeature now by default automatically handles all HTTP OPTIONS
requests so you no longer have to explicitly allow for OPTION requests in your routes: http://bit.ly/19HbMVf
Can be disabled with:
Plugins.Add(new CorsFeature { AutoHandleOptionsRequests = false })
Authentication​
The Auth Tables are now called UserAuth and UserAuthDetails and implements the IUserAuth and IUserAuthDetails interfaces. For advanced customization, these tables can now be extended using custom models inheriting these interfaces by using the generic AuthRepository types, e.g:
OrmLiteAuthRepository<TUserAuth, TUserAuthDetails>
RedisAuthRepository<TUserAuth, TUserAuthDetails>
Where the common non-generic OrmLiteAuthRepository is just a concrete impl inheriting from OrmLiteAuthRepository<UserAuth, UserAuthDetails>
. Use InitSchema()
to ensure missing Auth Tables are created at registration.
New optional UserAuthRole table added​
A new UserAuthRole
class was created for users who would prefer roles to be managed in separate tables rather than blobbed with the UserAuth table and session. E.g. You can change your custom session to check the database for asserting required users and permissions with:
public class CustomUserSession : AuthUserSession
{
public override bool HasRole(string role)
{
using (var db = HostContext.TryResolve<IDbConnectionFactory>().Open())
{
return db.Count<UserAuthRole>(q =>
q.UserAuthId == int.Parse(UserAuthId) && q.Role == role) > 0;
}
}
public override bool HasPermission(string permission)
{
using (var db = HostContext.TryResolve<IDbConnectionFactory>().Open())
{
return db.Count<UserAuthRole>(q =>
q.UserAuthId == int.Parse(UserAuthId) && q.Permission == permission) > 0;
}
}
}
Support for Max Login Attempts​
The OrmLiteAuthRepository
now supports automatically locking out user accounts after reaching the maximum number of Login attempts which can be specified at registration, e.g:
container.Register<IAuthRepository>(c =>
new OrmLiteAuthRepository(c.Resolve<IDbConnectionFactory>()) {
MaxLoginAttempts = appSettings.Get("MaxLoginAttempts", 5)
});
To opt-in to use the new locking behavior provide a value for MaxLoginAttempts
as shown above. The above registration first uses the value overridable in appSettings if it exists, otherwise it defaults to a Maximum of 5 login attempts.
Adhoc locking of User Accounts​
The CredentialsAuthProvider
also supports locking user accounts by populating the UserAuth.LockedDate
column with a non-null value. Set it back to null to unlock the account.
Initializing Auth Repository Schemas​
Some Auth Repositories like OrmLite require an existing schema before they can be used, this can be done in the AppHost with:
//Create missing Auth Tables in any Auth Repositories that need them
container.Resolve<IAuthRepository>().InitSchema();
This was previously named CreateMissingTables()
and is safe to always run as it's a NO-OP for Auth repositories that don't require a schema and only creates missing tables, so is idempotent/non-destructive on subsequent runs.
New AuthWeb Test project​
A new test project testing all Authentication providers within the same ServiceStack ASP.NET Web Application is in ServiceStack.AuthWeb.Tests.
AppSettings​
AppSettings can now be passed a tier in the constructor, e.g. new AppSettings(tier: "Live")
which it uses as a prefix to reference Tier-specific appSettings first, e.g:
<add key="Live.AppDb" value="..." />
Before falling back to the common key without the prefix, i.e:
<add key="AppDb" value="..." />
AppSettings now allows a Parsing Strategy, e.g. You can collapse new lines when reading a complex configuration object in Web.Config <appSettings/>
with:
var appSettings = new AppSettings {
ParsingStrategy = AppSettingsStrategy.CollapseNewLines
};
Nested Request DTOs​
Using nested types as Request DTO's are now supported. Nested Request DTO types include the names of their containing class to form their unique name, allowing the use of multiple nested types with the same name, which is potentially interesting to be used as a versioning strategy.
Localized symbols​
I've added IAppHost.ResolveLocalizedString
support in this commit which lets you override the built-in English symbols used in ServiceStack, e.g. this lets you change built-in ServiceStack routes, e.g: /auth
, /assignroles
, ?redirect=
, etc. into something more appropriate for your language.
Other New Web Framework Features​
- Added convenient Repository and Logic base classes to reduce boilerplate when extracting logic from services into custom classes
- Added
IAppHost.OnExceptionTypeFilter
to be able to customize ResponseStatus based on Exception types. Used to change the default behavior of ArgumentExceptions so that they're converted to field errors - Added
IAppHost.OnServiceException
so service exceptions can be intercepted and converted to different responses - Add
ConvertHtmlCodes
extension method converting HTML entities to hex-encoded entities - Add
Config.ScanSkipPaths
option to skip any plugins using the VFS to scan the filesystem (e.g. Razor/Markdown feature) from scanning specified directories,/bin/
and/obj/
are added by default. - Added a pre-defined
/swagger-ui/
route that loads the Swagger UI and auto configures it to look at ServiceStack services. A link to this is on the metadata page under Plugin Links heading. - Added
ModelFilter
andModelPropertyFilter
to allow fine-grained custom control on what's displayed in the Swagger API - Wrappers around .NET's JSON and XML DataContract Serializers now share the same
IStringSerializer
interface - Added ToMsgPack/FromMsgPack and ToProtoBuf/FromProtoBuf extension methods
- Improved support for stripping App Virtual Paths when Resolving Absolute Urls useful when applications are hosted with virtual app paths as done in Amazon Web Services. This behavior can be enabled with
Config.StripApplicationVirtualPath = true
. - Support for explicitly referencing ignored DTO properties in Route PathInfo definitions, but not QueryStrings
- Add support for getting Id property from runtime object type
- Added support for registering a singleton instance as a runtime type
- Added new IRestGateway interface that typed 3rd Party gateways can use to retain a consistent and mockable interface. Specialized MockRestGateway added to stub or mock out gateways to 3rd Party services
__requestinfo
is now available on any request with?debug=requestinfo
and is accessible to administrators or when in DebugMode, and provides in-depth diagnostics about the details of the current request and the configured AppHost including Startup errors (if any).- Plugins can register startup exceptions with
IAppHost.NotifyStartupException
- Added new HTTP Headers on IHttpRequest for
XForwardedPort
andXForwardedProtocol
- Added
[EnsureHttps]
Request Filter to automatically redirect request if service was not requested under a Secure Connection with options to SkipIfDebugMode or SkipIfXForwardedFor to allow local development and requests via proxies / load-balancers in HTTP. - Users in the Admin role have super-user access giving them access to all protected resources. You can also use
Config.AdminAuthSecret
to specify a special string to give you admin access without having to login by adding?authsecret=xxx
to the query string.
OrmLite​
Improved Consistency​
As the API surface of OrmLite expands it became a lot more important to focus on better consistency which now sees all alternative aliases having been removed in favor of standardized naming around SQL equivalents (e.g Select,Insert,etc). Also the parameterized APIs and the C#-like string.Format API's have now been merged with the parameterized APIs now being the default and the string.Format API having a 'Fmt' suffix.
Most of these APIs now have XML docs and Examples for a better Intelli-sense experience. We've also provided them in a list along side it's generated SQL in these API tests
Some notes:
Select
returns a ListSingle
returns 1 row (or null) if it doesn't existScalar
returns a single a scalar value (e.g. int, long)Where
is a short-hand for 'Select' that takes a single filterCount
is a convenience that performs an aggregate SQL CountExists
returns true if there were any resultsLazy
suffix indicates the results are lazily streamedColumn
returns the first column results in a ListColumnDistinct
returns the first column unique results in a HashSetDictionary
returns a Dictionary made up from the first 2 columnsLookup
returns a LINQ-like grouping in aDictionary<K, List<V>>
NonDefaults
suffix indicates only non-null values are used in qryOnly
suffix allows you to specify fields used on the call-siteSql
prefix are helpers for reading and querying arbitrary raw SQLSave
is a convenience that inserts or updates depending if it exists or not. It also now populates AutoIncrementing Id's on Inserts.- All batch operations like
InsertAll
,UpdateAll
,DeleteAll
,SaveAll
participate in an existing transaction if 1 exists, otherwise a new one - Removed all 'where T:' constraints where possible
OrDefault
APIs removed, All APIs now return null instead of throwing- autoDisposeConnection removed. false for ":memory:" otherwise true
- Now that all OrmLite's parameterized
Query*
APIs have been merged (above), anyQuery
APIs are from Dapper's extension method, which is also included in OrmLite under ServiceStack.OrmLite.Dapper namespace. - All remaining OrmLIte Attributes have been moved to ServiceStack.Interfaces, which in future will be the only dependency needed by your data models and DTOs.
OrmLite extension methods are now mockable​
OrmLite API's can now be mocked by injecting a ResultsFilter letting you mock the results return by OrmLite which it will use instead of hitting the database. You can also mock with a filter function and it also supports nesting, see examples at: http://bit.ly/1aldecK
This will be useful in Unit Testing Services that access OrmLite directly instead of using a repository.
Support for references, POCO style​
We've added a cool new feature to Store and Load related entities that works great on POCO which are enabled when you use the [Reference]
attribute, e.g: http://bit.ly/1gmvtV6
Unlike normal complex properties in OrmLite:
- Doesn't persist as complex type blob
- Doesn't impact normal querying
- Saves and loads references independently from itself
- Populated references get serialized in Text serializers (only populated are visible).
- Data is only loaded 1-reference-level deep
- Reference Fields require consistent
(T)Id
naming
Basically it provides a better story when dealing with referential data that doesn't impact the POCO's ability to be used as DTO's. At the moment it's limited to loading and saving on a Single instance. We'll look at optimizations for batches on this in future.
We're going to be giving OrmLite a lot more attention from now on given that we're working full-time on ServiceStack and are using it exclusively for our .NET RDBMS persistence. We also intend on adding specialized support to take advantage of PostgreSQL's new features like their HStore and native JSON support. PostgreSQL has been offering the best features of both RDBMS and NoSQL worlds lately and has recently become a particularly attractive option now that AWS is offering first-class support for PostgreSQL in both their RDS and Redshift services.
ServiceStack.Text​
- Allow adding metadata attributes to types or attributes at runtime
- Add JsConfig.ExcludeTypes option to skip serialization of non-serializable properties like Streams
- Change QueryString's to also adopt the configured
JsConfig.PropertyConvention
andJsConfig.EmitLowercaseUnderscoreNames
behavior - Added an injectable ComplexTypeStrategy to the QueryStringSerializer that allows customizing the generation of complex types, e.g. can use a hash literal notation strategy with
QueryStringStrategy.FormUrlEncoded
. - Added
typeof(T).New()
extension method providing a fast way of creating new instances of static or runtime types that will use factory functions registered in the centralizedJsConfig.ModelFactory
(if configured). - The string "on" (i.e. the default value for HTML checkbox) is considered a true value for booleans (same with '1')
- The JSON serializers can be configured to support UnixTime and UnixTimeMs for DateTime's
- Renamed JsonDateHandler to
DateHandler
and JsonPropertyConvention toPropertyConvention
HTTP Utils are now mockable​
Following in the steps of now being able to Mock OrmLite, the HTTP Utils extension methods (http://bit.ly/WyV2tn) are now mockable, e.g:
using (new HttpResultsFilter {
StringResult = "mocked"
})
{
//All return "mocked"
"http://google.com".GetJsonFromUrl();
"http://google.com".GetXmlFromUrl();
"http://google.com".GetStringFromUrl(accept: "text/csv");
"http://google.com".PostJsonToUrl(json: "{\"postdata\":1}");
}
More examples showing how all HTTP Apis can be mocked are at: http://bit.ly/HdWmgm
New pre-release MyGet Feeds​
Instead of publishing pre-release packages on NuGet, we're instead going to release our interim packages to MyGet first which provides greater control and allows better management of packages.
The Instructions to add ServiceStack's MyGet feed to VS.NET are:
- Go to Tools -> Options -> Package Manager -> Package Sources
- Add the Source https://www.myget.org/F/servicestack with the name of your choice, e.g. ServiceStack MyGet feed