728x90
반응형

참고링크 : https://blog.hexabrain.net/98

using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello, world!");
        }
    }
}

using = using은 말 그대로 '사용하다'라는 의미를 가지고 있습니다. 바로 네임스페이스 System을 사용한다는 말과 같습니다. using을 이용하면, 전체 이름을 참조하지 않고 선언된 네임스페이스 내부 개체들에 접근할 수 있어 불필요한 타이핑을 막습니다.

 

namespace = 네임스페이스(namespace)는 관련된 구조체, 클래스, 델리게이트, 인터페이스 등을 그룹화 한것을 말합니다. 예를 들어서, System.Collections.Generic에는 제네릭 컬렉션을 정의하는 클래스와 인터페이스들이 들어있습니다. 또 System.Linq에는, LINQ를 사용하는 쿼리를 지원하는 클래스와 인터페이스들이 들어있습니다. 이처럼 네임스페이스는 사용하기 편리하게끔 성격이 비슷한 것들을 묶어놓는 것과 같습니다.

 

main = static void Main는 메소드(method)이며, 메인(main) 메소드는 그중에서 가장 중요한 메소드 이며, 프로그램의 최초의 진입점(Entry Point)을 나타냅니다. 모든 프로그램에는 메인 메소드가 반드시 존재해야하며, 메인 메소드가 시작되면 프로그램이 시작되며, 종료되면 프로그램도 같이 종료됩니다. 여기서 static는 한정자로 정적인 메소드를 의미하며, void는 반환 형식으로 반환 값이 없음을 의미합니다.

 

< 자리표시자 >

프로그램 실행 결과를 화면에 출력할 때 사용하는 출력문 등에서는 자리 표시자(틀) 개념을 이용해서 출력 서식을 지정할 수 있습니다. {n} 형태로 {0}, {1}, {2} 순서대로 자리를 만들고 그다음에 있는 값을 차례로 넘겨받아 출력합니다. {0}, {1} 식으로 뒤에 이어 나올 값에 대한 자리 번호(인덱스)를 지정해 놓는 방법을 자리 표시자(place holder) 또는 서식 지정자(format specifier)라고 합니다. 번호 인덱스는 0부터 시작합니다. 다음 코드를 살펴보세요.

Console.WriteLine("{0}", "Hello, C#");

WriteLine() {0} 형태로 0번째 자리를 만들어 놓으면 콤마 뒤에 있는 "Hello, C#" 문자열이 {0} 자리에서 실행됩니다.

 

 

 

 

 

 

728x90
반응형
728x90
반응형

오버로딩 (Overloading)과 오버라이딩 (Overriding)은 객체 지향 프로그래밍에서 메소드를 다룰 때 사용되는 개념입니다. 

 

1.오버로딩 (Overloading): 메소드 오버로딩은 한 클래스 내에서 같은 이름의 메소드를 여러 개 정의하는 것입니다. 
이 메소드들은 매개변수의 수, 타입 또는 순서가 다르기 때문에 서로 다른 기능을 수행할 수 있습니다. 
또한 컴파일러가 호출되는 매개변수를 기준으로 적절한 메소드를 선택합니다. 
메소드 오버로딩을 사용하면 코드를 간결하게 유지하면서 동일한 기능을 하는 메소드들을 하나의 이름으로 그룹화할 수 있습니다.

public class Calculation
{
    public int Add(int a, int b)
    {
        return a + b;
    }

    public double Add(double a, double b)
    {
        return a + b;
    }
}



2. 오버라이딩 (Overriding): 메소드 오버라이딩은 기반 클래스(base class)에 있는 메소드를 파생 클래스(derived class)에서 재정의하여 사용하는 것입니다. 
이를 통해 파생 클래스는 부모 클래스의 메소드를 같은 이름과 시그니처로 사용할 수 있지만, 다른 동작을 수행하도록 구현할 수 있습니다. 
오버라이딩을 사용하면 기반 클래스의 기본 기능을 변경하거나 확장해서, 더 구체적이고 맞춤화된 동작을 제공할 수 있습니다.

public class Animal
{
    public virtual void Speak()
    {
        Console.WriteLine("알 수 없음");
    }
}

public class Dog : Animal
{
    public override void Speak()
    {
        Console.WriteLine("멍멍");
    }
}

 

 

 

 

728x90
반응형

'입사후 공부한 내용' 카테고리의 다른 글

[C#] 기본 개념  (0) 2023.06.23
[React] 노마드코더 기초  (0) 2023.06.21
[MSSQL] 연결 에러 해결!  (0) 2023.06.16
[ASP.NET] MVC강의 기초 및 심화  (0) 2023.06.13
[ASP.NET] 개념과 역사  (0) 2023.06.13
728x90
반응형

React를 사용하기 위해 불러야 할 스크립트

  <script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script>
  <script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script>

 

React JS가 element를 생성하고 event listener를 더하는 것을 도와준다.

ReactDOM은 React element들을 가져다가 HTML로 바꿔준다. 

 

JSX(JavaScript XML)는 리액트와 같은 라이브러리에서 사용하는 문법입니다.

자바스크립트 내부에서 HTML과 유사한 구문을 사용하여 UI구조를 작성하는데 사용됩니다.

 

<JSX>

 

과거문법

function WelcomeMessage() {
  return React.createElement('h1', null, 'Hello, world!');
}

 

현재문법

function WelcomeMessage() {
  return <h1>Hello, world!</h1>;
}

 

그런데 JSX문법으로 그냥 작성하면 html에서는 알아듣지 못한다. 대신 Babel을 가져와서 사용한다.

<!DOCTYPE html>
<html>
  <body>
    <div id="root"></div>
  </body>
  //ReactJS
  <script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script>
  //ReactDOM
  <script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script>
  //Babel
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
  <script type="text/babel"> //꼭 넣어줘야 정상작동
    const root = document.getElementById("root");
    const Title = (
      <h3 id="title" onMouseEnter={() => console.log("mouse enter")}>
        Hello~
      </h3>
    );
    const Button = (
      <button
        style={{
          backgroundColor: "tomato",
        }}
        onClick={() => console.log("im clicked")}
      >
        Click me!
      </button>
    );
    const contatiner = React.createElement("div", null, [Title, Button]);
    ReactDOM.render(contatiner, root);
  </script>
</html>

 

더 나은 형태로 변형하면 다음과 같다.

<!DOCTYPE html>
<html>
  <body>
    <div id="root"></div>
  </body>
  <script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script>
  <script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script>
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
  <script type="text/babel">
    const root = document.getElementById("root");
    function Title() {
      return (
        <h3 id="title" onMouseEnter={() => console.log("mouse enter")}>
          Hello~
        </h3>
      );
    }
    const Button = () => (
      <button
        style={{
          backgroundColor: "tomato",
        }}
        onClick={() => console.log("im clicked")}
      >
        Click me!
      </button>
    );
    const Container = () => (
      <div>
        <Title /> <Button />
      </div>
    );
    ReactDOM.render(<Container />, root);
  </script>
</html>

 

<State>

<!DOCTYPE html>
<html>
  <body>
    <div id="root"></div>
  </body>
  <script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script>
  <script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script>
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
  <script type="text/babel">
    const root = document.getElementById("root");
    function App() {
      let [counter, setCounter] = React.useState(0);
      const onClick = () => {
        setCounter(counter + 1);
      };
      return (
        <div>
          <h3>Total clicks: {counter}</h3>
          <button onClick={onClick}>Click me!</button>
        </div>
      );
    }
    ReactDOM.render(<App />, root);
  </script>
</html>

 

state를 세팅하는 데는 2가지 방법이 있다.
1) 직접 할당 :setState(state +1)
2 )함수 할당:setState(state => state +1) (함수의 첫번째 인자는 현재 state 이다)

현재 state랑 관련이 없는 값을 새로운 state로 하고싶은 경우에는 (1),
현재 state에 조금의 변화를 주어서 새로운 state를 주고 싶은 경우에는 (2)

최종적으로는 2번 함수할당이 더 안전하다.

 

      const [amount, setAmount] = React.useState(0);
      const [inverted, setInverted] = React.useState(false);

 

두번째로 들어가는 함수는 실행될때마다 화면이 새로 렌더링된다는 것이 중요!

 

시간과 분 단위 변환하는 코드

<!DOCTYPE html>
<html>
  <body>
    <div id="root"></div>
  </body>
  <script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script>
  <script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script>
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
  <script type="text/babel">
    function MinutesToHours() {
      const [amount, setAmount] = React.useState(0);
      const [inverted, setInverted] = React.useState(false);
      const onChange = (event) => {
        setAmount(event.target.value);
      };
      const reset = () => setAmount(0);
      const onInvert = () => {
        reset();
        setInverted((current) => !current);
      };

      return (
        <div>
          <div>
            <label htmlFor="minutes">Minutes</label>
            <input
              value={inverted ? amount * 60 : amount}
              id="minutes"
              placeholder="Minutes"
              type="number"
              onChange={onChange}
              disabled={inverted}
            />
          </div>

          <div>
            <label htmlFor="hours">Hours</label>
            <input
              value={inverted ? amount : Math.round(amount / 60)}
              id="hours"
              placeholder="Hours"
              type="number"
              onChange={onChange}
              disabled={!inverted}
            />
          </div>
          <button onClick={reset}>Reset</button>
          <button onClick={onInvert}>
            {inverted ? "Turn back" : "Invert"}
          </button>
        </div>
      );
    }

    function KmToMiles() {
      const [distance, setDistance] = React.useState(0);
      const [flipped, setFlipped] = React.useState(false);
      const onChange = (event) => {
        setDistance(event.target.value);
      };
      const reset = () => setDistance(0);
      const onFlip = () => {
        reset();
        setFlipped((current) => !current);
      };
      return (
        <div>
          <div>
            <label htmlFor="km">KM</label>
            <input
              value={flipped ? Math.round(distance * 1.609344) : distance}
              id="km"
              placeholder="KM"
              type="number"
              onChange={onChange}
              disabled={flipped}
            />
          </div>
          <div>
            <label htmlFor="miles">Miles</label>
            <input
              value={flipped ? distance : Math.round(distance * 0.621371)}
              id="miles"
              placeholder="Miles"
              type="number"
              onChange={onChange}
              disabled={!flipped}
            />
          </div>
          <button onClick={reset}>Reset</button>
          <button onClick={onFlip}>{flipped ? "Turn back" : "Flip"}</button>
        </div>
      );
    }
    function App() {
      const [index, setIndex] = React.useState("XX");
      const onSelect = (event) => {
        setIndex(event.target.value);
      };
      return (
        <div>
          <h1>Super Converter</h1>
          <select value={index} onChange={onSelect}>
            <option value="XX">Select your units</option>
            <option value="0">Minutes & Hours</option>
            <option value="1">Km & Miles</option>
          </select>
          <hr />
          {index === "XX" ? "Please select your units" : null}
          {index === "0" ? <MinutesToHours /> : null}
          {index === "1" ? <KmToMiles /> : null}
          {/* 2개일 때는 이거도 가능?
          {index === "0" ? <MinutesToHours /> : <KmToMiles />}*/}
        </div>
      );
    }
    const root = document.getElementById("root");
    ReactDOM.render(<App />, root);
  </script>
</html>

 

 

 

<Props>

Props(속성)은 React에서 데이터를 부모 컴포넌트로부터 자식 컴포넌트로 전달하는 방법입니다. 

이렇게 props를 통해 컴포넌트 간에 데이터를 주고받을 수 있습니다. 

Props는 읽기 전용이며, 자식 컴포넌트에서 변경할 수 없습니다.

<!DOCTYPE html>
<html>
  <body>
    <div id="root"></div>
  </body>
  <script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script>
  <script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script>
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
  <!-- PropTypes -->
  <script src="https://unpkg.com/prop-types@15.7.2/prop-types.min.js"></script>

  <script type="text/babel">
    function Btn({ text, fontSize = 12 }) {
      return (
        <button
          style={{
            backgroundColor: "tomato",
            color: "white",
            padding: "10px 20px",
            border: 0,
            borderRadius: 10,
            fontSize,
          }}
        >
          {text}
        </button>
      );
    }
    Btn.propTypes = {
      text: PropTypes.string.isRequired,
      fontSize: PropTypes.number,
    };
    function App() {
      return (
        <div>
          <Btn text="Save Changes" fontSize={18} />
          <Btn text={"Continue"} />
        </div>
      );
    }
    const root = document.getElementById("root");
    ReactDOM.render(<App />, root);
  </script>
</html>

 

<Create React App>

새로운 폴더를 만들고 싶은 공간에서

우클릭 -> 터미널 열기 실행후 다음과 같은 명령어를 입력하자.

 

npx create-react-app my-app(폴더명)

 

그러면 중간에 질문이 나오고 y를 누르면 된다.

 

해당 명령어를 통해 새로 생성하는 이유는 다음과 같다.

 

<EFFECTS>

• 리액트를 사용하는 이유: 최소 단위의 렌더링을 위해
• useState(): 변수, 변수를 제어하는 함수로 구성되며 변하는 값을 제어, 해당 부분의 리렌더링을 위함
• props: 태그의 속성 값을 함수의 아규먼트 처럼 컴포넌트에 값을 전달해준다.
• useEffect(): 코드의 실행 시점을 관리할 수 있는 선택권을 얻는 방어막 같은 존재, 디펜던시가 없을 경우 최초 1회 실행, 있을 경우 해당 값이 변할 경우 실행한다. 이 때 디펜던시는 여러개 입력이 가능하다.


🏴 부모 컴포넌트에서 리렌더링이 일어날 경우 모든 자식들이 리렌더링이 된다.(wa can use memo)

🏴 propType을 설치하고 props의 타입을 지정해 줄 수 있다. 이 때 isRequired로 필수값을 지정 가능

 

useEffect()란?

더보기

useEffect는 state의 상태를 감지 변경이 있을 때란 해당 컴포넌트를 랜더링한다.
useState(function(), []) [] 로 3가지 경우의 수 존재 ex) a, b 스테이트
1. 빈 배열을 넣는 경우, 최초 1회 랜더링 될 때만 실행한다.
2. [a] 하나의 state만 넣는 경우 a가 변경될 경우만 랜더링한다.
3. [a, b] a나 b중 하나가 값이 변경 될 때 랜더링한다.

useEffect 왜 써?
렌더링이 계속 된다면, 특히 특정 api를 불러오게 되는 경우 계속해서 불러오는 문제가 생길 수 있다.
state를 변경할 때, 계속해서 렌더링 되는 문제점이 존재한다. 많은 state가 존재한다면 성능 저하 문제가 발생할 수 있다. 이런 문제를 해결하기 위해 사용한다.

 

 

import { useEffect, useState } from "react";

function App() {
  const [counter, setValue] = useState(0);
  const [keyword, setKeyword] = useState("");
  const onClick = () => setValue((prev) => prev + 1);
  const onChange = (event) => setKeyword(event.target.value);
  console.log("난 항상 실행중!");
  useEffect(() => {
    console.log("1번만 실행");
  }, []);
  useEffect(() => {
    if (keyword !== "" && keyword.length > 5) {
      console.log("키워드 변화에만 실행");
    }
  }, [keyword]);
  useEffect(() => {
    console.log("카운터 변화 실행");
  }, [counter]);
  return (
    <div>
      <input
        value={keyword}
        onChange={onChange}
        type="text"
        placeholder="Search here..."
      ></input>
      <h1>{counter}</h1>
      <button onClick={onClick}>Click me!</button>
    </div>
  );
}

export default App;

 

<To Do List>

import { useEffect, useState } from "react";

function App() {
  const [toDo, setToDo] = useState("");
  const [toDos, setToDos] = useState([]);
  const onChange = (event) => setToDo(event.target.value);
  const onSubmit = (event) => {
    event.preventDefault();
    if (toDo === "") {
      return;
    }
    //중요한 로직
    setToDos((currentArray) => [toDo, ...currentArray]); 
    setToDo("");
  };
  return (
    <div>
      <h1>My To Dos({toDos.length})</h1>
      <form onSubmit={onSubmit}>
        <input
          onChange={onChange}
          value={toDo}
          type="text"
          placeholder="write your to do..."
        />
        <button>Add To Do</button>
      </form>
    </div>
  );
}

export default App;

 

import { useEffect, useState } from "react";

function App() {
  const [toDo, setToDo] = useState("");
  const [toDos, setToDos] = useState([]);
  const onChange = (event) => setToDo(event.target.value);
  const onSubmit = (event) => {
    event.preventDefault();
    if (toDo === "") {
      return;
    }
    setToDos((currentArray) => [toDo, ...currentArray]);
    setToDo("");
  };
  return (
    <div>
      <h1>My To Dos({toDos.length})</h1>
      <form onSubmit={onSubmit}>
        <input
          onChange={onChange}
          value={toDo}
          type="text"
          placeholder="write your to do..."
        />
        <button>Add To Do</button>
      </form>
      <hr />
      <ul>
        {toDos.map((item, index) => (
          <li key={index}>{item}</li>
        ))}
      </ul>
    </div>
  );
}

export default App;

 

<Coin Tracker>

import { useEffect, useState } from "react";

function App() {
  const [loading, setLoading] = useState(true);
  const [coins, setCoins] = useState([]);
  useEffect(() => {
    fetch("https://api.coinpaprika.com/v1/tickers")
      .then((response) => response.json())
      .then((json) => {
        setCoins(json);
        setLoading(false);
      });
  }, []);
  return (
    <div>
      <h1>The COIN TRADE {coins.length}</h1>
      {loading ? <strong>Loading...</strong> : null}
      <ul>
        {coins.map((coin) => (
          <li>
            {coin.name} ({coin.symbol}): {coin.quotes.USD.price}
          </li>
        ))}
      </ul>
    </div>
  );
}

export default App;

 

<Movie App>

import { useState } from "react";
import Movie from "../components/Movie";

function Home() {
  const [loading, setLoding] = useState(true);
  const [movies, setMovies] = useState([]);
  const getMovies = async () => {
    const json = await (
      await fetch(
        `https://yts.mx/api/v2/list_movies.json?minimum_rating=9&sort_by=year`
      )
    ).json();
    setMovies(json.data.movies);
    setLoding(false);
  };

  useEffect(() => {
    getMovies();
  }, []);
  console.log(movies);
  return (
    <div>
      {loading ? (
        <h1>Loading...</h1>
      ) : (
        <div>
          {movies.map((movie) => (
            <Movie
              key={movie.id}
              medium_cover_image={movie.medium_cover_image}
              title={movie.title}
              summary={movie.summary}
              genres={movie.genres}
            />
          ))}
        </div>
      )}
    </div>
  );
}

export default Home;

npm i react-router-dom@5.3.0

 

 

 

 

 

 

 

 

728x90
반응형

'입사후 공부한 내용' 카테고리의 다른 글

[C#] 기본 개념  (0) 2023.06.23
[개념정리] 오버로딩, 오버라이딩  (0) 2023.06.22
[MSSQL] 연결 에러 해결!  (0) 2023.06.16
[ASP.NET] MVC강의 기초 및 심화  (0) 2023.06.13
[ASP.NET] 개념과 역사  (0) 2023.06.13
728x90
반응형

기존의 MSSQL 연결 코드

const config = {
user: process.env.MSSQL_USER,
password: process.env.MSSQL_PASSWORD,
server: process.env.MSSQL_SERVER,
database: process.env.MSSQL_DB,
options: {
encrypt: true,
cryptoCredentialsDetails: {
minVersion: "TLSv1.3",
},
},

 

해당 코드로 실행시에는 여러 에러코드가 발생했다.

 

< 에러 내용 >

더보기

(node:17836) [DEP0123] DeprecationWarning: Setting the TLS ServerName to an IP address is not permitted by RFC 6066. This will be ignored in a future version.
(Use `node --trace-deprecation ...` to show where the warning was created)
데이터베이스 연결에 실패했습니다.

originalError: ConnectionError: Failed to connect to 110.10.130.21:1433 - C84E0000:error:0A0000BF:SSL routines:tls_setup_handshake:no protocols available:c:\ws\deps\openssl\openssl\ssl\statem\statem_lib.c:124:

 

그리고 계속된 구글링을 통해 다음과 같이 코드를 수정하였다.

// 데이터베이스 연결 설정
const config = {
  type: "mssql",
  server: process.env.MSSQL_SERVER,
  database: process.env.MSSQL_DB,
  authentication: {
    type: "default",
    options: {
      userName: process.env.MSSQL_USER,
      password: process.env.MSSQL_PASSWORD,
    },
  },
  options: {
    encrypt: false,
    enableArithAbort: true,
    cryptoCredentialsDetails: {
      minVersion: "TLSv1",
    },
    trustServerCertificate: true,
  },
};

(async function () {
  try {
    // 데이터베이스 연결
    await sql.connect(config);
    console.log("데이터베이스에 연결되었습니다.");
  } catch (err) {
    console.error("데이터베이스 연결에 실패했습니다.", err);
  }
})();

자세히 읽어보기 보단 코드 한줄씩 붙여가며 계속 실행해본 것이라

성공한 이유가 궁금했다. 성공한 이유는 다음과 같다고 한다.

현재 코드에서 연결이 정상적으로 작동한 것은 다음과 같은 변경사항들 때문입니다:

encrypt: false로 변경함으로써 SSL/TLS 암호화를 사용하지 않게 되어 영향을 미칠 수 있습니다. 이것은 서버가 SSL/TLS 암호화를 지원하지 않을 때 문제를 해결할 수 있습니다. 하지만 보안상의 문제로 데이터 전송이 암호화되지 않게 됩니다.

trustServerCertificate
: true 옵션을 추가하여 서버의 인증서를 무조건 신뢰하도록 설정했습니다. 이 변경 사항으로 인해 클라이언트가 서버의 인증서를 확인하지 않고 연결을 수락하게 됩니다. 인증서가 올바르지 않거나, 자가 서명된 인증서를 사용하는 경우에도 연결에 성공할 수 있습니다. 그럼에도 불구하고 이 설정은 보안상 좋지 않은 선택이며 데이터 공격에 취약해질 수 있습니다.

cryptoCredentialsDetails 
옵션을 수정하여 최소 TLS 버전을 'TLSv1'로 변경했습니다. 이것은 이전에 발생한 TLS 버전 불일치 문제를 해결하는 데 도움이 되었을 수 있습니다.
변경된 코드는 연결 문제를 일시적으로 해결했지만, 중요한 것은 데이터베이스와 클라이언트 사이의 전송에 암호화된 연결을 사용하도록 설정하는 것입니다. SSL/TLS를 사용하여 데이터를 암호화하고, 유효한 서버 인증서를 사용하여 서버에 대한 신뢰를 높이는 것이 좋습니다. 이러한 설정을 적용하기 위해 데이터베이스 서버 관리자와 협력하는 것이 필요할 수 있습니다.

728x90
반응형
728x90
반응형

강의듣기 : https://www.youtube.com/playlist?list=PLtht1_et-35DI4cRVKEUUaQAuT3FW2jet 

 

비주얼 스튜디오는 커뮤니티(무료)버전으로 다운 받고,

.NET 프레임워크 를 검색해서 추가 다운 받아줘야 한다.

아래의 ASP.NET 웹 애플리케이션(.NET Framwork)와 ASP.NET 웹 응용프로그램이

새로운 프로젝트로 생성되지 않아 뻘짓을 많이 했다.

 

< 기초 >

비주얼 스튜디오에서 새로운 프로젝트를 만든다.

다음을 누르고 비어있음, MVC를 체크한다. (HTTPS에 대한 구성은 빼주는게 좋다)

만들어졌다면 컨트롤러 폴더에서 우클릭 - 추가 - 컨트롤러 - MVC 5 컨트롤러 비어있음을 추가해준다.

그리고 이름은 HomeController로 바꾼다.

 

이제 다음과 같은 컨트롤러 코드로 변경해주자.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace WebApplication1.Controllers
{
    public class HomeController : Controller
    {
        // GET: Home
        public string Index()
        {
            return "My first Application!";
        }
    }
}

위 코드는 Home 컨트롤러에서 Index로 접속가능하게 해준다.

다음과 같은 url로 접속 가능한 이유는 App_start 폴더에 있는 Config에서 설정이 자동으로 되어 있기 때문이다.

 

< 컨트롤러 >

 

 

 

컨트롤러는 클래스,

액션은 메서드,

아이디는 매개변수라고 생각하면 된다.

 

새로운 컨트롤러 Board를 만들어보자.

컨트롤러 폴더에서 우클릭 + 추가를 통해 새로운 컨트롤러 생성.

 

namespace WebApplication1.Controllers
{
    public class BoardController : Controller
    {
        // GET: Board
        public string List(int? Id)
        {
            if (Id == null)
                return "Error Message #1";
            return "보드 리스트: " + Id.Value;
        }
    }
}

 

< 뷰 >

뷰를 사용하려면 메서드에서 string을 변경해야한다. (string -> ActionResult)

namespace WebApplication1.Controllers
{
    public class BoardController : Controller
    {
        // GET: Board
        public ActionResult List(int? Id)
        {
            if (Id == null)
                return HttpNotFound("에러메시지");
            return View();
        }
    }
}

 

현재 view폴더에 아무것도 없고, return View()에도 매개변수가 없기 때문에

아래와 같이 메서드가 있는 줄에서 우클릭+뷰추가를 통해 파일을 만들어준다.

 

List.cshtml 코드

body>
    <div> 
        <table>
            <thead>
                <tr>
                    <th>번호</th>
                    <th>제목</th>
                    <th>글쓴이</th>
                </tr>    
            </thead>
            <tbody>
                @for (int i = 0; i < 10; i++)
                {
                <tr>
                    <td>@(i+1)</td>
                    <td>제목입니다</td>
                    <td>홍길동</td>
                </tr>
                }
            </tbody>
        </table>
    </div>
</body>

실행시키면 다음과 같은 화면이 된다.

< 모델 >

모델은 데이터의 속성을 정의하고 데이터의 처리를 담당합니다.

 

모델 폴더에서 새 항목을 추가합니다.

클래스를 만들어줍니다.

이후 다음의 코드를 작성하면 데이터의 속성을 정의할 수 있습니다.

namespace WebApplication1.Models
{
    public class Document
    {
        // prop 쓰고 tab을 누르면 빠르게 작성가능
        public int Document_Number { get; set; }
        public string Title { get; set; }
        public string Writer { get; set; }
    }
}

데이터의 처리를 위해 새폴더를 만들고 새로운 클래스 파일을 만들어줍니다.

namespace WebApplication1.Data
{
    public class DocumentData
    {
        public List<Document> Documents
        {
            get
            {
                return new List<Document>
                {
                    new Document{ Document_Number = 1, Title="공지1", Writer="홍길동"},
                    new Document{ Document_Number = 2, Title="공지2", Writer="임꺽정"},
                    new Document{ Document_Number = 3, Title="공지3", Writer="변사또"},
                };
            }
        }
    }
}

모델폴더에 데이터 처리를 위한 클래스를 새로 만들어준다.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using WebApplication1.Data;

namespace WebApplication1.Models
{
    public class DocumentActs
    {
        public List<Document> GetDocuments()
        {
            DocumentData documentData = new DocumentData();
            var documents = documentData.Documents;
            return documents;
        }
    }
}

 

그리고 보드컨트롤러로 가서 요청을 한다.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using WebApplication1.Models; //추가

namespace WebApplication1.Controllers
{
    public class BoardController : Controller
    {
        // GET: Board
        public ActionResult List(int? Id)
        {
            if (Id == null)
                return Content("Error Message #1");

            DocumentActs documentActs = new DocumentActs();
            var documents = documentActs.GetDocuments();

            return View(documents);
        }
    }
}

 

그다음 뷰로 가서 출력한다.

@model List<WebApplication1.Models.Document> //프로젝트명+모델+다큐먼트
@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>List</title>
</head>
<body>
    <div> 
        <table>
            <thead>
                <tr>
                    <th>번호</th>
                    <th>제목</th>
                    <th>글쓴이</th>
                </tr>    
            </thead>
            <tbody>
                @foreach (var item in Model)
            {
                <tr>
                    <td>@item.Document_Number</td>
                    <td>@item.Title</td>
                    <td>@item.Writer</td>
                </tr>
            }
            </tbody>
        </table>
    </div>
</body>
</html>

 

이 모든 과정을 설명하자면

먼저 컨트롤러가 모델에서 데이터를 처리하는 클래스를 부름(DocumentActs)

받아온 값을 객체에 담아서 뷰로 리턴합니다.

            DocumentActs documentActs = new DocumentActs();
            var documents = documentActs.GetDocuments();
            return View(documents);

 

< ViewBag & ViewData >

데이터를 전달하는 방법은 다음과 같습니다.

View(object model)

        public ActionResult List()
        {
            DocumentActs documentActs = new DocumentActs();
            var documents = documentActs.GetDocuments();
            return View(documents);
        }

이 경우 하나의 모델데이터만 전달할 수 있기 때문에 여러 데이터를 전달하려 한다면 한계가 있습니다.

그래서 ViewBag&ViewData가 필요합니다.

 

        public ActionResult List()
        {
            DocumentActs documentActs = new DocumentActs();
            MemberActs memberActs = new MemberActs();

            var documents = documentActs.GetDocuments();
            var member = memberActs.GetMember(1);

            ViewBag.Member = member;

            return View(documents);
        }

View()는 한개의 매개변수만 담을 수 있으니,

ViewBag을 통해 다른 매개변수를 저장하고 사용합니다.

        <p>
        @ViewBag.Member.Name 님 환영합니다.
        </p>

 

ViewData는 다음과 같이 사용할 수 있습니다.

ViewData["Members"] = member;

그리고 cshtml으로 갑니다.

@model List<WebApplication1.Models.Document>
@{
    Layout = null;
    var member = ViewData["Member"] as WebApplication1.Models.Member;
}

ViewData의 경우는 형변환을 한 후 사용합니다.

@member.Name 님 환영합니다.
@model List<WebApplication6.Models.Document>
    @foreach (var item in Model)
    {
        <tr>
            <td>@item.Document_Number</td>
            <td>@item.Title</td>
            <td>@item.Writer</td>
        </tr>
    }
////////////////////////////////////////////
    <tbody>
        @foreach (var member in ViewBag.Member)
        {
            <tr>
                <td>@member.Name</td>
                <td>@member.Age</td>
            </tr>
        }
    </tbody>
////////////////////////////////////////////
    <p>이름: @ViewBag.Member[0].Name</p>
    <p>나이: @ViewBag.Member[0].Age</p>
    <p>이름: @ViewBag.Member[1].Name</p>
    <p>나이: @ViewBag.Member[1].Age</p>

 

 

< Razor >

Razor는 렌더링이라는 역활을 담당합니다.

렌더링이란 어떠한 것을 사용자(클라이언트)에게 보여주는 것입니다.

ViewBag.Arr = new string[]
{
	"1",
    "2",
    "3",
}
@foreach(string s in ViewBag.Arr)
{
	<div>@s</div>
}

 

< Layout >

레이아웃을 우리말로 한다면 '배치'입니다.

프로그래밍적으로 레이아웃은 반복되는 코드, 중복되는 코드를 다시 사용할 일 없게끔 하는 것 입니다.

@RenderBody() 라는 것과 입력했던 값이 대체 된다.

<개념정리>

1. ViewBag & ViewData: 이들은 컨트롤러에서 뷰로 데이터를 전달하는 데 사용합니다.
ViewData: ViewData는 Key-Value 쌍의 딕셔너리로서, TempData와 유사하지만 요청이 끝날 때 소멸됩니다. ViewData는 동적 속성을 제공하지 않으며, 문자열을 키로 사용합니다. 데이터 형식을 지정해야 되기 때문에 형식 변환이 필요할 수 있습니다.
ViewBag: ViewBag은 ViewData의 래퍼이며, 동적 속성을 제공하는 데 사용됩니다. ViewBag을 이용하면 코드가 더 짧아지며, 지정된 속성에 동적으로 액세스할 수 있습니다. 형식 변환 필요성이 줄어들지만, 코드 작성 시 덜 엄격하게 체크한다는 단점이 있습니다.

 

2. Razor: Razor는 ASP.NET의 바인딩 구문 중 하나로, C# 또는 VB코드를 HTML 문서에 삽입하여 웹 페이지를 동적으로 생성합니다. Razor 구문은 '@' 기호로 시작하며, 다음과 같은 형식을 가집니다. '@(표현식)', '@{ ... }' 등입니다. Razor는 서버 측 코드와 클라이언트 측 코드를 명확하게 구분하여 개발자가 코드를 쉽게 작성하고 유지할 수 있도록 지원합니다.

 

3. Layout: Layout은 ASP.NET에서 마스터 페이지와 같은 개념으로, 공통되는 페이지 요소를 재사용하고 중복을 줄이기 위한 방법입니다. 여러 뷰에서 공유할 수 있는 베이스 페이지를 설정하고, 각 뷰에 필요한 내용만 추가하여 효율적으로 페이지 구성을 관리할 수 있습니다. Layout 페이지는 _Layout.cshtml 파일로 저장되며, 각 뷰에서 '@{ Layout = "_Layout"; }'와 같은 코드로 그것을 참조할 수 있습니다.

 

< 심화 >

1. Entity Framework 설치

 

새 프로젝트 만들기 -> ASP.NET 웹 응용 프로그램(Empty , MVC) ->

도구(NuGet 패키지 관리자) -> 솔루션용 NuGet 패키지 관리 -> EntityFramework 설치하기

 

 

2. CRUD Action & View생성

Model 폴더에 Book.cs 파일을 만들어준다.

using System.ComponentModel;
using System.ComponentModel.DataAnnotations;

namespace LibraryApplication.Models
{
    public class Book
    {
        [Key]
        public int Book_U { get; set; }
        [DisplayName("제목")]
        public string Title { get; set;}
        [DisplayName("저자")]
        public string Writer { get; set; }
        [DisplayName("요약")]
        public string Summary { get; set; }
        [DisplayName("출판사")]
        public string Publisher { get; set; }
        [DisplayName("출판일")]
        public int Published_date { get; set; }
    }
}

그후 Web.config에서 다음과 같은 코드를 추가한다.

<connectionStrings>
<add name ="DBCS" connectionString="server=MSSQL_SERVER_ID; database=Library; integrated security=SSPI" providerName="System.Data.SqlClient"/>
</connectionStrings>

 

그리고 Context라는 폴더 생성후 클래스 LibaryDb 생성

using LibraryApplication.Models;
using System.Data.Entity;

namespace LibraryApplication.Context
{
    public class LibaryDb : DbContext
    {
        public LibaryDb():base("name=DBCS") { }
        public DbSet<Book> Books { get; set; }
    }
}

컨트롤러 생성

 

생성후 컨트롤러에서 F5를 눌러 실행하면 화면이 발생한다.

생성 삭제 수정 등이 간단하게 구현되어 있다.

 

3. Action & View 설명

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

728x90
반응형
728x90
반응형

참고사이트 : https://www.dotnetnote.com/docs/aspnet/aspnet-intro/

유튜브 재생목록 : https://www.youtube.com/playlist?list=PLO56HZSjrPTBblm3CbalLSf7Zv7IrwU7G 

ASP.NET 개념정리 : https://www.youtube.com/watch?v=idO_OsRcCYc&t=1s 

 

ASP.NET이란 마이크로소프트의 웹프레임워크이자 웹 기술의 집합체다.

Web Pages는 현재 안쓰고 MVC로 바뀌었다고 보면 됨. 현재는 MVC가 주류로 사용되고 있다.

 

 

 

 

728x90
반응형
728x90
반응형

1. EC2 가상서버 만들기  https://goddaehee.tistory.com/316

 

[AWS] 2. EC2 생성 및 접속하기(AWS SSH키 등록 하기)

2. EC2 생성 및 접속하기 & SSH키 등록 하기 안녕하세요. 갓대희 입니다. 이번 포스팅은 [ EC2 생성, 섭속, 종료 그리고 AWS SSH키 등록 하기 ] 입니다. : ) 시작하기 앞서 - 혹시 공부를 위해서 이 글을 본

goddaehee.tistory.com

 

내 나름대로 요약하자면, AWS 콘솔 로그인후 지역 서울로 설정하여 인스턴스를 만든다.

그리고 조건을 확인하며 인스턴스 생성한후 키 페어 생성하여 폴더에 따로 보관한다!

해당 폴더에서 우클릭 ->  더 많은 옵션 표시 한 후 Git Bash를 실행한다.

입력해야 할 정보는 [연결]에 들어간다.

인스턴트 연결에서 [SSH 클라이언트]에 가면 진행해야할 입력키를 알려준다.

[예:] 여기에 적힌 값을 바로 복사하여 붙여넣기 한다.

다음과 같은 화면이 나오면 git clone [저장소URL]을 입력한다.

이때 저장소URL은 HTTPS와 SSH가 있는데,

HTTPS가 안된다면 바로 SSH로 시도 해봐야 한다.

(HTTPS로 했을 시에는 WRITE와 ADMIN 권한을 줘도 자꾸 권한이 없다고 진행안됨)

 

2. 실행하기: 정상적으로 clone이 되었다면 다음 링크를 보고 따라하면 될 것 같다.

https://hevton.tistory.com/m/530

 

EC2 에 Node.js 웹서버구현 기초

EC2에 우선 ssh로 원격 접속을 해 들어간다. 그 상태에서 먼저 다운로더 패키지를 업데이트 해주고 sudo apt update 그다음 nodejs를 설치해주고 sudo apt install nodejs 그다음 nodejs 패키지매니저인 npm도 다

hevton.tistory.com

 

728x90
반응형
728x90
반응형

SQL Server Management Studio Management Studio 19를 설치해서

새쿼리로 문법연습은 하고 있었지만, VS Code에서 데이터베이스를 다뤄보고 싶었다.

그런데 생각보다 연결할 방법을 찾지 못했다.

열심히 구글링하고 유튜브를 찾아봤지만 헛수고...

공식문서를 들어가봤다!

 

https://learn.microsoft.com/ko-kr/sql/tools/visual-studio-code/mssql-extensions?view=sql-server-ver16 

 

Visual Studio Code mssql 확장명 개요 - SQL Server

Visual Studio Code용 mssql 확장명을 통한 개발

learn.microsoft.com

 

이 부분을 보고 확장 mssql을 설치했다.

 

위에서 보이는 화면처럼 로컬호스트에 연결하려면 localhost 위에 있는 + 버튼을 누르자.

그다음 SQL Server 연결시 보이는 서버이름 을 입력하자.

그후 옵션들을 잘 읽고 인증방법 선택이 나올 것이다.

 Integrated 인증으로 연결완료하였다.

잘 안된다면 추가링크를 확인하자.

추가링크 :  https://pyoja.tistory.com/288

728x90
반응형

'입사후 공부한 내용' 카테고리의 다른 글

[MSSQL] 연결 에러 해결!  (0) 2023.06.16
[ASP.NET] MVC강의 기초 및 심화  (0) 2023.06.13
[ASP.NET] 개념과 역사  (0) 2023.06.13
AWS EC2 가상서버 만들기 + 연결하기  (0) 2023.06.13
[MSSQL] 기본 문법  (0) 2023.06.01

+ Recent posts