Signalr to return content - signalr

What is the best extension point of self hosted signalr to add some code to return additional content (for example list of hub methods and it's models description), just like /signalr/hubs returns javascript with autogenerated proxies.

Solved with
app.Map("/api",
builder =>
builder.Run(context => Task.Run(() =>
context.Response.Write(
HubApiInfoProvider.GetApiInfo()))));
Where HubApiInfoProvider.GetApiInfo() returns a plain text. It's simplified version of #halter73 solution.

Related

How to pass query string with routes in laravel 5.4

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.

Get types implementing interface in ASP.NET Core web application

I am trying to port some of my plain ASP.NET (MVC) code to the ASP.NET Core web application. My code looked like this:
System.Web.Compilation.BuildManager.GetReferencedAssemblies()
.Cast<System.Reflection.Assembly>()
.SelectMany(
a => a.GetTypes()).Where(type => typeof(IGoogleSitemap).IsAssignableFrom(type)
)
.ToList();
But I am not getting that to work on ASP.NET Core (1.1). For one thing Assembly does not have GetReferencedAssemblies() only GetEntryAssembly(). And GetEntryAssembly().GetReferencedAssemblies() gives me a list of AssemblyName instead of Assembly objects.
Basically I am looking for all controllers implementing the IGoogleSitemap interface (defined in a separate assembly).
As I mentioned, .NET Core being so streamlined causes some things to be more complicated. I got it to work by changing the code to this (.NET Core 1.1)
IEnumerable<System.Reflection.TypeInfo> all =
Assembly.GetEntryAssembly().DefinedTypes.Where(type =>
typeof(FullNamespace.IGoogleSitemap).IsAssignableFrom(type.AsType()));
foreach (TypeInfo ti in all)
{
Type t = ti.AsType();
// of all candidates filter out the actual interface definition
if (!t.Equals(typeof(IGoogleSitemap)))
{
// do work here
}
}
Well, that does it for the Entry Assembly at least, still have not figured out how to do it for all referenced assemblies because GetReferencedAssemblies() returns AssemblyName rather than Assembly.
I found a (terribly inefficient) way of achieving this,
var all =
Assembly
.GetEntryAssembly()
.GetReferencedAssemblies()
.Select(Assembly.Load)
.SelectMany(x => x.DefinedTypes)
.Where(type => typeof(ICloudProvider).IsAssignableFrom(type.AsType()));
foreach (var ti in all)
{
var t = ti.AsType();
if (!t.Equals(typeof(ICloudProvider)))
{
// do work
}
}
I am worried about the cost of the Assembly.Load part, but this will probably get my work done for now - as I only need the Fully Qualified Name of all the classes that implements ICloudProvider.

Angular2 HTTP Post ASP.NET MVC Web API

How do you properly create a Web API POST of complex object or multiple parameters using Angular2?
I have a service component in Angular2 as seen below:
public signin(inputEmail: string, inputPassword: string): Observable<Response> {
return this.http.post('/api/account/signin', JSON.stringify({ Email: inputEmail, Password: inputPassword}), this.options);
}
The targeted web api is seen below:
[HttpPost]
[Route("signin")]
public async Task<IActionResult> Signin(string email, string password)
{
....
}
This does not work because I need to convert the parameters of the web api into a single POCO class entity with Email and Password properties and put the [FromBody] attribute: Signin([FromBody] Credential credential)
Without using [FromURI] (POST requests with query strings?), how can I make POSTs of multiple parameters or complex objects without converting these parameters into a single POCO class?
Because what if I have numerous Web API POST actions with parameters like (string sensitiveInfo1, string name, int sensitiveInfo2) or (ClassifiedInfo info, string sensitiveInfo1, string sensitiveInfo2), do I need to convert them all to POCO classes and always use [FromBody]?
PS.
I was using RestangularJS before and it can posts anything (mulitple primitive objects and complex objects) without my Web API actions having [FromBody] attributes. Will about to investigate how RestangularJS do it.
Without using [FromURI] (POST requests with query strings?), how can I make POSTs of multiple parameters or complex objects without converting these parameters into a single POCO class?
I know its not what you want to hear but out of the box this is not possible. It is not a limitation of the browser code that is making the request. This means it does not matter if you are using Angular, JQuery, straight JavaScript, or even RestangularJS. This is a limitation (I use that word loosely as I am sure this is by design) of Web API (any version). Here is the documentation on this design: Parameter Binding in ASP.NET Web API by Mike Wasson.
At most one parameter is allowed to read from the message body. So this will not work:
// Caution: Will not work!
public HttpResponseMessage Post([FromBody] int id, [FromBody] string name) { ... }
So the question becomes, what are your options?
Create a model
This is the thing you were trying to avoid but I list it first because this is how Web API was intended to behave. I have not yet heard a compelling reason not to do this. This approach allows you to extend your model easily without having to change the method signature. It also allows for model validation on the model itself. Personally I really like this approach.
public class SignInModel{
public string Email {get;set;}
public string Password {get;set;}
}
[HttpPost]
[Route("signin")]
public async Task<IActionResult> Signin(SignInModel signInModel)
{
// ....
}
I did not repeat your existing JavaScript code because what you have works as is with the above web api code
URL
Again, what you were trying to avoid. This does make what you want possible with the limitation that you have to pass these parameters using the Query string on the URL. The JavaScript would change but the signature you had on the Web API method would not.
public signin(inputEmail: string, inputPassword: string): Observable<Response> {
return this.http.post('/api/account/signin/?email=inputEmail&password=inputPassword', null, this.options);
}
I did not repeat your existing Web API code because what you have works as is with the above web JavaScript code (by default FromUri is assumed I believe)
Custom Model Binder
See Passing multiple POST parameters to Web API Controller Methods by Rick Strahl. This option allows you to create a custom model binder that could do what you are asking. It is a whole bunch of extra code though for, IMHO, not much benefit. Maybe there are situations where it would be useful although I really cannot think of any off the top of my head.
Dynamic
Finally you could also pass in a dynamic object as the parameter of your Web API. This is essentially the same as receiving the JSON as a string and making your Controller code responsible for the deserialization of content. Again, I believe that this would make your code worse in most situations as you have to implement custom validation and type checks. This answer was proposed previously on SO by Bes Ley. Again, maybe there are situations where it would be useful although I really cannot think of any off the top of my head.
If you call Web API 2.2 post method from Angular 2 type script, dont forget to add following header content and parameter object.
let headers = new Headers({ 'Content-Type': 'application/x-www-form-urlencoded' });
var params = new URLSearchParams();
params.set('userid', '102');
params.set('username', 'foo');
return this._http.post('http://localhost:6579/api/PostUser', params.toString(), { headers: headers }).map(res => res.json());
Perhaps you should post with options:
{
headers: new Headers({
'Content-Type': 'application/x-www-form-urlencoded'
})
}
and encode data like
jQuery.param({user:'bla', password: 'bla'});
WebAPI does not provide this out of the box. If you try to get understanding of web API bindings, you might be able to figure out why.
I think this article might help.
The generic rules are:
– simple, string-convertible parameters (value types, strings, Guids, DateTimes and so on) are by default read from URI
– complex types are by default read from the body
– collections of simple parameters are by default read from the body too
– you cannot compose a single model based on input from both URI and request body, it has to be one or the other
I have fixed the issue of Angular2 HTTP Post ASP.NET MVC Web API
let headers = new Headers();
headers.append('Content-Type', 'application/x-www-form-urlencoded; charset=utf-8');
let params: URLSearchParams = new URLSearchParams();
params.set('value', '2');
let options = new RequestOptions({
headers: headers//,
//search: params
});
let content = new URLSearchParams();
content.set('StudentName', 'Inderjit Singh';
content.set('Mobile', '+919041165398');
content.set('Nationality', 'Indian');
content.set('AdmissionNo', '6');
content.set('SectionCode', '1');
content.set('Gender', 'Male');
content.set('RegNo', '18585');
content.set('ClassCode', '1');
this.http.post('YOUR_URL', content.toString(), { headers: headers }).map((res: Response) => { console.log("data is==>" + res.text()); }).subscribe();
WebApi will be able to deserialize your Credential object provided the JSON object has the same field names (I am not sure about case so you may be right here). You seem to be missing the headers from the post call in your Angular2 component.
Can you check the Content-Type using Chrome Debugger or Fiddler? It should be application/json.
Try this, passing a complex class object into a single data parameter.
var SearchQuery = function () {
this.Alphabet = null;
this.Search = false;
this.Keyword = null;
this.RegionList = null;
};
var para = new SearchQuery();
{ data: JSON.stringify(para) } - Post Data
you can receive it using a JObject in your API controller and deserialize it as according to your classes.

When to specify certain Setups in Moq

I'm trying to follow this Get Started example for testing with Moq. I'm able to duplicate the examples within my own testing project and can get my tests to pass (testing my service where my context is injected). However, what I don't understand is WHEN to use each of the following Setup calls:
var mockSet = new Mock<DbSet<Blog>>();
mockSet.As<IQueryable<Blog>>().Setup(m => m.Provider).Returns(data.Provider);
mockSet.As<IQueryable<Blog>>().Setup(m => m.Expression).Returns(data.Expression);
mockSet.As<IQueryable<Blog>>().Setup(m => m.ElementType).Returns(data.ElementType);
mockSet.As<IQueryable<Blog>>().Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator());
Can someone explain in very basic terms as to when each of these should be used?
For example, It seems that if the method in my service that I'm testing uses an expression, I need to do the 2nd setup call above (I've done some trial and error by removing and re-inserting these calls). I've been to the Moq documentation as well as MSDN for Table-TEntity and I still don't see it. Perhaps because I don't have a strong grasp of the Linq namespace.
TL;DR - When using an Entity Framework DBContext dependency, you will need perform these Setups on any DBSet which you intend to mock, specifically to return fake data to any LINQ queries on the DBSet. All 4 setups should be done for each mocked DbSet - this can be done generically in a helper method.
In more Detail:
In general, with Strict mode off, Setup is only required on methods that you actually want to Mock. In this case, if you haven't done a Setup on a method which is invoked during your Unit Test, Moq will instead provide default behaviour for any method which hasn't been explicitly Setup, which typically is to return the default(T) of any expected return type, T. For classes, the default is null, which isn't really going to help any during testing of classes dependent on a Mocked EF DbContext.
The specific example you have provided is the standard mocked setup for an Entity Framework DbSet, which then allows you to provide fake data for this specific DbSet (DbSet<Blog>), by providing an alternative IQueryable<Blog> from a List<Blog> collection (as opposed to the usual concrete RDBMS implementation).
A suggestion would be to move the DbSetmock code into your standard unit test plumbing setup framework / toolkit, to create a helper method like:
public static Mock<IDbSet<T>> GetMockedDbSet<T>(IList<T> fakeData) where T : class, new()
{
var data = fakeData.AsQueryable();
var mockSet = new Mock<IDbSet<T>>();
mockSet.As<IQueryable<T>>().Setup(m => m.Provider).Returns(data.Provider);
mockSet.As<IQueryable<T>>().Setup(m => m.Expression).Returns(data.Expression);
mockSet.As<IQueryable<T>>().Setup(m => m.ElementType).Returns(data.ElementType);
mockSet.As<IQueryable<T>>().Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator());
return mockSet;
}
Which you can then set up on your Mock DBContext, as follows:
var mockContext = new Mock<IMyDbContext>();
var mockBlogDbSet = GetMockedDbSet<Blog>(new List<Blog>{... fake data here ...});
mockContext.Setup(c => c.Blogs).Returns(mockBlogDbSet.Object);
var sut = new SomeClassIWantToTest(mockContext.Object); // Inject dependency into Ctor
sut.DoSomething();...

Is there an equivalent of the Rhino Mocks .Do() method in Moq?

Is there an equivalent of the Rhino Mocks .Do() method in Moq? I am converting my Rhino Mocks code to Moq, and am stuck on the following:
mockedObject
.Expect(x => x.GetSomething())
.Do((Func<SomeClass>)(() => new SomeClass());
This is not the same as (in Moq, similar in Rhino Mocks):
mockedObject
.Setup(x => x.GetSomething())
.Return(new SomeClass());
When GetSomething() is called multiple times in your unit test, the first piece of code will always return a new instance. The second piece will always return the same instance.
What I want is for my mocked object (with Moq) to always return a new instance. So I actually want to provide an implementation of the GetSomething() method to my mocked object.
Using sequences won't do the trick, because I don't know how many times GetSomething() will be called, nor am I interested in this.
You should be able to pass .Returns a Func<SomeClass> just like you're doing with Rhino mocks:
mockedObject
.Setup(x => x.GetSomething())
.Returns(() => new SomeClass());

Resources