Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
LongSack
Jan 17, 2003

I think, rather than exposing my API layer to arbitrary queries, I’m just going to expose the endpoints which I need, like to get all dishes in category Pizza: https://localhost:5001/v1/Dish/ForCategory/1

But thanks for the responses. I’ll definitely check them out.

Adbot
ADBOT LOVES YOU

ModeSix
Mar 14, 2009

Has anyone here had experience with the .NET implementation of gRPC?

I just discovered this today and want to learn more. If anyone has a link or three to some reading/tutorials that aren't part of the MS documentation and actually show something somewhat complex with it that would be great.

Boz0r
Sep 7, 2006
The Rocketship in action.
I've been on too many CRM projects where all code ended up in <EntityName>Manager classes, so much so that I can't even remember how to name and define responsibilities of new classes. Does anyone have any tips for getting me back on track, so I'll write less lovely code in the future?

insta
Jan 28, 2009
Embrace CQRS. It flattens everything.

Cuntpunch
Oct 3, 2003

A monkey in a long line of kings

ModeSix posted:

Has anyone here had experience with the .NET implementation of gRPC?

I just discovered this today and want to learn more. If anyone has a link or three to some reading/tutorials that aren't part of the MS documentation and actually show something somewhat complex with it that would be great.

Define Complex?

GRPC.NET is pretty straightforward: a protobuf goes through codegen and stubs out the messages into request/reply types and virtual methods you can override in an implementation to do whatever you'd like within the boundaries of that signature. MSDN has some of the more thorough documentation on getting this all set up to run alongside ASP.NET Core, but Google's got some documentation on their equivalent stuff as well.

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



OK so this is a new one on me. ASP MVC template weirdness: I've got a simple int property in a model that represents a DB ID that I want to round-trip through a form, so I do

code:
@Html.HiddenFor(m => m.ThingamagigId)
in the cshtml like you do, but the rendered partial comes back with ... value=""> :what: Tried doing

code:
@Html.HiddenFor(m => m.ThingamagigId) @Model.ThingamagigId
and I get ..value="">12345 out, same as the value of the prop I was seeing in the debugger, but not filled into the drat hidden input for some reason. I even stuck a breakpoint in the cshtml and can see the value filled in on the Model. It's just returning PartialView("path/to/view.cshtml", model), no crazy DIY rendering or anything. This also only seems to happen coming from one of the methods that renders to this view, basically when you create the object model, not when you load a saved one. I'm stumped here and wondering if y'all have seem anything like this.

epswing
Nov 4, 2003

Soiled Meat

Munkeymon posted:

I'm stumped here and wondering if y'all have seem anything like this.

Been a while since I played with cshtml, and maybe this is a stupid question but, is ThingamagigId a property (not a field)? What is the access modifier (public/private/protected)?

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



epalm posted:

Been a while since I played with cshtml, and maybe this is a stupid question but, is ThingamagigId a property (not a field)? What is the access modifier (public/private/protected)?

It's a public property, yeah. And, like I said, it works right if the same partial view with the same model type is rendered from a different method, for some reason.

bobthenameless
Jun 20, 2005

I'm a bit rusty on asp.net, and may be mixing up various ms web tech, but try one of the hiddenfor overloads, something like
code:
@Html.HiddenFor(m => m.ThingamagigId, new { Value = Model.ThingamagigId })
Reading around, it needs the capital V, and maybe a keyword escape @, or maybe neither...but i think that's changed across various framework/razor lib changes in recent times? istr this feeling really redundant and weird to some, but also working out well. it's also helpful if or when you need to set other html attributes like class (..., new {@class = "btn-primary"}), or programmatically assign id names, or for whatever reason.

Alternatively, it working from one method and not the other could (perhaps) be caused because they're different http actions (ie GET vs POST) and/or whether its updating the pages viewbag/viewdata dictionary on page load vs form entry. depending on how its called, the model state may not be updated - in past projects, this was from "odd" JS calls on the page, which would ignore/null the controller model.... i think. its been a little bit.

I also seem to remember just adding an attribute on the model Id property was enough with a similar issue, but i think that was an older serialization lib thing

MisterZimbu
Mar 13, 2006
DI best practices question. Say I have a project already up and running that digests data in a database:

code:
public class AppSettings : IAppSettings {
  public string ConnectionString { get; set; }
}

public class DataProcessor : IDataProcessor {
  public DataProcessor(AppSettings settings) {}

  public void ProcessData() {
     ...
  }
}

public static class Startup {
  public void ConfigureServices(ServiceCollection sc) {
    sc.AddScoped<IAppSettings, AppSettings>();
    sc.AddScoped<IDataProcessor, DataProcessor>();
  }
}
I want to update the solution to be able to point at multiple databases. This there a best practice for parameterizing the services I've already written, without actually having to change the signature of every method in the class to take an additional parameter? Real solution has a larger number of services, and some of them reference other services, so I'm hesitant to go too deep in changing the method signatures, etc.

Currently I'm able to solve it by creating a "context" object that represents a single database, and update the services to have a dependency on that instead of referencing AppSettings directly. Then I create a scope in the ServiceProvider, and when looping through the databases, get a new context object and set the properties in that manually. It works, but it feels like there's a better way to go about doing this:

code:
public class DataProcessorContext : IDataProcessorContext {
   public string ConnectionString { get; set; }
}

public class DataProcessor : IDataProcessor {
  // change DataProcessor to take a context object instead of an AppSettings
  public DataProcessor(IDataProcessorContext context) {}
}

public class AppSettings : IAppSettings {
  public string[] ConnectionStrings { get; set; }
}

public class DataProcessorLoop : IDataProcessorLoop {
  public void ProcessData() {
    foreach(var cs in appSettings.ConnectionStrings) {
      using(var scope = serviceProvider.CreateScope()) {
        var context = scope.ServiceProvider.GetRequiredService<IDataProcessorContext>();
        context.ConnectionString = cs;

        var processor = scope.ServiceProvider.GetRequiredService<IDataProcessor>();
        dataProcessor.ProcessData();
      }      
    }
  }
}
Apologies in advance for the incomprehensible XY problem post

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



bobthenameless posted:

I'm a bit rusty on asp.net, and may be mixing up various ms web tech, but try one of the hiddenfor overloads, something like
code:
@Html.HiddenFor(m => m.ThingamagigId, new { Value = Model.ThingamagigId })
Reading around, it needs the capital V, and maybe a keyword escape @, or maybe neither...but i think that's changed across various framework/razor lib changes in recent times? istr this feeling really redundant and weird to some, but also working out well. it's also helpful if or when you need to set other html attributes like class (..., new {@class = "btn-primary"}), or programmatically assign id names, or for whatever reason.

Alternatively, it working from one method and not the other could (perhaps) be caused because they're different http actions (ie GET vs POST) and/or whether its updating the pages viewbag/viewdata dictionary on page load vs form entry. depending on how its called, the model state may not be updated - in past projects, this was from "odd" JS calls on the page, which would ignore/null the controller model.... i think. its been a little bit.

I also seem to remember just adding an attribute on the model Id property was enough with a similar issue, but i think that was an older serialization lib thing

That does work, but it works by making a second attribute 'Value' that's actually filled in while the 'value' attribute is still blank. The form deserializer must build a value dict case-insensitively, so it round-trips correctly,

Turns out the previous form is sending a blank ThingamagigId which is saved in ModelState and the HTML helpers prefer values from there over values in the actual Model for some reason, even when it's blank, which is the opposite of the form serializer's behavior :wtc: Calling Clear() on ModelState fixes it but boy that's surprising, and not in a fun way.

insta
Jan 28, 2009

MisterZimbu posted:

DI best practices question. Say I have a project already up and running that digests data in a database:

code:
public class AppSettings : IAppSettings {
  public string ConnectionString { get; set; }
}

public class DataProcessor : IDataProcessor {
  public DataProcessor(AppSettings settings) {}

  public void ProcessData() {
     ...
  }
}

public static class Startup {
  public void ConfigureServices(ServiceCollection sc) {
    sc.AddScoped<IAppSettings, AppSettings>();
    sc.AddScoped<IDataProcessor, DataProcessor>();
  }
}
I want to update the solution to be able to point at multiple databases. This there a best practice for parameterizing the services I've already written, without actually having to change the signature of every method in the class to take an additional parameter? Real solution has a larger number of services, and some of them reference other services, so I'm hesitant to go too deep in changing the method signatures, etc.

Currently I'm able to solve it by creating a "context" object that represents a single database, and update the services to have a dependency on that instead of referencing AppSettings directly. Then I create a scope in the ServiceProvider, and when looping through the databases, get a new context object and set the properties in that manually. It works, but it feels like there's a better way to go about doing this:

code:
public class DataProcessorContext : IDataProcessorContext {
   public string ConnectionString { get; set; }
}

public class DataProcessor : IDataProcessor {
  // change DataProcessor to take a context object instead of an AppSettings
  public DataProcessor(IDataProcessorContext context) {}
}

public class AppSettings : IAppSettings {
  public string[] ConnectionStrings { get; set; }
}

public class DataProcessorLoop : IDataProcessorLoop {
  public void ProcessData() {
    foreach(var cs in appSettings.ConnectionStrings) {
      using(var scope = serviceProvider.CreateScope()) {
        var context = scope.ServiceProvider.GetRequiredService<IDataProcessorContext>();
        context.ConnectionString = cs;

        var processor = scope.ServiceProvider.GetRequiredService<IDataProcessor>();
        dataProcessor.ProcessData();
      }      
    }
  }
}
Apologies in advance for the incomprehensible XY problem post

Don't inject IAppSettings, but instead inject your own IConnectionStringProvider. Then, use the "for X class dependency Y, use implementation Z". The code for Lamar is approximately:
code:

public class DataProcessor : IDataProcessor {
  public DataProcessor(IConnectionStringProvider csp) {}
}

IoC.Configure(c => {
  c.For<IDataProcessor>.Use<DataProcessor>.Ctor<IConnectionStringProvider>().Is<AppleDatabase/BananaDatabase/CherryDatabase>();
});


ModeSix
Mar 14, 2009

Cuntpunch posted:

Define Complex?

GRPC.NET is pretty straightforward: a protobuf goes through codegen and stubs out the messages into request/reply types and virtual methods you can override in an implementation to do whatever you'd like within the boundaries of that signature. MSDN has some of the more thorough documentation on getting this all set up to run alongside ASP.NET Core, but Google's got some documentation on their equivalent stuff as well.

I am looking for something a bit more in depth than a hello - response example, which is what I've been able to find digging through the Microsoft documentation/sample pieces on it.

Or maybe it is that simple and I am over thinking it?

Cuntpunch
Oct 3, 2003

A monkey in a long line of kings

ModeSix posted:

I am looking for something a bit more in depth than a hello - response example, which is what I've been able to find digging through the Microsoft documentation/sample pieces on it.

Or maybe it is that simple and I am over thinking it?

Possibly, but what is your use case?

In the simplest sense, GRPC is just message-passing, regardless of how complicated those message structures might be. Define a protobuf schema, then implement the generated methods on the server side so that the generated Client can get that data back.

For unary calls (hit an endpoint with a request, get a response) it's *just that simple* and with GRPC.NET, even streaming (what I might call 'complex' behavior) is really straightforward: https://docs.microsoft.com/en-us/aspnet/core/grpc/client?view=aspnetcore-3.1

You can hide as much complicated logic as you want in the server method implementations, but that's not part of the scope of GRPC.NET. Which is, basically, just 'for this RPC endpoint, given a defined Request message, I'll generate a defined Response message'.

Calidus
Oct 31, 2011

Stand back I'm going to try science!
Anyone have positive or negative experiences with Math.NET? I need to rewrite someone else’s Matlab code. I have much more experience with .NET than python.

Ola
Jul 19, 2004

Calidus posted:

I need to rewrite someone else’s Matlab code.

Haven't got any special tips, other than remember that someone loves you and that the world is a beautiful place.

distortion park
Apr 25, 2011


Calidus posted:

Anyone have positive or negative experiences with Math.NET? I need to rewrite someone else’s Matlab code. I have much more experience with .NET than python.

I'm not familiar with the details of its implementation (it has some support for MKL) but it's probably worth doing some research about performance and if you're going to be able to recreate whatever they've done in Matlab efficiently.

insta
Jan 28, 2009

Calidus posted:

Anyone have positive or negative experiences with Math.NET? I need to rewrite someone else’s Matlab code. I have much more experience with .NET than python.

I wasn't a fan the 19 minutes I played with it. It is probably a very authentic port, but it's not very .NET friendly. A lot of the method calls are static calls, and they update the parameters passed in, and that's gross to me.

raminasi
Jan 25, 2005

a last drink with no ice

pointsofdata posted:

I'm not familiar with the details of its implementation (it has some support for MKL) but it's probably worth doing some research about performance and if you're going to be able to recreate whatever they've done in Matlab efficiently.

insta posted:

I wasn't a fan the 19 minutes I played with it. It is probably a very authentic port, but it's not very .NET friendly. A lot of the method calls are static calls, and they update the parameters passed in, and that's gross to me.

I touched it once like a decade ago and I remember it being a pain to wire it up to properly use the underlying FORTRAN libraries that it wanted to delegate to, which is a bad sign for usability and a good sign for performance. But again, this was a decade ago.

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



Has anyone synchronized MachineKeys on Azure by copying the sections from one App Service's rootweb.config to another manually through Kudu tools? Or even heard of this being done?

In case you're tempted to X/Y me here: Yes, I know App Service Plans share keys but they're location-bound and we failover between locations. Yes, I know you can set them during Application_Start, but that's code that needs maintained.

New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug

Munkeymon posted:

Has anyone synchronized MachineKeys on Azure by copying the sections from one App Service's rootweb.config to another manually through Kudu tools? Or even heard of this being done?

In case you're tempted to X/Y me here: Yes, I know App Service Plans share keys but they're location-bound and we failover between locations. Yes, I know you can set them during Application_Start, but that's code that needs maintained.

Can't you store them in keyvault and have the application pull them from keyvault at startup?

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



New Yorp New Yorp posted:

Can't you store them in keyvault and have the application pull them from keyvault at startup?

Munkeymon posted:

Yes, I know you can set them during Application_Start, but that's code that needs maintained.

B-Nasty
May 25, 2005

Munkeymon posted:

Has anyone synchronized MachineKeys on Azure by copying the sections from one App Service's rootweb.config to another manually through Kudu tools? Or even heard of this being done?

I assume you're not using Core? The DataProtection stuff in Core should work seamlessly for App Services. The key files are backed to network storage and automatically synced to all machines.

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



B-Nasty posted:

I assume you're not using Core? The DataProtection stuff in Core should work seamlessly for App Services. The key files are backed to network storage and automatically synced to all machines.

I did see that but assumed we couldn't share a filesystem mounted to App Services between regions. Also, we're not on Core, but the package claims to work with 4.5.1 and up.

Munkeymon fucked around with this message at 19:19 on Aug 27, 2020

Sab669
Sep 24, 2009

I guess this is more of a SQL question than a .NET question, but... I have a versioned table in my MVC project with 2 columns defined like so:

code:
    [StartTime]                         DATETIME2 (7) GENERATED ALWAYS AS ROW START NOT NULL,
    [EndTime]                           DATETIME2 (7) GENERATED ALWAYS AS ROW END   NOT NULL,

    ......

    PERIOD FOR SYSTEM_TIME ([StartTime], [EndTime])
A lot of the records in the database have the exact same StartTime, some have `1900-01-01 00:00:00.0000000` - but more confusingly every last record has an EndTime of `9999-12-31 23:59:59.9999999` and I can't figure out why? From what I've read, both of those 'as row start/end' triggers suggests those columns should be generated every time the record is updated so shouldn't we be seeing the same value in both fields for every item?

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



The example in the docs doesn't have NOT NULL on the time columns, so that might be messing up whatever mechanism automatically sets and updates the start/end time.

redleader
Aug 18, 2005

Engage according to operational parameters
the start and end times for temporal tables define the period for which that row is valid. sql uses the maximum possible time for a row to indicate that the row is currently active. end will only be set to a different value when the row is deleted, which indicates the row is closed and no longer active. see the docs

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



redleader posted:

the start and end times for temporal tables define the period for which that row is valid. sql uses the maximum possible time for a row to indicate that the row is currently active. end will only be set to a different value when the row is deleted, which indicates the row is closed and no longer active. see the docs

Hmm, I assumed they meant there were overlapping records with that end date, but now I'm not sure why I assumed that

distortion park
Apr 25, 2011


Munkeymon posted:

Hmm, I assumed they meant there were overlapping records with that end date, but now I'm not sure why I assumed that

For the same primary key value, there should be no overlap.

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



pointsofdata posted:

For the same primary key value, there should be no overlap.

Right, which is why I jumped to assuming they did something that prevented SQL from managing the column values correctly.

Withnail
Feb 11, 2004
Is there a way in visual studio to show unused public properties, without using resharper?

New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug

Withnail posted:

Is there a way in visual studio to show unused public properties, without using resharper?

Make it private and see what breaks.

Withnail
Feb 11, 2004

New Yorp New Yorp posted:

Make it private and see what breaks.

lol I need to refactor hundreds of legacy classes. That would not be time efficient.

insta
Jan 28, 2009

Withnail posted:

lol I need to refactor hundreds of legacy classes. That would not be time efficient.

Sounds like you need Roslyn!

Cuntpunch
Oct 3, 2003

A monkey in a long line of kings

Withnail posted:

Is there a way in visual studio to show unused public properties, without using resharper?

The problem is that it's not necessarily safe to make that suggestion, since it presents a significant breaking change to (primarily) library authors.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe
Just decided to resume work on a personal project after a month away from it, Visual Studio asks to update itself and I say yes... and now I have a bunch of uh, whatever this is:

code:
2>Path\Site.csproj : warning NU1701: Package 'System.ComponentModel.Annotations 4.7.0' was restored using '.NETFramework,Version=v4.6.1, .NETFramework,Version=v4.6.2, .NETFramework,Version=v4.7, .NETFramework,Version=v4.7.1, .NETFramework,Version=v4.7.2, .NETFramework,Version=v4.8' instead of the project target framework '.NETStandard,Version=v2.1'. This package may not be fully compatible with your project.
2>Path\Site.csproj : error NU1202: Package Microsoft.AspNetCore.Components.WebAssembly 3.2.0 is not compatible with netstandard2.1 (.NETStandard,Version=v2.1). Package Microsoft.AspNetCore.Components.WebAssembly 3.2.0 does not support any target frameworks.
2>Path\Site.csproj : error NU1202: Package System.Net.Http.Json 3.2.0 is not compatible with netstandard2.1 (.NETStandard,Version=v2.1). Package System.Net.Http.Json 3.2.0 does not support any target frameworks.
(like two dozen more in the same vein as those last 2)
This project was building before so I have no idea why these packages are apparently incompatible suddenly. the Team Explorer panel indicates that there are no changes, so the files are the same as the ones that previously worked.

Microsoft's docs on NU1202 say "Solution: Change the project's target framework to one that the package supports." but um... the error messages say the packages don't support any target framework. so how would I do that?!

e: and I did a clean and rebuild, deleted the bin and obj folders for all projects in the solution, restarted even though the VS installer didn't ask me to, this still happens.

e: also tried
code:
dotnet nuget locals all --clear
didn't help either

Hammerite fucked around with this message at 21:02 on Sep 6, 2020

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe
Well, it turns out there were minor-minor updates to the 4 nuget packages I actually had references to (they went from 3.2.0 to 3.2.1) and installing those solved the problem. VS's nuget interface refused to update them though, I had to uninstall the packages and then reinstall them. super unhelpful behaviour from VS - if it had just said "you must update these packages because we hosed around with something" obviously I would have done.

Boz0r
Sep 7, 2006
The Rocketship in action.
My csproj files has a <Compile Include"..."/> entry for each cs-file in the project, and it's giving me merge errors every time someone else added a file. Is that the normal way, or can I tell it to include everything, and exclude specifics if I want?

EDIT: It looks like it works with this tag. Is this the "proper" way to do it?

code:
<Compile Include="**/*.cs" Exclude="bin/**/*.cs;obj/**/*.cs" />

Boz0r fucked around with this message at 08:04 on Sep 7, 2020

raminasi
Jan 25, 2005

a last drink with no ice

Boz0r posted:

My csproj files has a <Compile Include"..."/> entry for each cs-file in the project, and it's giving me merge errors every time someone else added a file. Is that the normal way, or can I tell it to include everything, and exclude specifics if I want?

EDIT: It looks like it works with this tag. Is this the "proper" way to do it?

code:
<Compile Include="**/*.cs" Exclude="bin/**/*.cs;obj/**/*.cs" />

The “proper” way is to update to SDK-style project files, which implicitly include all .cs files in the project directory. I’m on my phone or I’d find more specific instructions.

Adbot
ADBOT LOVES YOU

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



Withnail posted:

Is there a way in visual studio to show unused public properties, without using resharper?


CodeLense does it

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply