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
Uziel
Jun 28, 2004

Ask me about losing 200lbs, and becoming the Viking God of W&W.
OK, so I previously mentioned building a app/site really quickly with an approaching deadline. I made it, and am going into testing. My original intention was to just manually handle billing via paypal, but I've gotten much more attention and desire than anticipated and need to go with a tiered service offering which makes manual billing tricky.

Has anyone implemented tier based billing easily into an MVC site? What should I use? I'm essentially looking for the easiest thing possible for the least amount of work on my end. The basics would be that the user picks their plan in their profile (ie, bronze is $20/month silver is $50/month, etc), and then they are automatically billed. I'm assuming there are ways for a 3rd party to handle the card info, processing, etc. Users would be able to switch plans at any time, so I guess it would need to handle prorates or something?

I am totally out of my element here since like 99% of my experience is building corporate intranet apps/sites that don't do user registration, billing, etc.

Adbot
ADBOT LOVES YOU

zerofunk
Apr 24, 2004
Never done it myself, but something like https://stripe.com/ is supposed to make this fairly easy (or at least easier?). It looks like they don't have an official .NET library, but there are some community ones linked. Looks like you can also just do everything straight through HTTP. I want to say there are a few other companies with similar offerings, but I don't remember the names now.

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy
We've used Braintree before, but given the choice to do it over again I would try Stripe. We tried to use Braintree's automated billing, but there were too many weird gotchas so we just fell back to handling monthly billing, prorating logic, etc. on our own and just used Braintree to store credit cards and bill them every month.

Captain Capacitor
Jan 21, 2008

The code you say?
I just can't seem to get WebClient to authenticate against an intranet SharePoint site. All I want to do is scrape the HTML :(

I've tried using the default network credentials, specifying them manually, tried impersonating myself, but all of them just end up with 401.

:sigh:

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy

Captain Capacitor posted:

I just can't seem to get WebClient to authenticate against an intranet SharePoint site. All I want to do is scrape the HTML :(

I've tried using the default network credentials, specifying them manually, tried impersonating myself, but all of them just end up with 401.

:sigh:

We have an app that talks to SharePoint, here's what we use to connect (more or less - modified to fit in a forum post):

C# code:
private string RequestSPUrl(string url, string body, ICredentials credentials)
{
	var req = WebRequest.Create(url);
	req.AuthenticationLevel = AuthenticationLevel.MutualAuthRequested;
	req.Credentials = credentials;
	req.Method = string.IsNullOrEmpty(body) ? "GET" : "POST";

	if (!string.IsNullOrEmpty(body))
	{
		var stream = req.GetRequestStream();
		var writer = new StreamWriter(stream, Encoding.UTF8);
		writer.Write(body);
		writer.Flush();
		stream.Close();
	}

	var resp = req.GetResponse();
	var stream = resp.GetResponseStream();
	var reader = new StreamReader(stream);
	return reader.ReadToEnd();
}
The credentials are passed in, usually created like:

C# code:
ICredentials credentials = new NetworkCredential(userid, password, domain);

wwb
Aug 17, 2004

Why scrape the html when just about everything in sharepoint should be exposed in a web service which is a bit less work to consume . . .

Mr Shiny Pants
Nov 12, 2012
Exactly, you could download the actual page you want to scrape from the Document Library and parse it yourself. SharePoint is pretty good when it comes to exposing the stuff it holds through webservices. It is all soap and some CAML :( but it will work.

Uziel
Jun 28, 2004

Ask me about losing 200lbs, and becoming the Viking God of W&W.

Bognar posted:

We've used Braintree before, but given the choice to do it over again I would try Stripe. We tried to use Braintree's automated billing, but there were too many weird gotchas so we just fell back to handling monthly billing, prorating logic, etc. on our own and just used Braintree to store credit cards and bill them every month.

zerofunk posted:

Never done it myself, but something like https://stripe.com/ is supposed to make this fairly easy (or at least easier?). It looks like they don't have an official .NET library, but there are some community ones linked. Looks like you can also just do everything straight through HTTP. I want to say there are a few other companies with similar offerings, but I don't remember the names now.

Thanks. Looks like I'll be giving it a try. Has anyone actually done MVC with Stripe then?

sausage king of Chicago
Jun 13, 2001
So I'm trying to use the twitter API and authorize with OAuth with this code:

code:
        public ActionResult AuthorizeTwitter()
        {            
            Response.Redirect(GetRequestToken());
            return View();
        }

        private string GetRequestToken()
        {
            var twitter = new Twitter(consumer, consumerSecret, oauth_token, oauth_token_secret);
            twitter.BaseURI = requestUrl;
            var result = twitter.GetRequest("http://localhost:60707/Twitter/GetAccessToken");

            string[] resultArray = result.Split('&');
            twitter.RequestToken = resultArray[0].Split('=')[1];
            twitter.RequestTokenSecret = resultArray[1].Split('=')[1];
            
            var requestToken = Session["oauth_token"] = resultArray[0].Split('=')[1];            
            Session["oauth_secret"] = resultArray[1].Split('=')[1];
            
            string redirect = authorizeUrl + requestToken;
            return (redirect);
        }

        public ActionResult GetAccessToken()
        {

            string verifier = Request.Params["oauth_verifier"];
            string token = Request.Params["oauth_token"];
            string secret = Session["oauth_secret"].ToString();
   	    .....	    
However, when I get to the GetAccessToken method, for some reason Session["oauth_secret"] is null, though it's set right before in GetRequestToken. Why is this? I had all my code in the controller before but refactored it out to it's own class called 'Twitter', and now the Session is coming back null?

Also, a related question, should I be keeping these values in Session? Are there any problems with doing this and is there a better way to do it?

Captain Capacitor
Jan 21, 2008

The code you say?

Mr Shiny Pants posted:

Exactly, you could download the actual page you want to scrape from the Document Library and parse it yourself. SharePoint is pretty good when it comes to exposing the stuff it holds through webservices. It is all soap and some CAML :( but it will work.

I was hoping it would be easier than that. I guess I'm still getting used to the .NET world. I wouldn't even know where to begin with finding out how to poke around the SharePoint API.

Mr Shiny Pants
Nov 12, 2012

Captain Capacitor posted:

I was hoping it would be easier than that. I guess I'm still getting used to the .NET world. I wouldn't even know where to begin with finding out how to poke around the SharePoint API.

If you use VS, and you should, you can just use a Service Reference to a sharepoint list. The endpoint would be something like http://url/_layouts/lists.asmx this will give you a way to query the lists for items.

Otherwise you could use the SharePoint component model and use those APIs. Just add a reference to the SharePoint dll and you can open a sitecollection, its webs and the corresponding lists.

Powershell is another that is good:

From memory, something like:
code:
$site = Get-SPSite -identity [url]http://serverurl[/url]

$web = $site.RootWeb

$list = $web.Lists | where-object {$_.Name -eq "listname"}

$item = $list.items | where-object {$_.Name -eq "itemname"}
This should give you the item you are interested in. Mind you this is from memory, but it should not be more than a few lines of code.

If you have the item you can do all the processing you want with it.

Mr Shiny Pants fucked around with this message at 12:23 on May 27, 2015

invision
Mar 2, 2009

I DIDN'T GET ENOUGH RAPE LAST TIME, MAY I HAVE SOME MORE?
I beat my head against the wall for HOURS today trying to get this figured out, so I thought I'd share. It's stupid simple, but I'm also just now learning C#, coming from VBS and VBA, with a tiny bit of PHP/html/css thrown in there. Also I really want to see how I could have done this better. Everyone at work writes *sick rear end VBA* for excel, but I'm the only C# guy around.

Situation: WinForms app that's really just a bunch of buttons to launch different websites/applications, since we use probably ~20 different tools a day minimum at work. Other offices wanted the tool, so I needed to figure out how to let them set it up however they'd like.
Decided to go with storing the button label/what it launches in Properties.Settings.Default. To make it way easier, I created a second form (form2) that was basically a clone of the main form, except now when you click it lets you change text/launch parameters.
The issue was that I could not get the button text on Form1 to refresh unless the program restarted. Tried just setting it temporarily to whatever the new text was, but that wouldn't work either.


Form2 does this:
code:
  public void theSetting(string label, string button)
        {        
            string buttonVar = button + "txt";
            Properties.Settings.Default[buttonVar] = label;
            Properties.Settings.Default.Save();
            Form1 frm1 = new Form1();
            frm1.settingsUpdater();
          }
frm1.settingsUpdater() does this:
code:
 public void settingsUpdater()
        {
            Properties.Settings.Default.Reload();
            btn1.Invalidate();  //use this to raise an event to redraw the drat buttons on form 1
        }
Created an event handler for Form1.btn1
code:
this.btn1.Invalidated += new System.Windows.Forms.InvalidateEventHandler(this.btn1_Changed);
And then finally this goddamn thing actually changes the button text.
code:
private void btn1_Changed(object sender, EventArgs e)
        {
            btn1.Text = Properties.Settings.Default.btn1txt;
            btn2.Text = Properties.Settings.Default.btn2txt;
            btn3.Text = Properties.Settings.Default.btn3txt;
            btn4.Text = Properties.Settings.Default.btn4txt;
        }
...I tried for literal hours trying to make it redraw the buttons with the new text, but absolutely couldn't get it. Still not sure why this way works, but calling btn1.Text = Properties.Settings.Default.btn1txt inside of settingsupdater() wouldn't work. I'm assuming it's because it's called by form2, but I don't get the ~why~.

crashdome
Jun 28, 2011
I believe you are looking for
code:
ApplicationSettingsBase.Reload()

crashdome
Jun 28, 2011
MVVM/IoC Question:

So I have a few services I am passing into most of my VMs. My constructors are getting a bit heavy. What's the cleanest way to deal with excessively long VM constructors. I know this has been brought up before but, I can't seem to find it in the thread?

E.g. I have currently...
code:
public class ViewModel1
{
      public ViewModel1 (IViewModel1Service service, ISettingsService settingsService, IAccessService accessService, INavigationService navigationService)
      {
            ...
      }
}

]public class ViewMode2
{
      public ViewModel2 (IViewModel2Service service, ISettingsService settingsService, IAccessService accessService)
      {
            ...
      }
}
As you can see, the last three parameters of the first ViewModel and the last two of the second are used in almost every ViewModel.

My observation is that almost every ViewModel injects a unique service and then... a bunch of others that are basically the same.

Is the best way to wrap them in a registered type? Or should I wrap each of those into a static container of sorts?

Registered Type
E.g.
code:
public class ViewModel1
{
      public ViewModel1 (IViewModel1Service service, IGlobalServices globalServices)
      {
            ISettingsService _settingsService  = globalServices.SettingsService;
            IAccessService _accessService  = globalServices.AccessService;
            INavigationService _navigationService  = globalServices.NavigationService;
		....
      }
}
OR

Static Type Wrapper
E.g.
code:
public static SettingsModule
{
      public static int SettingProperty1
	{
		get { return ServiceLocator.Current.GetInstance<ISettingsService>().SettingProperty1; }
	}
}

public class ViewModel1
{
      public ViewModel1 (IViewModel1Service service)
      {
            ...
      }

	public void SomeMethod()
	{
		int consumeProperty = SettingsModule.SettingsProperty1;
	}
}
OR????

I'm getting tired eyes looking at all these drat private fields and bulky constructors.

EssOEss
Oct 23, 2006
128-bit approved
That style you have there is perfectly normal and is a fine way to do it. Yes, the constructors will be long and you will have private fields. Don't worry about it - that is how it is meant to be. Make sure you are making proper use of a dependency injection container to remove any manual labor involved in wiring up the dependencies - you should not be calling any of these constructors manually.

Most dependency injection containers should also allow properties to be injected into, allowing you to remove the constructors, if that makes you like the look of the code better. I personally can't stand it since it requires the setters to be open to calling also later, which is just evil.

epswing
Nov 4, 2003

Soiled Meat

I tend to push common services into a base class, so at least I don't have to specify private fields for them every time. In the example below, I've also moved the common services to the front of the concrete class constructors.

C# code:
public abstract class BaseViewModel
{
    private readonly ISettingsService settingsService;
    private readonly IAccessService accessService;
    
    public BaseViewModel(ISettingsService settingsService, IAccessService accessService)
    {
        this.settingsService = settingsService;
        this.accessService = accessService;
    }
}

public class ViewModel1 : BaseViewModel
{
    private readonly IViewModel1Service service;
    private readonly INavigationService navigationService;
    
    public ViewModel1 (ISettingsService settingsService, IAccessService accessService, IViewModel1Service service, INavigationService navigationService)
        : base(settingsService, accessService)
    {
        this.service = service;
        this.navigationService = navigationService;
    }
}

public class ViewModel2 : BaseViewModel
{
    private readonly IViewModel2Service service;
    
    public ViewModel2 (ISettingsService settingsService, IAccessService accessService, IViewModel2Service service)
        : base(settingsService, accessService)
    {
        this.service = service;
    }
}

epswing
Nov 4, 2003

Soiled Meat
Maybe not the right thread but I'll try here first. SQL Server 2012 is doing something strange. In my Action Center -> Reliability Monitor tells me that "SQL Server 2012 Database Engine Shared" has had a "Successful application reconfiguration" 2 or 3 times per minute, and has been doing so nonstop for the last 3 days. What's going on here? Anyone seen this before? I don't know if this is a Windows thing or a SQL Server thing.

Windows 2012 Essentials
SQL Server 2012 SP1

http://imgur.com/a/vMTZu

Uziel
Jun 28, 2004

Ask me about losing 200lbs, and becoming the Viking God of W&W.

Uziel posted:

Thanks. Looks like I'll be giving it a try. Has anyone actually done MVC with Stripe then?
Well, I can say that I've actually done MVC with Stripe now!
It was rather easy, the API and it's documentation was a pleasure to use. I wasn't sure how to best use the API to match the model of my payment/user system, but I went on their IRC channel, and a few devs working for Stripe pointed me in the right direction!

Aside from a few minor things like validation, and prettying things up, I'm almost done!

My use case was basically:
Users sign up, and are put on free plan, and a stripe customer is created.
If a user wants to switch to a non free plan, they simply select the plan they want. If their stripe account doesn't have a card associated, prompt them for their card details and using stripe.js send them to the API and get a token back. The card details never touch my server, my form is just submitted with the customer, the plan they are switching to, and a token.
I then create a card for them using the token (which then expires), change their plan, and update their user record as to which plan they are on.
On the stripe dashboard, I can see that the customer then has the new plan, and that their card was charged.

Dr. Poz
Sep 8, 2003

Dr. Poz just diagnosed you with a serious case of being a pussy. Now get back out there and hit them till you can't remember your kid's name.

Pillbug
It's Friday. Let's have a fight: I've seen some support here and other places in favor of using Query objects to encapsulate data access (EF, NHibernate, Raven, etc) and I tried pulling up a few examples and working out a rough example for a particular itch at work I've wanted scratched. I showed it to a coworker and his concern was that he was seeing the dreaded Repository pattern being called by another name. I can see the argument for it, I suppose. The thing I'm working on really isn't of any consequence, so this may not be the best project to use in the search of a specific answer since the nature of the project can dictate the approach to take but I'm interested in the experiences by those here. For this project, my only real needs are querying the data

What separates the two in your minds? Is this a difference without a distinction? Does the name you call it by not matter? Are they both Anti-Patterns?

Here are some links I looked over while researching.

Query Objects: a better approach than your BLL/repository

https://lostechies.com/jimmybogard/2012/10/08/favor-query-objects-over-repositories/

Well designed query commands and/or specifications

Dr. Poz fucked around with this message at 15:26 on May 29, 2015

Funking Giblet
Jun 28, 2004

Jiglightful!
The idea is that queries and query handlers are added to the solution and just work, there is no adding to a repository interface and implementation class, and then updating the dll in the client etc. It also means you don't need to change the constructors to inject different repos etc, you just have a generic mediator which figures it out for you. Each query can be implemented using any method you like, using any data access you like.

wwb
Aug 17, 2004

Dr. Poz posted:

It's Friday. Let's have a fight: I've seen some support here and other places in favor of using Query objects to encapsulate data access (EF, NHibernate, Raven, etc) and I tried pulling up a few examples and working out a rough example for a particular itch at work I've wanted scratched. I showed it to a coworker and his concern was that he was seeing the dreaded Repository pattern being called by another name. I can see the argument for it, I suppose. The thing I'm working on really isn't of any consequence, so this may not be the best project to use in the search of a specific answer since the nature of the project can dictate the approach to take but I'm interested in the experiences by those here. For this project, my only real needs are querying the data

What separates the two in your minds? Is this a difference without a distinction? Does the name you call it by not matter? Are they both Anti-Patterns?

Here are some links I looked over while researching.

Query Objects: a better approach than your BLL/repository

https://lostechies.com/jimmybogard/2012/10/08/favor-query-objects-over-repositories/

Well designed query commands and/or specifications

I think there is a big difference -- you can create very, very flexible yet targeted query objects versus the very generic things one gets to see in repositories. At the same time, if you hit the upstream interfaces right, you can keep a lot of the flexibility you get by riding generic repositories. One trick I really loved with it was using the query objects to perform inversion of control in certain places. I would definitely use it again.

Now, I do agree that you need to be careful not to twist the query object pattern into generic repository land. That is what happened when I handed the project to one of our junior guys.

wwb
Aug 17, 2004

EssOEss posted:

That style you have there is perfectly normal and is a fine way to do it. Yes, the constructors will be long and you will have private fields. Don't worry about it - that is how it is meant to be. Make sure you are making proper use of a dependency injection container to remove any manual labor involved in wiring up the dependencies - you should not be calling any of these constructors manually.

Most dependency injection containers should also allow properties to be injected into, allowing you to remove the constructors, if that makes you like the look of the code better. I personally can't stand it since it requires the setters to be open to calling also later, which is just evil.

I think constructor injection vs property injection is an important semantic point. Constructor injection says "I need this to operate and there is no sensible default so you must supply this info" whereas property injection is a case where a sensible default can be found and you can just run with it. A good simple example would be a logger -- I'd give an object a default implementation that either is just eating the messages or spitting out debug output and then let folks inject fancier ones for production.

New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug

wwb posted:

I think constructor injection vs property injection is an important semantic point. Constructor injection says "I need this to operate and there is no sensible default so you must supply this info" whereas property injection is a case where a sensible default can be found and you can just run with it. A good simple example would be a logger -- I'd give an object a default implementation that either is just eating the messages or spitting out debug output and then let folks inject fancier ones for production.

I don't like property injection because it means that an external agent can theoretically change the implementation at any time. When there's a sensible default, I prefer chained constructors:

code:
public Foo() : this(new Bar()) {}
public Foo(IBar bar) 
{
    this.bar = bar;
}

Dr. Poz
Sep 8, 2003

Dr. Poz just diagnosed you with a serious case of being a pussy. Now get back out there and hit them till you can't remember your kid's name.

Pillbug
Thanks for the input that clears up our conceptual issues. Can someone point me to some better links/examples than the ones I posted?

crashdome
Jun 28, 2011

epalm posted:

I tend to push common services into a base class, so at least I don't have to specify private fields for them every time. In the example below, I've also moved the common services to the front of the concrete class constructors.

wwb posted:

I think constructor injection vs property injection is an important semantic point. Constructor injection says "I need this to operate and there is no sensible default so you must supply this info" whereas property injection is a case where a sensible default can be found and you can just run with it. A good simple example would be a logger -- I'd give an object a default implementation that either is just eating the messages or spitting out debug output and then let folks inject fancier ones for production.

I've tried to avoid the base class idea although I am not sure fully why. I can see the benefits especially if you want to base class a lot of redundant methods used in every ViewModel. I see a pitfall in that if I don't want a particular base class method in a class I am stuck with a tree of base classes implementing and abstracting various method calls if I do that.

Not big on Property Injection either.

For the record, I am using SimpleIoC at the moment.

To quote eplam's code, what is the difference between these two concepts?

Base Class
C# code:
public abstract class BaseViewModel
{
    private readonly ISettingsService settingsService;
    private readonly IAccessService accessService;
    
    public BaseViewModel(ISettingsService settingsService, IAccessService accessService)
    {
        this.settingsService = settingsService;
        this.accessService = accessService;
    }
}

public class ViewModel1 : BaseViewModel
{
    private readonly IViewModel1Service service;
    private readonly INavigationService navigationService;
    
    public ViewModel1 (ISettingsService settingsService, IAccessService accessService, IViewModel1Service service, INavigationService navigationService)
        : base(settingsService, accessService)
    {
        this.service = service;
        this.navigationService = navigationService;
    }
}

public class ViewModel2 : BaseViewModel
{
    private readonly IViewModel2Service service;
    
    public ViewModel2 (ISettingsService settingsService, IAccessService accessService, IViewModel2Service service)
        : base(settingsService, accessService)
    {
        this.service = service;
    }
}
AND

IoC Registered Wrapper Type Container Class Thingy
C# code:
public class GlobalServices : IGlobalServices
{
    private readonly ISettingsService settingsService;
    private readonly IAccessService accessService;
    private readonly INavigationService navigationService;
    
    public GlobalServices(ISettingsService settingsService, IAccessService accessService, INavigationService navigationService)
    {
        this.settingsService = settingsService;
        this.accessService = accessService;
        this.navigationService = naviagtionService;
    }

    public ISettingsService Settings
    {
        get { return settingsService; }
    }

    public IAccessService Access
    {
        get { return accessService; }
    }

    public INavigationService Navigation
    {
        get { return navigationService; }
    }
}

public class ViewModel1 
{
    private readonly IViewModel1Service service;
    private readonly IGlobalServices globalServices;
    
    public ViewModel1 (IGlobalServices globalServices, IViewModel1Service service)
    {
        this.service = service;
        this.globalServices = globalServices;
    }
}

public class ViewModel2
{
    private readonly IViewModel2Service service;
    private readonly IGlobalServices globalServices;
    
    public ViewModel2  (IGlobalServices globalServices, IViewModel1Service service)
    {
        this.service = service;
        this.globalServices = globalServices;
    }
}
I mentioned base classing redundant methods above... granted I lose that ability here but, I could simply base class the globalServices injection if I really wanted.

crashdome fucked around with this message at 21:38 on May 29, 2015

Destroyenator
Dec 27, 2004

Don't ask me lady, I live in beer
I tend to avoid property injection too. I would only use a base class with injection for a base Controller in MVC/WebAPI where you know you're always going to want a RoleService or UserRepo or something in almost every action, and they all have a common base class anyway. In that case I'd go with property injection on the base class (to save passing them through all the time) and ctor injection for everything else.

One solution for your problem could be an interface that defined the services as properties. Then you could allow property injection only for that interface, your view models that take that standard set could implement the interface to get them and any additional services would be injected the standard way. You do end up with some property injection but it's limited and you avoid the base class concerns. (Disclaimer: haven't tried this, not sure which IoC containers will let you wire up injection method based on interface rather than implementation.)

Spazz
Nov 17, 2005

I'm having to re-write some of our internal reporting tools and one of them is our on call notification. I want to rewrite it to use an external API for MMS/SMS notifications instead of e-mailing <number>@att.net. Do you guys have any suggestions for a third party utility that doesn't suck for MMS/SMS?

epswing
Nov 4, 2003

Soiled Meat

Spazz posted:

Do you guys have any suggestions for a third party utility that doesn't suck for MMS/SMS?

Absolutely https://www.twilio.com/

Drastic Actions
Apr 7, 2009

FUCK YOU!
GET PUMPED!
Nap Ghost

Seconding this. We use it here and it's really good. If cost matters though it can get expensive.

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy

Drastic Actions posted:

Seconding this. We use it here and it's really good. If cost matters though it can get expensive.

Also, make sure you handle things like not getting stuck in an SMS loop or sending out 100000 phone calls in an hour. Twilio will happily handle that and happily charge you for it.

Calidus
Oct 31, 2011

Stand back I'm going to try science!
Does this seem sane and do able? It would be nice to know if I am being a complete moron before I start coding. Right now I have everything functioning in a single terrible for loop that takes 1 to 15 minutes to completes depending on the how many items get posted back to the server.

code:
Thread 1  -> Receive Post on MVC Controller -> redirect to index page 
		|Thread 2 -> For Loop to create threads for each new File -> wait for child threads to finish -> log result in database -> thread closed
				|Thread 3-> Create PDF File 1 -> Email PDF File 1 -> Log result in database -> thread closed
				|Thread 4-> Create PDF File 2 -> Email PDF File 2 -> Log result in database -> thread closed
				|Thread 5-> Create PDF File 3 -> Email PDF File 3 -> Log result in database -> thread closed
				etc

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy
Doable yes, sane no. This is what you should be running a background service for (one that doesn't steal threads from your web server). Your web request should save it to a database or a queue somewhere, then redirect the user once that save is acknowledged. The background service would read off that queue, then do whatever work needs to be done.

ASP.NET only has (2 x CPU cores) threads to handle requests by default. If you start stealing threads to do a bunch of work, you can make the server unresponsive.

New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug

Bognar posted:

Doable yes, sane no. This is what you should be running a background service for (one that doesn't steal threads from your web server). Your web request should save it to a database or a queue somewhere, then redirect the user once that save is acknowledged. The background service would read off that queue, then do whatever work needs to be done.

ASP.NET only has (2 x CPU cores) threads to handle requests by default. If you start stealing threads to do a bunch of work, you can make the server unresponsive.

Yeah, that's what I was about to say. Generating PDFs and sending emails is not something your web server should ever be doing.

Calidus
Oct 31, 2011

Stand back I'm going to try science!
Thanks for the reply that makes a lot of sense, the simple web application kinda ballooned over time. I used rotativa (wkhtmltopdf C# lib) generate some simple pdfs of invoices then it kinda transformed into creating 100 page pdfs over time. If I am going to making a background service is it best to have one service per website or compartmentalize them even more? One service for file creation, one for emails, one for faxes, etc?

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy

Calidus posted:

If I am going to making a background service is it best to have one service per website or compartmentalize them even more? One service for file creation, one for emails, one for faxes, etc?

I usually lump simple tasks all into one service, e.g. things that won't take more than a few seconds to complete such as email/fax/etc. However, if there's added complexity like a bunch of dependencies or a really long running task, then I'll break the complex stuff off into separate services.

As an example, we run a site that helps manage lots of PowerPoint slides. We have one service that handles email, periodic tasks like triggering billing through a payment processor or generating an email to the developers from logged exceptions. This just runs as an Azure WebJob since its only dependencies are access to the database and ability to make HTTP calls.

Meanwhile, we have a virtual machine dedicated entirely to running PowerPoint through Interop and generating thumbnails from slides. All third-party solutions for this have rendering bugs, so we just run PowerPoint itself so we have guaranteed correct thumbnails. This has a huge dependency on PowerPoint, and also on a larger set of installed fonts, so we isolate it into its own service. We can also replicate the VM to scale up thumbnailing as necessary.

Humphrey Appleby
Oct 30, 2013

Knowledge only means complicity in guilt; ignorance has a certain dignity.
I am looking for some continuous integration advice regarding keeping track of versions. Right now we are using Jenkins for CI and deploying builds (WCF service hosted on IIS). We manually adjust major and minor, but build and revision get set automatically as Jenkins builds. After Jenkins finishes using msbuild it gets the current version and commits it to mercurial. This makes it really easy to correlate our logs to our repo. I am not a huge fan of Jenkins making a commit/push for every CI build. I'm thinking the best alternative is to log the current commit hash and that can just as easily be looked up. I feel this should be way easier though. I'm open to any suggestions.

New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug

Humphrey Appleby posted:

I am looking for some continuous integration advice regarding keeping track of versions. Right now we are using Jenkins for CI and deploying builds (WCF service hosted on IIS). We manually adjust major and minor, but build and revision get set automatically as Jenkins builds. After Jenkins finishes using msbuild it gets the current version and commits it to mercurial. This makes it really easy to correlate our logs to our repo. I am not a huge fan of Jenkins making a commit/push for every CI build. I'm thinking the best alternative is to log the current commit hash and that can just as easily be looked up. I feel this should be way easier though. I'm open to any suggestions.

You generally shouldn't put binaries in source control. You generally also shouldn't use a build system to deploy, because it encourages bad practices (like having one build per environment instead of a sane binary promotion strategy). The build system should generate artifacts, put them somewhere, then kick off a release using a proper release management tool. I've heard good things about Octopus Deploy, but I haven't used it. Microsoft's release platform is getting a major overhaul soon, as well. I've set up and used Chef and found it to be fairly terrible.

Another option that could suit you would be to turn everything into NuGet packages as a post-build step.

New Yorp New Yorp fucked around with this message at 20:02 on Jun 1, 2015

Humphrey Appleby
Oct 30, 2013

Knowledge only means complicity in guilt; ignorance has a certain dignity.

Ithaqua posted:

You generally shouldn't put binaries in source control. You generally also shouldn't use a build system to deploy, because it encourages bad practices (like having one build per environment instead of a sane binary promotion strategy). The build system should generate artifacts, put them somewhere, then kick off a release using a proper release management tool. I've heard good things about Octopus Deploy, but I haven't used it. Microsoft's release platform is getting a major overhaul soon, as well.

Another option that could suit you would be to turn everything into NuGet packages as a post-build step.

Thanks for the reply. I agree on not using Jenkins to deploy. We are not keep binaries in Mercurial. Jenkins is making a commit with the version number of the DLL after the build. We then store the DLL(s) and deploy to one of the testing servers. When someone uses one of the test servers or production the DLL version number is in our logging. We then can always use that version number to look up the commit Jenkins did right after it made a build. The key part for us is being able to tie any log message to a specific commit/point in time.

Funking Giblet
Jun 28, 2004

Jiglightful!

Humphrey Appleby posted:

Thanks for the reply. I agree on not using Jenkins to deploy. We are not keep binaries in Mercurial. Jenkins is making a commit with the version number of the DLL after the build. We then store the DLL(s) and deploy to one of the testing servers. When someone uses one of the test servers or production the DLL version number is in our logging. We then can always use that version number to look up the commit Jenkins did right after it made a build. The key part for us is being able to tie any log message to a specific commit/point in time.

Why not write the commit id of the build to the assembly as the Product Number or something, instead of committing from Jenkins.

Adbot
ADBOT LOVES YOU

Uziel
Jun 28, 2004

Ask me about losing 200lbs, and becoming the Viking God of W&W.
Bah, intellisense has entirely broken for Visual Studio 2013. Has this happened to anyone before? I've tried closing visual studio, restarting, deleting the suo file, etc. Any ideas?

Edit: It was Tools -> Text Editor -> C# -> Auto List Members and Parameter information. Bah. I swear it was checked before.

Uziel fucked around with this message at 22:23 on Jun 1, 2015

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